-/**\r
- Write data from the buffer to video display based on UGA Draw setting.\r
-\r
- @param Private Consplitter Text Out pointer.\r
- @param GraphicsOutput Graphics Output protocol pointer.\r
- @param UgaDraw UGA Draw protocol pointer.\r
-\r
- @retval EFI_UNSUPPORTED No graphics devcie available .\r
- @retval EFI_SUCCESS The Blt operation completed.\r
- @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
- @retval EFI_DEVICE_ERROR A hardware error occured writting to the video buffer.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullUgaSync (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
- )\r
-{\r
- if (GraphicsOutput != NULL) {\r
- return GraphicsOutput->Blt (\r
- GraphicsOutput,\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Private->UgaBlt,\r
- EfiBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->UgaHorizontalResolution,\r
- Private->UgaVerticalResolution,\r
- 0\r
- );\r
- } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
- return UgaDraw->Blt (\r
- UgaDraw,\r
- Private->UgaBlt,\r
- EfiUgaBltBufferToVideo,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- Private->UgaHorizontalResolution,\r
- Private->UgaVerticalResolution,\r
- Private->UgaHorizontalResolution * sizeof (EFI_UGA_PIXEL)\r
- );\r
- } else {\r
- return EFI_UNSUPPORTED;\r
- }\r
-}\r
-\r
-\r
-/**\r
- Write a Unicode string to the output device.\r
-\r
- @param Private Pointer to the console output splitter's private\r
- data. It indicates the calling context.\r
- @param WString The NULL-terminated Unicode string to be\r
- displayed on the output device(s). All output\r
- devices must also support the Unicode drawing\r
- defined in this file.\r
-\r
- @retval EFI_SUCCESS The string was output to the device.\r
- @retval EFI_DEVICE_ERROR The device reported an error while attempting to\r
- output the text.\r
- @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
- defined text mode.\r
- @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
- characters in the Unicode string could not be\r
- rendered and were skipped.\r
-\r
-**/\r
-EFI_STATUS\r
-DevNullTextOutOutputString (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN CHAR16 *WString\r
- )\r
-{\r
- UINTN SizeScreen;\r
- UINTN SizeAttribute;\r
- UINTN Index;\r
- EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
- CHAR16 *Screen;\r
- CHAR16 *NullScreen;\r
- CHAR16 InsertChar;\r
- CHAR16 TempChar;\r
- CHAR16 *PStr;\r
- INT32 *Attribute;\r
- INT32 *NullAttributes;\r
- INT32 CurrentWidth;\r
- UINTN LastRow;\r
- UINTN MaxColumn;\r
-\r
- Mode = &Private->TextOutMode;\r
- NullScreen = Private->DevNullScreen;\r
- NullAttributes = Private->DevNullAttributes;\r
- LastRow = Private->DevNullRows - 1;\r
- MaxColumn = Private->DevNullColumns;\r
-\r
- if ((Mode->Attribute & EFI_WIDE_ATTRIBUTE) != 0) {\r
- CurrentWidth = 2;\r
- } else {\r
- CurrentWidth = 1;\r
- }\r
-\r
- while (*WString != L'\0') {\r
-\r
- if (*WString == CHAR_BACKSPACE) {\r
- //\r
- // If the cursor is at the left edge of the display, then move the cursor\r
- // one row up.\r
- //\r
- if (Mode->CursorColumn == 0 && Mode->CursorRow > 0) {\r
- Mode->CursorRow--;\r
- Mode->CursorColumn = (INT32) MaxColumn;\r
- }\r
-\r
- //\r
- // If the cursor is not at the left edge of the display,\r
- // then move the cursor left one column.\r
- //\r
- if (Mode->CursorColumn > 0) {\r
- Mode->CursorColumn--;\r
- if (Mode->CursorColumn > 0 &&\r
- NullAttributes[Mode->CursorRow * MaxColumn + Mode->CursorColumn - 1] & EFI_WIDE_ATTRIBUTE\r
- ) {\r
- Mode->CursorColumn--;\r
-\r
- //\r
- // Insert an extra backspace\r
- //\r
- InsertChar = CHAR_BACKSPACE;\r
- PStr = WString + 1;\r
- while (*PStr != L'\0') {\r
- TempChar = *PStr;\r
- *PStr = InsertChar;\r
- InsertChar = TempChar;\r
- PStr++;\r
- }\r
-\r
- *PStr = InsertChar;\r
- *(++PStr) = 0;\r
-\r
- WString++;\r
- }\r
- }\r
-\r
- WString++;\r
-\r
- } else if (*WString == CHAR_LINEFEED) {\r
- //\r
- // If the cursor is at the bottom of the display,\r
- // then scroll the display one row, and do not update\r
- // the cursor position. Otherwise, move the cursor down one row.\r
- //\r
- if (Mode->CursorRow == (INT32) (LastRow)) {\r
- //\r
- // Scroll Screen Up One Row\r
- //\r
- SizeAttribute = LastRow * MaxColumn;\r
- CopyMem (\r
- NullAttributes,\r
- NullAttributes + MaxColumn,\r
- SizeAttribute * sizeof (INT32)\r
- );\r
-\r
- //\r
- // Each row has an ending CHAR_NULL. So one more character each line\r
- // for DevNullScreen than DevNullAttributes\r
- //\r
- SizeScreen = SizeAttribute + LastRow;\r
- CopyMem (\r
- NullScreen,\r
- NullScreen + (MaxColumn + 1),\r
- SizeScreen * sizeof (CHAR16)\r
- );\r
-\r
- //\r
- // Print Blank Line at last line\r
- //\r
- Screen = NullScreen + SizeScreen;\r
- Attribute = NullAttributes + SizeAttribute;\r
-\r
- for (Index = 0; Index < MaxColumn; Index++, Screen++, Attribute++) {\r
- *Screen = L' ';\r
- *Attribute = Mode->Attribute;\r
- }\r
- } else {\r
- Mode->CursorRow++;\r
- }\r
-\r
- WString++;\r
- } else if (*WString == CHAR_CARRIAGE_RETURN) {\r
- //\r
- // Move the cursor to the beginning of the current row.\r
- //\r
- Mode->CursorColumn = 0;\r
- WString++;\r
- } else {\r
- //\r
- // Print the character at the current cursor position and\r
- // move the cursor right one column. If this moves the cursor\r
- // past the right edge of the display, then the line should wrap to\r
- // the beginning of the next line. This is equivalent to inserting\r
- // a CR and an LF. Note that if the cursor is at the bottom of the\r
- // display, and the line wraps, then the display will be scrolled\r
- // one line.\r
- //\r
- Index = Mode->CursorRow * MaxColumn + Mode->CursorColumn;\r
-\r
- while (Mode->CursorColumn < (INT32) MaxColumn) {\r
- if (*WString == CHAR_NULL) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_BACKSPACE) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_LINEFEED) {\r
- break;\r
- }\r
-\r
- if (*WString == CHAR_CARRIAGE_RETURN) {\r
- break;\r
- }\r
-\r
- if (*WString == UNICODE_WIDE_CHAR || *WString == UNICODE_NARROW_CHAR) {\r
- CurrentWidth = (*WString == UNICODE_WIDE_CHAR) ? 2 : 1;\r
- WString++;\r
- continue;\r
- }\r
-\r
- if (Mode->CursorColumn + CurrentWidth > (INT32) MaxColumn) {\r
- //\r
- // If a wide char is at the rightmost column, then move the char\r
- // to the beginning of the next row\r
- //\r
- NullScreen[Index + Mode->CursorRow] = L' ';\r
- NullAttributes[Index] = Mode->Attribute | (UINT32) EFI_WIDE_ATTRIBUTE;\r
- Index++;\r
- Mode->CursorColumn++;\r
- } else {\r
- NullScreen[Index + Mode->CursorRow] = *WString;\r
- NullAttributes[Index] = Mode->Attribute;\r
- if (CurrentWidth == 1) {\r
- NullAttributes[Index] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
- } else {\r
- NullAttributes[Index] |= (UINT32) EFI_WIDE_ATTRIBUTE;\r
- NullAttributes[Index + 1] &= (~ (UINT32) EFI_WIDE_ATTRIBUTE);\r
- }\r
-\r
- Index += CurrentWidth;\r
- WString++;\r
- Mode->CursorColumn += CurrentWidth;\r
- }\r
- }\r
- //\r
- // At the end of line, output carriage return and line feed\r
- //\r
- if (Mode->CursorColumn >= (INT32) MaxColumn) {\r
- DevNullTextOutOutputString (Private, mCrLfString);\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r