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