\r
return Length;\r
}\r
+\r
+/**\r
+ Draws a dialog box to the console output device specified by \r
+ ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke\r
+ from the console input device specified by ConIn defined in the \r
+ EFI_SYSTEM_TABLE.\r
+\r
+ If there are no strings in the variable argument list, then ASSERT().\r
+ If all the strings in the variable argument list are empty, then ASSERT().\r
+\r
+ @param[in] Attribute Specifies the foreground and background color of the popup.\r
+ @param[out] Key A pointer to the EFI_KEY value of the key that was \r
+ pressed. This is an optional parameter that may be NULL.\r
+ If it is NULL then no wait for a keypress will be performed.\r
+ @param[in] ... The variable argument list that contains pointers to Null-\r
+ terminated Unicode strings to display in the dialog box. \r
+ The variable argument list is terminated by a NULL.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CreatePopUp (\r
+ IN UINTN Attribute, \r
+ OUT EFI_INPUT_KEY *Key, OPTIONAL\r
+ ...\r
+ )\r
+{\r
+ VA_LIST Args;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;\r
+ EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;\r
+ UINTN Columns;\r
+ UINTN Rows;\r
+ UINTN Column;\r
+ UINTN Row;\r
+ UINTN NumberOfLines;\r
+ UINTN MaxLength;\r
+ CHAR16 *String;\r
+ UINTN Length;\r
+ CHAR16 *Line;\r
+ UINTN EventIndex;\r
+\r
+ //\r
+ // Determine the length of the longest line in the popup and the the total \r
+ // number of lines in the popup\r
+ //\r
+ VA_START (Args, Key);\r
+ MaxLength = 0;\r
+ NumberOfLines = 0;\r
+ while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {\r
+ MaxLength = MAX (MaxLength, StrLen (String));\r
+ NumberOfLines++;\r
+ }\r
+ VA_END (Args);\r
+\r
+ //\r
+ // If the total number of lines in the popup is zero, then ASSERT()\r
+ //\r
+ ASSERT (NumberOfLines != 0);\r
+\r
+ //\r
+ // If the maximum length of all the strings is zero, then ASSERT()\r
+ //\r
+ ASSERT (MaxLength != 0);\r
+\r
+ //\r
+ // Cache a pointer to the Simple Text Output Protocol in the EFI System Table\r
+ //\r
+ ConOut = gST->ConOut;\r
+ \r
+ //\r
+ // Save the current console cursor position and attributes\r
+ //\r
+ CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));\r
+\r
+ //\r
+ // Retrieve the number of columns and rows in the current console mode\r
+ //\r
+ ConOut->QueryMode (ConOut, SavedConsoleMode.Mode, &Columns, &Rows);\r
+\r
+ //\r
+ // Disable cursor and set the foreground and background colors specified by Attribute\r
+ //\r
+ ConOut->EnableCursor (ConOut, FALSE);\r
+ ConOut->SetAttribute (ConOut, Attribute);\r
+\r
+ //\r
+ // Limit NumberOfLines to height of the screen minus 3 rows for the box itself\r
+ //\r
+ NumberOfLines = MIN (NumberOfLines, Rows - 3);\r
+\r
+ //\r
+ // Limit MaxLength to width of the screen minus 2 columns for the box itself\r
+ //\r
+ MaxLength = MIN (MaxLength, Columns - 2);\r
+\r
+ //\r
+ // Compute the starting row and starting column for the popup\r
+ //\r
+ Row = (Rows - (NumberOfLines + 3)) / 2;\r
+ Column = (Columns - (MaxLength + 2)) / 2;\r
+\r
+ //\r
+ // Allocate a buffer for a single line of the popup with borders and a Null-terminator\r
+ //\r
+ Line = AllocateZeroPool ((MaxLength + 3) * sizeof (CHAR16));\r
+\r
+ //\r
+ // Draw top of popup box \r
+ //\r
+ SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);\r
+ Line[0] = BOXDRAW_DOWN_RIGHT;\r
+ Line[MaxLength + 1] = BOXDRAW_DOWN_LEFT;\r
+ Line[MaxLength + 2] = L'\0';\r
+ ConOut->SetCursorPosition (ConOut, Column, Row++);\r
+ ConOut->OutputString (ConOut, Line);\r
+\r
+ //\r
+ // Draw middle of the popup with strings\r
+ //\r
+ VA_START (Args, Key);\r
+ while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {\r
+ Length = StrLen (String);\r
+ SetMem16 (Line, (MaxLength + 2) * 2, L' ');\r
+ if (Length <= MaxLength) {\r
+ //\r
+ // Length <= MaxLength\r
+ //\r
+ CopyMem (Line + 1 + (MaxLength - Length) / 2, String , Length * sizeof (CHAR16));\r
+ } else {\r
+ //\r
+ // Length > MaxLength\r
+ //\r
+ CopyMem (Line + 1, String + (Length - MaxLength) / 2 , MaxLength * sizeof (CHAR16));\r
+ }\r
+ Line[0] = BOXDRAW_VERTICAL;\r
+ Line[MaxLength + 1] = BOXDRAW_VERTICAL;\r
+ Line[MaxLength + 2] = L'\0';\r
+ ConOut->SetCursorPosition (ConOut, Column, Row++);\r
+ ConOut->OutputString (ConOut, Line);\r
+ NumberOfLines--;\r
+ }\r
+ VA_END (Args);\r
+\r
+ //\r
+ // Draw bottom of popup box\r
+ //\r
+ SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);\r
+ Line[0] = BOXDRAW_UP_RIGHT;\r
+ Line[MaxLength + 1] = BOXDRAW_UP_LEFT;\r
+ Line[MaxLength + 2] = L'\0';\r
+ ConOut->SetCursorPosition (ConOut, Column, Row++);\r
+ ConOut->OutputString (ConOut, Line);\r
+\r
+ //\r
+ // Free the allocated line buffer\r
+ //\r
+ FreePool (Line);\r
+\r
+ //\r
+ // Restore the cursor visibility, position, and attributes\r
+ //\r
+ ConOut->EnableCursor (ConOut, SavedConsoleMode.CursorVisible);\r
+ ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);\r
+ ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute);\r
+\r
+ //\r
+ // Wait for a keystroke\r
+ //\r
+ if (Key != NULL) {\r
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
+ gST->ConIn->ReadKeyStroke (gST->ConIn, Key);\r
+ }\r
+}\r