Keep StdErr same logic initialization with ConOut, e.g. initialize gST->StandardError...
authorli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 12 Apr 2012 02:16:47 +0000 (02:16 +0000)
committerli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 12 Apr 2012 02:16:47 +0000 (02:16 +0000)
Signed-off-by: Li Elvin <elvin.li@intel.com>
Reviewed-by: Sun Rui <rui.sun@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13190 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitter.c

index 6425bea..ab42b92 100644 (file)
@@ -16,7 +16,7 @@
   never removed. Such design ensures sytem function well during none console\r
   device situation.\r
 \r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -377,7 +377,7 @@ ConSplitterDriverEntry(
           FeaturePcdGet (PcdConOutUgaSupport));\r
 \r
   //\r
-  // The driver creates virtual handles for ConIn, ConOut.\r
+  // The driver creates virtual handles for ConIn, ConOut, StdErr.\r
   // The virtual handles will always exist even if no console exist in the\r
   // system. This is need to support hotplug devices like USB.\r
   //\r
@@ -465,6 +465,28 @@ ConSplitterDriverEntry(
     }\r
 \r
   }\r
+\r
+  //\r
+  // Create virtual device handle for StdErr Splitter\r
+  //\r
+  Status = ConSplitterTextOutConstructor (&mStdErr);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &mStdErr.VirtualHandle,\r
+                    &gEfiSimpleTextOutProtocolGuid,\r
+                    &mStdErr.TextOut,\r
+                    NULL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {  \r
+      //\r
+      // Update the EFI System Table with new virtual console\r
+      // and update the pointer to Text Output protocol.\r
+      //\r
+      gST->StandardErrorHandle  = mStdErr.VirtualHandle;\r
+      gST->StdErr               = &mStdErr.TextOut;\r
+    }\r
+  }\r
+  \r
   //\r
   // Update the CRC32 in the EFI System Table header\r
   //\r
@@ -1313,27 +1335,6 @@ ConSplitterStdErrDriverBindingStart (
   EFI_STATUS                       Status;\r
   EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *TextOut;\r
 \r
-  if (mStdErr.CurrentNumberOfConsoles == 0) {\r
-    //\r
-    // Construct console output devices' private data\r
-    //\r
-    Status = ConSplitterTextOutConstructor (&mStdErr);\r
-    if (!EFI_ERROR (Status)) {\r
-      //\r
-      // Create virtual device handle for StdErr Splitter\r
-      //\r
-      Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &mStdErr.VirtualHandle,\r
-                      &gEfiSimpleTextOutProtocolGuid,\r
-                      &mStdErr.TextOut,\r
-                      NULL\r
-                      );\r
-    }\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
   //\r
   // Start ConSplitter on ControllerHandle, and create the virtual\r
   // agrogated console device on first call Start for a StandardError handle.\r
@@ -1366,20 +1367,6 @@ ConSplitterStdErrDriverBindingStart (
     return Status;\r
   }\r
 \r
-  if (mStdErr.CurrentNumberOfConsoles == 1) {\r
-    gST->StandardErrorHandle  = mStdErr.VirtualHandle;\r
-    gST->StdErr               = &mStdErr.TextOut;\r
-    //\r
-    // Update the CRC32 in the EFI System Table header\r
-    //\r
-    gST->Hdr.CRC32 = 0;\r
-    gBS->CalculateCrc32 (\r
-          (UINT8 *) &gST->Hdr,\r
-          gST->Hdr.HeaderSize,\r
-          &gST->Hdr.CRC32\r
-          );\r
-  }\r
-\r
   return Status;\r
 }\r
 \r
@@ -1716,38 +1703,7 @@ ConSplitterStdErrDriverBindingStop (
   //\r
   // Delete this console error out device's data structures.\r
   //\r
-  Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (mStdErr.CurrentNumberOfConsoles == 0) {\r
-    mStdErr.VirtualHandle     = NULL;\r
-\r
-    gST->StandardErrorHandle  = NULL;\r
-    gST->StdErr               = NULL;\r
-    //\r
-    // Update the CRC32 in the EFI System Table header\r
-    //\r
-    gST->Hdr.CRC32 = 0;\r
-    gBS->CalculateCrc32 (\r
-          (UINT8 *) &gST->Hdr,\r
-          gST->Hdr.HeaderSize,\r
-          &gST->Hdr.CRC32\r
-          );\r
-\r
-    //\r
-    // Uninstall Simple Text Output protocol from StdErr Handle.\r
-    //\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           mStdErr.VirtualHandle,\r
-           &gEfiSimpleTextOutProtocolGuid,\r
-           &mStdErr.TextOut,\r
-           NULL\r
-           );\r
-  }\r
-\r
-  return Status;\r
+  return ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
 }\r
 \r
 \r
