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