]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / CustomizedDisplayLib / CustomizedDisplayLib.c
CommitLineData
7c6c064c
ED
1/** @file\r
2\r
3 This library class defines a set of interfaces to customize Display module\r
4\r
d1102dba 5Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7c6c064c
ED
7\r
8**/\r
9#include "CustomizedDisplayLibInternal.h"\r
10\r
1436aea4
MK
11EFI_GUID gCustomizedDisplayLibGuid = {\r
12 0x99fdc8fd, 0x849b, 0x4eba, { 0xad, 0x13, 0xfb, 0x96, 0x99, 0xc9, 0xa, 0x4d }\r
13};\r
7c6c064c 14\r
1436aea4
MK
15EFI_HII_HANDLE mCDLStringPackHandle;\r
16UINT16 gClassOfVfr; // Formset class information\r
17BOOLEAN gLibIsFirstForm = TRUE;\r
18BANNER_DATA *gBannerData;\r
7c6c064c 19\r
1436aea4 20UINTN gFooterHeight;\r
7c6c064c
ED
21\r
22/**\r
23+------------------------------------------------------------------------------+\r
24| Setup Page |\r
25+------------------------------------------------------------------------------+\r
26\r
27Statement\r
28Statement\r
29Statement\r
30\r
31\r
32\r
33\r
34\r
35+------------------------------------------------------------------------------+\r
5a9f73bf
ED
36| F9=Reset to Defaults F10=Save |\r
37| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Exit |\r
7c6c064c
ED
38+------------------------------------------------------------------------------+\r
39 StatusBar\r
40**/\r
41\r
42/**\r
d1102dba
LG
43 This funtion defines Page Frame and Backgroud.\r
44\r
45 Based on the above layout, it will be responsible for HeaderHeight, FooterHeight,\r
46 StatusBarHeight and Backgroud. And, it will reserve Screen for Statement.\r
7c6c064c
ED
47\r
48 @param[in] FormData Form Data to be shown in Page.\r
49 @param[out] ScreenForStatement Screen to be used for Statement. (Prompt, Value and Help)\r
d1102dba 50\r
7c6c064c
ED
51 @return Status\r
52**/\r
53EFI_STATUS\r
54EFIAPI\r
55DisplayPageFrame (\r
1436aea4
MK
56 IN FORM_DISPLAY_ENGINE_FORM *FormData,\r
57 OUT EFI_SCREEN_DESCRIPTOR *ScreenForStatement\r
7c6c064c
ED
58 )\r
59{\r
1436aea4 60 EFI_STATUS Status;\r
7c6c064c
ED
61\r
62 ASSERT (FormData != NULL && ScreenForStatement != NULL);\r
1436aea4 63 if ((FormData == NULL) || (ScreenForStatement == NULL)) {\r
7c6c064c
ED
64 return EFI_INVALID_PARAMETER;\r
65 }\r
66\r
67 Status = ScreenDiemensionInfoValidate (FormData);\r
68 if (EFI_ERROR (Status)) {\r
69 return Status;\r
70 }\r
71\r
72 gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;\r
7c6c064c 73\r
1436aea4 74 ProcessExternedOpcode (FormData);\r
7c6c064c
ED
75\r
76 //\r
77 // Calculate the ScreenForStatement.\r
78 //\r
1436aea4 79 ScreenForStatement->BottomRow = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight;\r
5a9f73bf 80 if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
1436aea4 81 ScreenForStatement->TopRow = gScreenDimensions.TopRow + FRONT_PAGE_HEADER_HEIGHT;\r
7c6c064c 82 } else {\r
1436aea4 83 ScreenForStatement->TopRow = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;\r
7c6c064c 84 }\r
1436aea4 85\r
7c6c064c
ED
86 ScreenForStatement->LeftColumn = gScreenDimensions.LeftColumn;\r
87 ScreenForStatement->RightColumn = gScreenDimensions.RightColumn;\r
88\r
5a9f73bf
ED
89 if ((gLibIsFirstForm) || ((FormData->Attribute & HII_DISPLAY_MODAL) != 0)) {\r
90 //\r
91 // Ensure we are in Text mode\r
92 //\r
93 gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
94 ClearLines (0, gScreenDimensions.RightColumn, 0, gScreenDimensions.BottomRow, KEYHELP_BACKGROUND);\r
95 gLibIsFirstForm = FALSE;\r
7c6c064c
ED
96 }\r
97\r
98 //\r
5a9f73bf 99 // Don't print frame for modal form.\r
7c6c064c 100 //\r
7c6c064c
ED
101 if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
102 return EFI_SUCCESS;\r
103 }\r
104\r
5a9f73bf 105 if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
7c6c064c
ED
106 PrintBannerInfo (FormData);\r
107 }\r
108\r
5a9f73bf 109 PrintFramework (FormData);\r
7c6c064c 110\r
1436aea4 111 UpdateStatusBar (NV_UPDATE_REQUIRED, FormData->SettingChangedFlag);\r
7c6c064c 112\r
7c6c064c
ED
113 return EFI_SUCCESS;\r
114}\r
115\r
116/**\r
117 This function updates customized key panel's help information.\r
118 The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-.\r
119 and arrange them in Footer panel.\r
d1102dba
LG
120\r
121 @param[in] FormData Form Data to be shown in Page. FormData has the highlighted statement.\r
7c6c064c
ED
122 @param[in] Statement The statement current selected.\r
123 @param[in] Selected Whether or not a tag be selected. TRUE means Enter has hit this question.\r
124**/\r
125VOID\r
126EFIAPI\r
127RefreshKeyHelp (\r
1436aea4
MK
128 IN FORM_DISPLAY_ENGINE_FORM *FormData,\r
129 IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
130 IN BOOLEAN Selected\r
7c6c064c
ED
131 )\r
132{\r
1436aea4
MK
133 UINTN SecCol;\r
134 UINTN ThdCol;\r
135 UINTN RightColumnOfHelp;\r
136 UINTN TopRowOfHelp;\r
137 UINTN BottomRowOfHelp;\r
138 UINTN StartColumnOfHelp;\r
139 EFI_IFR_NUMERIC *NumericOp;\r
140 EFI_IFR_DATE *DateOp;\r
141 EFI_IFR_TIME *TimeOp;\r
142 BOOLEAN HexDisplay;\r
143 UINTN ColumnWidth1;\r
144 UINTN ColumnWidth2;\r
145 UINTN ColumnWidth3;\r
146 CHAR16 *ColumnStr1;\r
147 CHAR16 *ColumnStr2;\r
148 CHAR16 *ColumnStr3;\r
7c6c064c
ED
149\r
150 ASSERT (FormData != NULL);\r
151 if (FormData == NULL) {\r
152 return;\r
153 }\r
154\r
155 gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
156\r
157 if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {\r
158 return;\r
159 }\r
160\r
1436aea4
MK
161 SecCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3;\r
162 ThdCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3 * 2;\r
7c6c064c 163\r
d89d1a54
ED
164 //\r
165 // + 2 means leave 1 space before the first hotkey info.\r
166 //\r
7c6c064c 167 StartColumnOfHelp = gScreenDimensions.LeftColumn + 2;\r
af047db7 168 RightColumnOfHelp = gScreenDimensions.RightColumn - 1;\r
7c6c064c
ED
169 TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
170 BottomRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;\r
171\r
1436aea4
MK
172 ColumnWidth1 = SecCol - StartColumnOfHelp;\r
173 ColumnWidth2 = ThdCol - SecCol;\r
174 ColumnWidth3 = RightColumnOfHelp - ThdCol;\r
175 ColumnStr1 = gLibEmptyString;\r
176 ColumnStr2 = gLibEmptyString;\r
177 ColumnStr3 = gLibEmptyString;\r
af047db7 178\r
d89d1a54
ED
179 //\r
180 // Clean the space at gScreenDimensions.LeftColumn + 1.\r
181 //\r
182 PrintStringAtWithWidth (StartColumnOfHelp - 1, BottomRowOfHelp, gLibEmptyString, 1);\r
183 PrintStringAtWithWidth (StartColumnOfHelp - 1, TopRowOfHelp, gLibEmptyString, 1);\r
184\r
7c6c064c
ED
185 if (Statement == NULL) {\r
186 //\r
187 // Print Key for Form without showable statement.\r
188 //\r
af047db7
ED
189 PrintHotKeyHelpString (FormData, TRUE);\r
190 PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1);\r
191 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gLibEmptyString, ColumnWidth2);\r
192 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1);\r
d89d1a54
ED
193 if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
194 ColumnStr3 = gEscapeString;\r
195 }\r
1436aea4 196\r
d89d1a54 197 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);\r
af047db7 198\r
7c6c064c
ED
199 return;\r
200 }\r
201\r
202 HexDisplay = FALSE;\r
1436aea4
MK
203 NumericOp = NULL;\r
204 DateOp = NULL;\r
205 TimeOp = NULL;\r
7c6c064c 206 if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {\r
1436aea4 207 NumericOp = (EFI_IFR_NUMERIC *)Statement->OpCode;\r
7c6c064c
ED
208 HexDisplay = (NumericOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
209 } else if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {\r
1436aea4 210 DateOp = (EFI_IFR_DATE *)Statement->OpCode;\r
7c6c064c
ED
211 HexDisplay = (DateOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
212 } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {\r
1436aea4 213 TimeOp = (EFI_IFR_TIME *)Statement->OpCode;\r
7c6c064c 214 HexDisplay = (TimeOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;\r
d1102dba 215 }\r
7c6c064c 216\r
1436aea4
MK
217 switch (Statement->OpCode->OpCode) {\r
218 case EFI_IFR_ORDERED_LIST_OP:\r
219 case EFI_IFR_ONE_OF_OP:\r
220 case EFI_IFR_NUMERIC_OP:\r
221 case EFI_IFR_TIME_OP:\r
222 case EFI_IFR_DATE_OP:\r
223 if (!Selected) {\r
224 PrintHotKeyHelpString (FormData, TRUE);\r
225\r
226 if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
227 ColumnStr3 = gEscapeString;\r
af047db7 228 }\r
7c6c064c 229\r
1436aea4
MK
230 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);\r
231\r
232 if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
233 (Statement->OpCode->OpCode == EFI_IFR_TIME_OP))\r
234 {\r
235 PrintAt (\r
236 ColumnWidth1,\r
237 StartColumnOfHelp,\r
238 BottomRowOfHelp,\r
239 L"%c%c%c%c%s",\r
240 ARROW_UP,\r
241 ARROW_DOWN,\r
242 ARROW_RIGHT,\r
243 ARROW_LEFT,\r
244 gMoveHighlight\r
245 );\r
246 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2);\r
247 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber, ColumnWidth1);\r
248 } else {\r
249 PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
250 if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) && (LibGetFieldFromNum (Statement->OpCode) != 0)) {\r
251 ColumnStr1 = gAdjustNumber;\r
252 }\r
253\r
254 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1);\r
255 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterString, ColumnWidth2);\r
256 }\r
af047db7 257 } else {\r
1436aea4
MK
258 PrintHotKeyHelpString (FormData, FALSE);\r
259 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gEnterCommitString, ColumnWidth2);\r
260\r
261 //\r
262 // If it is a selected numeric with manual input, display different message\r
263 //\r
264 if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) ||\r
265 (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||\r
266 (Statement->OpCode->OpCode == EFI_IFR_TIME_OP))\r
267 {\r
268 ColumnStr2 = HexDisplay ? gHexNumericInput : gDecNumericInput;\r
269 PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, gLibEmptyString, ColumnWidth1);\r
270 } else {\r
271 PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
272 }\r
7c6c064c 273\r
1436aea4
MK
274 if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
275 ColumnStr1 = gPlusString;\r
276 ColumnStr3 = gMinusString;\r
277 }\r
7c6c064c 278\r
1436aea4
MK
279 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1);\r
280 PrintStringAtWithWidth (ThdCol, TopRowOfHelp, ColumnStr3, ColumnWidth3);\r
281 PrintStringAtWithWidth (SecCol, TopRowOfHelp, ColumnStr2, ColumnWidth2);\r
7c6c064c 282\r
1436aea4
MK
283 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, gEnterEscapeString, ColumnWidth3);\r
284 }\r
7c6c064c 285\r
1436aea4 286 break;\r
7c6c064c 287\r
1436aea4 288 case EFI_IFR_CHECKBOX_OP:\r
af047db7 289 PrintHotKeyHelpString (FormData, TRUE);\r
7c6c064c 290\r
5a9f73bf 291 if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
af047db7 292 ColumnStr3 = gEscapeString;\r
7c6c064c 293 }\r
1436aea4 294\r
af047db7 295 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);\r
7c6c064c 296\r
af047db7 297 PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
1436aea4
MK
298 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, gToggleCheckBox, ColumnWidth2);\r
299 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, gLibEmptyString, ColumnWidth1);\r
300 break;\r
301\r
302 case EFI_IFR_REF_OP:\r
303 case EFI_IFR_PASSWORD_OP:\r
304 case EFI_IFR_STRING_OP:\r
305 case EFI_IFR_TEXT_OP:\r
306 case EFI_IFR_ACTION_OP:\r
307 case EFI_IFR_RESET_BUTTON_OP:\r
308 case EFI_IFR_SUBTITLE_OP:\r
309 if (!Selected) {\r
310 PrintHotKeyHelpString (FormData, TRUE);\r
311\r
312 if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {\r
313 ColumnStr3 = gEscapeString;\r
314 }\r
315\r
316 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);\r
317\r
318 PrintAt (ColumnWidth1, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
319 if ((Statement->OpCode->OpCode != EFI_IFR_TEXT_OP) && (Statement->OpCode->OpCode != EFI_IFR_SUBTITLE_OP)) {\r
320 ColumnStr2 = gEnterString;\r
321 }\r
322\r
323 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2);\r
324 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1);\r
325 } else {\r
326 PrintHotKeyHelpString (FormData, FALSE);\r
327 if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) {\r
328 ColumnStr2 = gEnterCommitString;\r
329 ColumnStr3 = gEnterEscapeString;\r
330 }\r
331\r
332 PrintStringAtWithWidth (StartColumnOfHelp, TopRowOfHelp, ColumnStr1, ColumnWidth1);\r
333 PrintStringAtWithWidth (StartColumnOfHelp, BottomRowOfHelp, ColumnStr1, ColumnWidth1);\r
334 PrintStringAtWithWidth (SecCol, BottomRowOfHelp, ColumnStr2, ColumnWidth2);\r
335 PrintStringAtWithWidth (ThdCol, BottomRowOfHelp, ColumnStr3, ColumnWidth3);\r
7c6c064c 336 }\r
7c6c064c 337\r
1436aea4
MK
338 break;\r
339\r
340 default:\r
341 break;\r
d1102dba 342 }\r
7c6c064c
ED
343}\r
344\r
345/**\r
346 Update status bar.\r
347\r
d1102dba 348 This function updates the status bar on the bottom of menu screen. It just shows StatusBar.\r
7c6c064c
ED
349 Original logic in this function should be splitted out.\r
350\r
d1102dba 351 @param[in] MessageType The type of message to be shown. InputError or Configuration Changed.\r
7c6c064c
ED
352 @param[in] State Show or Clear Message.\r
353**/\r
354VOID\r
355EFIAPI\r
356UpdateStatusBar (\r
1436aea4
MK
357 IN UINTN MessageType,\r
358 IN BOOLEAN State\r
7c6c064c
ED
359 )\r
360{\r
1436aea4
MK
361 UINTN Index;\r
362 CHAR16 OptionWidth;\r
7c6c064c 363\r
1436aea4 364 OptionWidth = (CHAR16)((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);\r
7c6c064c
ED
365\r
366 switch (MessageType) {\r
1436aea4
MK
367 case INPUT_ERROR:\r
368 if (State) {\r
369 gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);\r
370 PrintStringAt (\r
371 gScreenDimensions.LeftColumn + OptionWidth,\r
372 gScreenDimensions.BottomRow - 1,\r
373 gInputErrorMessage\r
374 );\r
375 } else {\r
376 gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);\r
377 for (Index = 0; Index < (LibGetStringWidth (gInputErrorMessage) - 2) / 2; Index++) {\r
378 PrintStringAt (gScreenDimensions.LeftColumn + OptionWidth + Index, gScreenDimensions.BottomRow - 1, L" ");\r
379 }\r
7c6c064c 380 }\r
7c6c064c 381\r
1436aea4
MK
382 break;\r
383\r
384 case NV_UPDATE_REQUIRED:\r
385 //\r
386 // Global setting support. Show configuration change on every form.\r
387 //\r
388 if (State) {\r
389 gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);\r
7c6c064c 390 PrintStringAt (\r
1436aea4 391 gScreenDimensions.LeftColumn + OptionWidth * 2,\r
7c6c064c 392 gScreenDimensions.BottomRow - 1,\r
1436aea4 393 gNvUpdateMessage\r
7c6c064c 394 );\r
1436aea4
MK
395 } else {\r
396 gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);\r
397 for (Index = 0; Index < (LibGetStringWidth (gNvUpdateMessage) - 2) / 2; Index++) {\r
398 PrintStringAt (\r
399 (gScreenDimensions.LeftColumn + OptionWidth * 2 + Index),\r
400 gScreenDimensions.BottomRow - 1,\r
401 L" "\r
402 );\r
403 }\r
7c6c064c 404 }\r
7c6c064c 405\r
1436aea4
MK
406 break;\r
407\r
408 default:\r
409 break;\r
d1102dba 410 }\r
7c6c064c
ED
411}\r
412\r
413/**\r
d1102dba 414 Create popup window. It will replace CreateDialog().\r
7c6c064c
ED
415\r
416 This function draws OEM/Vendor specific pop up windows.\r
417\r
418 @param[out] Key User Input Key\r
419 @param ... String to be shown in Popup. The variable argument list is terminated by a NULL.\r
d1102dba 420\r
7c6c064c
ED
421**/\r
422VOID\r
423EFIAPI\r
424CreateDialog (\r
e3917e22 425 OUT EFI_INPUT_KEY *Key OPTIONAL,\r
7c6c064c
ED
426 ...\r
427 )\r
428{\r
1436aea4
MK
429 VA_LIST Marker;\r
430 EFI_INPUT_KEY KeyValue;\r
431 EFI_STATUS Status;\r
432 UINTN LargestString;\r
433 UINTN LineNum;\r
434 UINTN Index;\r
435 UINTN Count;\r
436 CHAR16 Character;\r
437 UINTN Start;\r
438 UINTN End;\r
439 UINTN Top;\r
440 UINTN Bottom;\r
441 CHAR16 *String;\r
442 UINTN DimensionsWidth;\r
443 UINTN DimensionsHeight;\r
444 UINTN CurrentAttribute;\r
445 BOOLEAN CursorVisible;\r
7c6c064c
ED
446\r
447 //\r
448 // If screen dimension info is not ready, get it from console.\r
449 //\r
1436aea4 450 if ((gScreenDimensions.RightColumn == 0) || (gScreenDimensions.BottomRow == 0)) {\r
7c6c064c
ED
451 ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
452 gST->ConOut->QueryMode (\r
453 gST->ConOut,\r
454 gST->ConOut->Mode->Mode,\r
455 &gScreenDimensions.RightColumn,\r
456 &gScreenDimensions.BottomRow\r
457 );\r
458 }\r
459\r
1436aea4
MK
460 DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;\r
461 DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;\r
7c6c064c
ED
462\r
463 LargestString = 0;\r
464 LineNum = 0;\r
465 VA_START (Marker, Key);\r
1436aea4
MK
466 while ((String = VA_ARG (Marker, CHAR16 *)) != NULL) {\r
467 LineNum++;\r
d1102dba 468\r
7c6c064c
ED
469 if ((LibGetStringWidth (String) / 2) > LargestString) {\r
470 LargestString = (LibGetStringWidth (String) / 2);\r
471 }\r
d1102dba 472 }\r
1436aea4 473\r
7c6c064c
ED
474 VA_END (Marker);\r
475\r
476 if ((LargestString + 2) > DimensionsWidth) {\r
477 LargestString = DimensionsWidth - 2;\r
478 }\r
d1102dba 479\r
1436aea4
MK
480 CurrentAttribute = gST->ConOut->Mode->Attribute;\r
481 CursorVisible = gST->ConOut->Mode->CursorVisible;\r
7c6c064c
ED
482 gST->ConOut->EnableCursor (gST->ConOut, FALSE);\r
483 gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
484\r
485 //\r
486 // Subtract the PopUp width from total Columns, allow for one space extra on\r
487 // each end plus a border.\r
488 //\r
1436aea4
MK
489 Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;\r
490 End = Start + LargestString + 1;\r
7c6c064c 491\r
1436aea4
MK
492 Top = ((DimensionsHeight - LineNum - 2) / 2) + gScreenDimensions.TopRow - 1;\r
493 Bottom = Top + LineNum + 2;\r
7c6c064c
ED
494\r
495 Character = BOXDRAW_DOWN_RIGHT;\r
496 PrintCharAt (Start, Top, Character);\r
497 Character = BOXDRAW_HORIZONTAL;\r
498 for (Index = Start; Index + 2 < End; Index++) {\r
499 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
500 }\r
501\r
502 Character = BOXDRAW_DOWN_LEFT;\r
503 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
504 Character = BOXDRAW_VERTICAL;\r
505\r
506 Count = 0;\r
507 VA_START (Marker, Key);\r
508 for (Index = Top; Index + 2 < Bottom; Index++, Count++) {\r
1436aea4 509 String = VA_ARG (Marker, CHAR16 *);\r
7c6c064c
ED
510\r
511 if (String[0] == CHAR_NULL) {\r
512 //\r
513 // Passing in a NULL results in a blank space\r
514 //\r
515 ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
516 } else if (String[0] == L' ') {\r
517 //\r
518 // Passing in a space results in the assumption that this is where typing will occur\r
519 //\r
520 ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);\r
521 PrintStringAt (\r
522 ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,\r
523 Index + 1,\r
524 String + 1\r
525 );\r
526 } else {\r
527 //\r
528 // This will clear the background of the line - we never know who might have been\r
529 // here before us. This differs from the next clear in that it used the non-reverse\r
530 // video for normal printing.\r
531 //\r
532 ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());\r
533 PrintStringAt (\r
534 ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,\r
535 Index + 1,\r
536 String\r
537 );\r
538 }\r
539\r
540 gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());\r
541 PrintCharAt (Start, Index + 1, Character);\r
542 PrintCharAt (End - 1, Index + 1, Character);\r
543 }\r
1436aea4 544\r
7c6c064c
ED
545 VA_END (Marker);\r
546\r
547 Character = BOXDRAW_UP_RIGHT;\r
548 PrintCharAt (Start, Bottom - 1, Character);\r
549 Character = BOXDRAW_HORIZONTAL;\r
550 for (Index = Start; Index + 2 < End; Index++) {\r
1436aea4 551 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
7c6c064c
ED
552 }\r
553\r
554 Character = BOXDRAW_UP_LEFT;\r
1436aea4 555 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);\r
7c6c064c
ED
556\r
557 if (Key != NULL) {\r
558 Status = WaitForKeyStroke (&KeyValue);\r
559 ASSERT_EFI_ERROR (Status);\r
560 CopyMem (Key, &KeyValue, sizeof (EFI_INPUT_KEY));\r
561 }\r
562\r
563 gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);\r
980f3026 564 gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);\r
7c6c064c
ED
565}\r
566\r
567/**\r
d1102dba
LG
568 Confirm how to handle the changed data.\r
569\r
6307a8b6 570 @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values.\r
7c6c064c
ED
571**/\r
572UINTN\r
573EFIAPI\r
574ConfirmDataChange (\r
575 VOID\r
576 )\r
577{\r
1436aea4
MK
578 CHAR16 YesResponse;\r
579 CHAR16 NoResponse;\r
580 EFI_INPUT_KEY Key;\r
7c6c064c
ED
581\r
582 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
d1102dba 583\r
7c6c064c
ED
584 YesResponse = gYesResponse[0];\r
585 NoResponse = gNoResponse[0];\r
d1102dba 586\r
7c6c064c
ED
587 //\r
588 // If NV flag is up, prompt user\r
589 //\r
590 do {\r
591 CreateDialog (&Key, gLibEmptyString, gSaveChanges, gAreYouSure, gLibEmptyString, NULL);\r
592 } while\r
593 (\r
1436aea4
MK
594 (Key.ScanCode != SCAN_ESC) &&\r
595 ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
596 ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
7c6c064c 597 );\r
d1102dba 598\r
7c6c064c 599 if (Key.ScanCode == SCAN_ESC) {\r
6307a8b6 600 return BROWSER_ACTION_NONE;\r
7c6c064c 601 } else if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
6307a8b6 602 return BROWSER_ACTION_SUBMIT;\r
7c6c064c 603 } else {\r
6307a8b6 604 return BROWSER_ACTION_DISCARD;\r
7c6c064c
ED
605 }\r
606}\r
607\r
608/**\r
609 OEM specifies whether Setup exits Page by ESC key.\r
610\r
d1102dba 611 This function customized the behavior that whether Setup exits Page so that\r
7c6c064c
ED
612 system able to boot when configuration is not changed.\r
613\r
614 @retval TRUE Exits FrontPage\r
615 @retval FALSE Don't exit FrontPage.\r
616**/\r
617BOOLEAN\r
618EFIAPI\r
619FormExitPolicy (\r
620 VOID\r
621 )\r
622{\r
5a9f73bf 623 return gClassOfVfr == FORMSET_CLASS_FRONT_PAGE ? FALSE : TRUE;\r
7c6c064c
ED
624}\r
625\r
626/**\r
d1102dba
LG
627 Set Timeout value for a ceratain Form to get user response.\r
628\r
7c6c064c 629 This function allows to set timeout value on a ceratain form if necessary.\r
d1102dba
LG
630 If timeout is not zero, the form will exit if user has no response in timeout.\r
631\r
7c6c064c
ED
632 @param[in] FormData Form Data to be shown in Page\r
633\r
d1102dba 634 @return 0 No timeout for this form.\r
7c6c064c
ED
635 @return > 0 Timeout value in 100 ns units.\r
636**/\r
637UINT64\r
638EFIAPI\r
639FormExitTimeout (\r
1436aea4 640 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
7c6c064c
ED
641 )\r
642{\r
643 return 0;\r
644}\r
1436aea4 645\r
7c6c064c
ED
646//\r
647// Print Functions\r
648//\r
1436aea4 649\r
7c6c064c
ED
650/**\r
651 Prints a unicode string to the default console, at\r
652 the supplied cursor position, using L"%s" format.\r
653\r
654 @param Column The cursor position to print the string at. When it is -1, use current Position.\r
655 @param Row The cursor position to print the string at. When it is -1, use current Position.\r
656 @param String String pointer.\r
657\r
658 @return Length of string printed to the console\r
659\r
660**/\r
661UINTN\r
662EFIAPI\r
663PrintStringAt (\r
1436aea4
MK
664 IN UINTN Column,\r
665 IN UINTN Row,\r
666 IN CHAR16 *String\r
7c6c064c
ED
667 )\r
668{\r
669 return PrintAt (0, Column, Row, L"%s", String);\r
670}\r
671\r
672/**\r
673 Prints a unicode string to the default console, at\r
674 the supplied cursor position, using L"%s" format.\r
675\r
676 @param Column The cursor position to print the string at. When it is -1, use current Position.\r
677 @param Row The cursor position to print the string at. When it is -1, use current Position.\r
678 @param String String pointer.\r
679 @param Width Width for String.\r
680\r
681 @return Length of string printed to the console\r
682\r
683**/\r
684UINTN\r
685EFIAPI\r
686PrintStringAtWithWidth (\r
1436aea4
MK
687 IN UINTN Column,\r
688 IN UINTN Row,\r
689 IN CHAR16 *String,\r
690 IN UINTN Width\r
7c6c064c
ED
691 )\r
692{\r
693 return PrintAt (Width, Column, Row, L"%s", String);\r
694}\r
695\r
696/**\r
3b28e744 697 Prints a character to the default console, at\r
7c6c064c
ED
698 the supplied cursor position, using L"%c" format.\r
699\r
700 @param Column The cursor position to print the string at. When it is -1, use current Position.\r
701 @param Row The cursor position to print the string at. When it is -1, use current Position.\r
702 @param Character Character to print.\r
703\r
704 @return Length of string printed to the console.\r
705\r
706**/\r
707UINTN\r
708EFIAPI\r
709PrintCharAt (\r
1436aea4
MK
710 IN UINTN Column,\r
711 IN UINTN Row,\r
712 CHAR16 Character\r
7c6c064c
ED
713 )\r
714{\r
715 return PrintAt (0, Column, Row, L"%c", Character);\r
716}\r
717\r
718/**\r
719 Clear retangle with specified text attribute.\r
720\r
721 @param LeftColumn Left column of retangle.\r
722 @param RightColumn Right column of retangle.\r
723 @param TopRow Start row of retangle.\r
724 @param BottomRow End row of retangle.\r
725 @param TextAttribute The character foreground and background.\r
726\r
727**/\r
728VOID\r
729EFIAPI\r
730ClearLines (\r
1436aea4
MK
731 IN UINTN LeftColumn,\r
732 IN UINTN RightColumn,\r
733 IN UINTN TopRow,\r
734 IN UINTN BottomRow,\r
735 IN UINTN TextAttribute\r
7c6c064c
ED
736 )\r
737{\r
738 CHAR16 *Buffer;\r
739 UINTN Row;\r
740\r
741 //\r
742 // For now, allocate an arbitrarily long buffer\r
743 //\r
744 Buffer = AllocateZeroPool (0x10000);\r
745 ASSERT (Buffer != NULL);\r
746\r
747 //\r
748 // Set foreground and background as defined\r
749 //\r
750 gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);\r
751\r
752 //\r
753 // Much faster to buffer the long string instead of print it a character at a time\r
754 //\r
755 LibSetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');\r
756\r
757 //\r
758 // Clear the desired area with the appropriate foreground/background\r
759 //\r
760 for (Row = TopRow; Row <= BottomRow; Row++) {\r
761 PrintStringAt (LeftColumn, Row, Buffer);\r
762 }\r
763\r
764 gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);\r
765\r
766 FreePool (Buffer);\r
767}\r
768\r
769//\r
770// Color Setting Functions\r
771//\r
772\r
773/**\r
774 Get OEM/Vendor specific popup attribute colors.\r
775\r
776 @retval Byte code color setting for popup color.\r
777**/\r
778UINT8\r
779EFIAPI\r
780GetPopupColor (\r
781 VOID\r
782 )\r
783{\r
784 return POPUP_TEXT | POPUP_BACKGROUND;\r
785}\r
786\r
787/**\r
788 Get OEM/Vendor specific popup attribute colors.\r
789\r
790 @retval Byte code color setting for popup inverse color.\r
791**/\r
792UINT8\r
793EFIAPI\r
794GetPopupInverseColor (\r
795 VOID\r
796 )\r
797{\r
798 return POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND;\r
799}\r
800\r
801/**\r
802 Get OEM/Vendor specific PickList color attribute.\r
803\r
804 @retval Byte code color setting for pick list color.\r
805**/\r
806UINT8\r
807EFIAPI\r
808GetPickListColor (\r
809 VOID\r
810 )\r
811{\r
812 return PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND;\r
813}\r
814\r
815/**\r
816 Get OEM/Vendor specific arrow color attribute.\r
817\r
818 @retval Byte code color setting for arrow color.\r
819**/\r
820UINT8\r
821EFIAPI\r
822GetArrowColor (\r
823 VOID\r
824 )\r
825{\r
826 return ARROW_TEXT | ARROW_BACKGROUND;\r
827}\r
828\r
829/**\r
830 Get OEM/Vendor specific info text color attribute.\r
831\r
832 @retval Byte code color setting for info text color.\r
833**/\r
834UINT8\r
835EFIAPI\r
836GetInfoTextColor (\r
837 VOID\r
838 )\r
839{\r
840 return INFO_TEXT | FIELD_BACKGROUND;\r
841}\r
842\r
843/**\r
844 Get OEM/Vendor specific help text color attribute.\r
845\r
846 @retval Byte code color setting for help text color.\r
847**/\r
848UINT8\r
849EFIAPI\r
850GetHelpTextColor (\r
851 VOID\r
852 )\r
853{\r
854 return HELP_TEXT | FIELD_BACKGROUND;\r
855}\r
856\r
857/**\r
858 Get OEM/Vendor specific grayed out text color attribute.\r
859\r
860 @retval Byte code color setting for grayed out text color.\r
861**/\r
862UINT8\r
863EFIAPI\r
864GetGrayedTextColor (\r
865 VOID\r
866 )\r
867{\r
868 return FIELD_TEXT_GRAYED | FIELD_BACKGROUND;\r
869}\r
870\r
871/**\r
872 Get OEM/Vendor specific highlighted text color attribute.\r
873\r
874 @retval Byte code color setting for highlight text color.\r
875**/\r
876UINT8\r
877EFIAPI\r
878GetHighlightTextColor (\r
879 VOID\r
880 )\r
881{\r
882 return PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);\r
883}\r
884\r
885/**\r
886 Get OEM/Vendor specific field text color attribute.\r
887\r
888 @retval Byte code color setting for field text color.\r
889**/\r
890UINT8\r
891EFIAPI\r
892GetFieldTextColor (\r
893 VOID\r
894 )\r
895{\r
896 return PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;\r
897}\r
898\r
899/**\r
900 Get OEM/Vendor specific subtitle text color attribute.\r
901\r
902 @retval Byte code color setting for subtitle text color.\r
903**/\r
904UINT8\r
905EFIAPI\r
906GetSubTitleTextColor (\r
907 VOID\r
908 )\r
909{\r
910 return PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND;\r
911}\r
912\r
913/**\r
914 Clear Screen to the initial state.\r
915**/\r
916VOID\r
d1102dba 917EFIAPI\r
7c6c064c
ED
918ClearDisplayPage (\r
919 VOID\r
920 )\r
921{\r
922 gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
923 gST->ConOut->ClearScreen (gST->ConOut);\r
5a9f73bf 924 gLibIsFirstForm = TRUE;\r
7c6c064c
ED
925}\r
926\r
927/**\r
928 Constructor of Customized Display Library Instance.\r
929\r
930 @param ImageHandle The firmware allocated handle for the EFI image.\r
931 @param SystemTable A pointer to the EFI System Table.\r
932\r
933 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
934\r
935**/\r
936EFI_STATUS\r
937EFIAPI\r
938CustomizedDisplayLibConstructor (\r
1436aea4
MK
939 IN EFI_HANDLE ImageHandle,\r
940 IN EFI_SYSTEM_TABLE *SystemTable\r
7c6c064c
ED
941 )\r
942{\r
943 mCDLStringPackHandle = HiiAddPackages (&gCustomizedDisplayLibGuid, ImageHandle, CustomizedDisplayLibStrings, NULL);\r
944 ASSERT (mCDLStringPackHandle != NULL);\r
945\r
1436aea4 946 InitializeLibStrings ();\r
7c6c064c
ED
947\r
948 return EFI_SUCCESS;\r
949}\r
950\r
951/**\r
952 Destructor of Customized Display Library Instance.\r
953\r
954 @param ImageHandle The firmware allocated handle for the EFI image.\r
955 @param SystemTable A pointer to the EFI System Table.\r
956\r
957 @retval EFI_SUCCESS The destructor completed successfully.\r
958 @retval Other value The destructor did not complete successfully.\r
959\r
960**/\r
961EFI_STATUS\r
962EFIAPI\r
963CustomizedDisplayLibDestructor (\r
964 IN EFI_HANDLE ImageHandle,\r
965 IN EFI_SYSTEM_TABLE *SystemTable\r
966 )\r
967{\r
1436aea4 968 HiiRemovePackages (mCDLStringPackHandle);\r
d1102dba 969\r
7c6c064c
ED
970 FreeLibStrings ();\r
971\r
972 return EFI_SUCCESS;\r
973}\r