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