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