@@ -4203,37 +4159,21 @@ ConSplitterTextOutOutputString (
   EFI_STATUS                      Status;\r
   TEXT_OUT_SPLITTER_PRIVATE_DATA  *Private;\r
   UINTN                           Index;\r
-  UINTN                           BackSpaceCount;\r
   EFI_STATUS                      ReturnStatus;\r
-  CHAR16                          *TargetString;\r
+  UINTN                           MaxColumn;\r
+  UINTN                           MaxRow;\r
 \r
   This->SetAttribute (This, This->Mode->Attribute);\r
 \r
   Private         = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
 \r
-  BackSpaceCount  = 0;\r
-\r
-  for (TargetString = WString; *TargetString != L'\0'; TargetString++) {\r
-    if (*TargetString == CHAR_BACKSPACE) {\r
-      BackSpaceCount++;\r
-    }\r
-  }\r
-\r
-  if (BackSpaceCount == 0) {\r
-    TargetString = WString;\r
-  } else {\r
-    TargetString = AllocatePool (sizeof (CHAR16) * (StrLen (WString) + BackSpaceCount + 1));\r
-    ASSERT (TargetString != NULL);\r
-\r
-    StrCpy (TargetString, WString);\r
-  }\r
   //\r
   // return the worst status met\r
   //\r
   for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
     Status = Private->TextOutList[Index].TextOut->OutputString (\r
                                                     Private->TextOutList[Index].TextOut,\r
-                                                    TargetString\r
+                                                    WString\r
                                                     );\r
     if (EFI_ERROR (Status)) {\r
       ReturnStatus = Status;\r
@@ -4243,10 +4183,50 @@ ConSplitterTextOutOutputString (
   if (Private->CurrentNumberOfConsoles > 0) {\r
     Private->TextOutMode.CursorColumn = Private->TextOutList[0].TextOut->Mode->CursorColumn;\r
     Private->TextOutMode.CursorRow    = Private->TextOutList[0].TextOut->Mode->CursorRow;\r
-  }\r
-\r
-  if (BackSpaceCount > 0) {\r
-    FreePool (TargetString);\r
+  } else {\r
+    //\r
+    // When there is no real console devices in system, \r
+    // update cursor position for the virtual device in consplitter.\r
+    //\r
+    Private->TextOut.QueryMode (\r
+                       &Private->TextOut,\r
+                       Private->TextOutMode.Mode,\r
+                       &MaxColumn,\r
+                       &MaxRow\r
+                       );    \r
+    for (; *WString != CHAR_NULL; WString++) {\r
+      switch (*WString) {\r
+      case CHAR_BACKSPACE:\r
+        if (Private->TextOutMode.CursorColumn == 0 && Private->TextOutMode.CursorRow > 0) {\r
+          Private->TextOutMode.CursorRow--;\r
+          Private->TextOutMode.CursorColumn = (INT32) (MaxColumn - 1);          \r
+        } else if (Private->TextOutMode.CursorColumn > 0) {\r
+          Private->TextOutMode.CursorColumn--;\r
+        }\r
+        break;\r
+      \r
+      case CHAR_LINEFEED:\r
+        if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {\r
+          Private->TextOutMode.CursorRow++;\r
+        }\r
+        break;\r
+      \r
+      case CHAR_CARRIAGE_RETURN:\r
+        Private->TextOutMode.CursorColumn = 0;\r
+        break;\r
+      \r
+      default:\r
+        if (Private->TextOutMode.CursorColumn < (INT32) (MaxColumn - 1)) {\r
+          Private->TextOutMode.CursorColumn++;\r
+        } else {\r
+          Private->TextOutMode.CursorColumn = 0;\r
+          if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {\r
+            Private->TextOutMode.CursorRow++;\r
+          }\r
+        }\r
+        break;\r
+      }\r
+    }\r
   }\r
 \r
   return ReturnStatus;\r