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