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