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