]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c
MmcDxe Diagnostics: return EFI_UNSUPPORTED for Language other than english
[mirror_edk2.git] / MdeModulePkg / Library / CustomizedDisplayLib / CustomizedDisplayLibInternal.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_SCREEN_DESCRIPTOR gScreenDimensions;\r
18CHAR16 *mLibUnknownString;\r
19extern EFI_HII_HANDLE mCDLStringPackHandle;\r
20CHAR16 *mSpaceBuffer;\r
21#define SPACE_BUFFER_SIZE 1000\r
22\r
23//\r
24// Browser Global Strings\r
25//\r
26CHAR16 *gEnterString;\r
27CHAR16 *gEnterCommitString;\r
28CHAR16 *gEnterEscapeString;\r
29CHAR16 *gEscapeString;\r
30CHAR16 *gMoveHighlight;\r
31CHAR16 *gDecNumericInput;\r
32CHAR16 *gHexNumericInput;\r
33CHAR16 *gToggleCheckBox;\r
34CHAR16 *gLibEmptyString;\r
35CHAR16 *gAreYouSure;\r
36CHAR16 *gYesResponse;\r
37CHAR16 *gNoResponse;\r
38CHAR16 *gPlusString;\r
39CHAR16 *gMinusString;\r
40CHAR16 *gAdjustNumber;\r
41CHAR16 *gSaveChanges;\r
42CHAR16 *gNvUpdateMessage;\r
43CHAR16 *gInputErrorMessage;\r
44\r
45/**\r
46\r
47 Print banner info for front page.\r
48\r
49 @param[in] FormData Form Data to be shown in Page\r
50 \r
51**/\r
52VOID\r
53PrintBannerInfo ( \r
54 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
55 )\r
56{\r
57 UINT8 Line;\r
58 UINT8 Alignment;\r
59 CHAR16 *StrFrontPageBanner;\r
60 UINT8 RowIdx;\r
61 UINT8 ColumnIdx;\r
62\r
63 //\r
64 // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
65 //\r
66 ClearLines (\r
67 gScreenDimensions.LeftColumn,\r
68 gScreenDimensions.RightColumn,\r
69 gScreenDimensions.TopRow,\r
70 FRONT_PAGE_HEADER_HEIGHT - 1 + gScreenDimensions.TopRow,\r
71 BANNER_TEXT | BANNER_BACKGROUND\r
72 );\r
73\r
74 //\r
75 // for (Line = 0; Line < BANNER_HEIGHT; Line++) {\r
76 //\r
77 for (Line = (UINT8) gScreenDimensions.TopRow; Line < BANNER_HEIGHT + (UINT8) gScreenDimensions.TopRow; Line++) {\r
78 //\r
79 // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {\r
80 //\r
81 for (Alignment = (UINT8) gScreenDimensions.LeftColumn;\r
82 Alignment < BANNER_COLUMNS + (UINT8) gScreenDimensions.LeftColumn;\r
83 Alignment++\r
84 ) {\r
85 RowIdx = (UINT8) (Line - (UINT8) gScreenDimensions.TopRow);\r
86 ColumnIdx = (UINT8) (Alignment - (UINT8) gScreenDimensions.LeftColumn);\r
87 \r
88 ASSERT (RowIdx < BANNER_HEIGHT && ColumnIdx < BANNER_COLUMNS);\r
89 \r
90 if (gBannerData!= NULL && gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {\r
91 StrFrontPageBanner = LibGetToken (gBannerData->Banner[RowIdx][ColumnIdx], FormData->HiiHandle);\r
92 } else {\r
93 continue;\r
94 }\r
95 \r
96 switch (Alignment - gScreenDimensions.LeftColumn) {\r
97 case 0:\r
98 //\r
99 // Handle left column\r
100 //\r
101 PrintStringAt (gScreenDimensions.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);\r
102 break;\r
103 \r
104 case 1:\r
105 //\r
106 // Handle center column\r
107 //\r
108 PrintStringAt (\r
109 gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3,\r
110 Line,\r
111 StrFrontPageBanner\r
112 );\r
113 break;\r
114 \r
115 case 2:\r
116 //\r
117 // Handle right column\r
118 //\r
119 PrintStringAt (\r
120 gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) * 2 / 3,\r
121 Line,\r
122 StrFrontPageBanner\r
123 );\r
124 break;\r
125 }\r
126 \r
127 FreePool (StrFrontPageBanner);\r
128 }\r
129 }\r
130}\r
131\r
132/**\r
5a9f73bf 133 Print framework and form title for a page.\r
7c6c064c 134\r
5a9f73bf 135 @param[in] FormData Form Data to be shown in Page\r
7c6c064c
ED
136**/\r
137VOID\r
138PrintFramework (\r
5a9f73bf 139 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
7c6c064c
ED
140 )\r
141{\r
142 UINTN Index;\r
143 CHAR16 Character;\r
144 CHAR16 *Buffer;\r
145 UINTN Row;\r
5a9f73bf 146 CHAR16 *TitleStr;\r
7c6c064c 147\r
5a9f73bf
ED
148 if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) {\r
149 //\r
150 // Only Setup page needs Framework\r
151 //\r
152 ClearLines (\r
153 gScreenDimensions.LeftColumn,\r
154 gScreenDimensions.RightColumn,\r
155 gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,\r
156 gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1,\r
157 KEYHELP_TEXT | KEYHELP_BACKGROUND\r
158 );\r
159 return;\r
160 }\r
161 \r
7c6c064c
ED
162 Buffer = AllocateZeroPool (0x10000);\r
163 ASSERT (Buffer != NULL);\r
164 Character = BOXDRAW_HORIZONTAL;\r
165 for (Index = 0; Index + 2 < (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn); Index++) {\r
166 Buffer[Index] = Character;\r
167 }\r
168\r
5a9f73bf
ED
169 //\r
170 // Print Top border line\r
171 // +------------------------------------------------------------------------------+\r
172 // ? ?\r
173 // +------------------------------------------------------------------------------+\r
174 //\r
175 gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
176 Character = BOXDRAW_DOWN_RIGHT;\r
7c6c064c 177\r
5a9f73bf
ED
178 PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow, Character);\r
179 PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
7c6c064c 180\r
5a9f73bf
ED
181 Character = BOXDRAW_DOWN_LEFT;\r
182 PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
7c6c064c 183\r
5a9f73bf
ED
184 Character = BOXDRAW_VERTICAL;\r
185 for (Row = gScreenDimensions.TopRow + 1; Row <= gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {\r
186 PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);\r
187 PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);\r
7c6c064c
ED
188 }\r
189 \r
5a9f73bf
ED
190 //\r
191 // Print Form Title\r
192 //\r
7c6c064c
ED
193 ClearLines (\r
194 gScreenDimensions.LeftColumn + 1,\r
195 gScreenDimensions.RightColumn - 1,\r
196 gScreenDimensions.TopRow + 1,\r
197 gScreenDimensions.TopRow + 1,\r
198 TITLE_TEXT | TITLE_BACKGROUND\r
199 );\r
200\r
5a9f73bf
ED
201 TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle);\r
202 ASSERT (TitleStr != NULL);\r
7c6c064c
ED
203 PrintStringAt (\r
204 (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2,\r
205 gScreenDimensions.TopRow + 1,\r
206 TitleStr\r
207 );\r
7c6c064c 208 FreePool (TitleStr);\r
5a9f73bf
ED
209\r
210 Character = BOXDRAW_UP_RIGHT;\r
211 PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);\r
212 PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
213\r
214 Character = BOXDRAW_UP_LEFT;\r
215 PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
216\r
217 //\r
218 // Print Bottom border line\r
219 // +------------------------------------------------------------------------------+\r
220 // ? ?\r
221 // +------------------------------------------------------------------------------+\r
222 //\r
223 Character = BOXDRAW_DOWN_RIGHT;\r
224 PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);\r
225\r
226 PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
227\r
228 Character = BOXDRAW_DOWN_LEFT;\r
229 PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
230 Character = BOXDRAW_VERTICAL;\r
231 for (Row = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
232 Row <= gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;\r
233 Row++\r
234 ) {\r
235 PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);\r
236 PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);\r
237 }\r
238\r
239 Character = BOXDRAW_UP_RIGHT;\r
240 PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, Character);\r
241\r
242 PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);\r
243\r
244 Character = BOXDRAW_UP_LEFT;\r
245 PrintCharAt ((UINTN) -1, (UINTN) -1, Character);\r
246 \r
247 FreePool (Buffer);\r
7c6c064c
ED
248}\r
249\r
250/**\r
251 Process some op code which is not recognized by browser core.\r
252\r
253 @param OpCodeData The pointer to the op code buffer.\r
254\r
255 @return EFI_SUCCESS Pass the statement success.\r
256\r
257**/\r
258VOID\r
259ProcessUserOpcode(\r
260 IN EFI_IFR_OP_HEADER *OpCodeData\r
261 )\r
262{\r
263 switch (OpCodeData->OpCode) {\r
264 case EFI_IFR_GUID_OP: \r
265 if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)((CHAR8*) OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
266 //\r
267 // Tiano specific GUIDed opcodes\r
268 //\r
269 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
270 case EFI_IFR_EXTEND_OP_LABEL:\r
271 //\r
272 // just ignore label\r
273 //\r
274 break;\r
275\r
276 case EFI_IFR_EXTEND_OP_BANNER:\r
277 //\r
278 // Only in front page form set, we care about the banner data.\r
279 //\r
5a9f73bf 280 if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {\r
7c6c064c
ED
281 //\r
282 // Initialize Driver private data\r
283 //\r
284 if (gBannerData == NULL) {\r
285 gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));\r
286 ASSERT (gBannerData != NULL);\r
287 }\r
288 \r
289 CopyMem (\r
290 &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
291 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
292 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
293 sizeof (EFI_STRING_ID)\r
294 );\r
295 }\r
296 break;\r
297\r
298 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
299 if (((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
300 gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;\r
301 }\r
302 break;\r
303\r
304 default:\r
305 break;\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 Process some op codes which is out side of current form.\r
317 \r
318 @param FormData Pointer to the form data.\r
319\r
320 @return EFI_SUCCESS Pass the statement success.\r
321\r
322**/\r
323VOID\r
324ProcessExternedOpcode (\r
325 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
326 )\r
327{\r
328 LIST_ENTRY *Link;\r
329 FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
330\r
331 Link = GetFirstNode (&FormData->StatementListOSF);\r
332 while (!IsNull (&FormData->StatementListOSF, Link)) {\r
333 Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
334 Link = GetNextNode (&FormData->StatementListOSF, Link);\r
335\r
336 ProcessUserOpcode(Statement->OpCode);\r
337 }\r
338\r
339 Link = GetFirstNode (&FormData->StatementListHead);\r
340 while (!IsNull (&FormData->StatementListHead, Link)) {\r
341 Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
342 Link = GetNextNode (&FormData->StatementListHead, Link);\r
343\r
344 ProcessUserOpcode(Statement->OpCode);\r
345 }\r
346}\r
347\r
348/**\r
349 Validate the input screen diemenstion info.\r
350\r
351 @param FormData The input form data info.\r
352\r
353 @return EFI_SUCCESS The input screen info is acceptable.\r
354 @return EFI_INVALID_PARAMETER The input screen info is not acceptable.\r
355\r
356**/\r
357EFI_STATUS \r
358ScreenDiemensionInfoValidate (\r
359 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
360 )\r
361{\r
362 LIST_ENTRY *Link;\r
363 UINTN Index;\r
364\r
365 //\r
366 // Calculate total number of Register HotKeys. \r
367 //\r
368 Index = 0;\r
369 if (!IsListEmpty (&FormData->HotKeyListHead)){\r
370 Link = GetFirstNode (&FormData->HotKeyListHead);\r
371 while (!IsNull (&FormData->HotKeyListHead, Link)) {\r
372 Link = GetNextNode (&FormData->HotKeyListHead, Link);\r
373 Index ++;\r
374 }\r
375 }\r
376\r
377 //\r
378 // Show three HotKeys help information on one row.\r
379 //\r
380 gFooterHeight = FOOTER_HEIGHT + (Index / 3);\r
381\r
382\r
383 ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
384 gST->ConOut->QueryMode (\r
385 gST->ConOut,\r
386 gST->ConOut->Mode->Mode,\r
387 &gScreenDimensions.RightColumn,\r
388 &gScreenDimensions.BottomRow\r
389 );\r
390\r
391 //\r
392 // Check local dimension vs. global dimension.\r
393 //\r
394 if (FormData->ScreenDimensions != NULL) {\r
395 if ((gScreenDimensions.RightColumn < FormData->ScreenDimensions->RightColumn) ||\r
396 (gScreenDimensions.BottomRow < FormData->ScreenDimensions->BottomRow)\r
397 ) {\r
398 return EFI_INVALID_PARAMETER;\r
399 } else {\r
400 //\r
401 // Local dimension validation.\r
402 //\r
403 if ((FormData->ScreenDimensions->RightColumn > FormData->ScreenDimensions->LeftColumn) &&\r
404 (FormData->ScreenDimensions->BottomRow > FormData->ScreenDimensions->TopRow) &&\r
405 ((FormData->ScreenDimensions->RightColumn - FormData->ScreenDimensions->LeftColumn) > 2) &&\r
406 ((FormData->ScreenDimensions->BottomRow - FormData->ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +\r
407 FRONT_PAGE_HEADER_HEIGHT + gFooterHeight + 3)) {\r
408 CopyMem (&gScreenDimensions, (VOID *) FormData->ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
409 } else {\r
410 return EFI_INVALID_PARAMETER;\r
411 }\r
412 }\r
413 }\r
414\r
415 return EFI_SUCCESS;\r
416}\r
417\r
418/**\r
419 Get the string based on the StringId and HII Package List Handle.\r
420\r
421 @param Token The String's ID.\r
422 @param HiiHandle The package list in the HII database to search for\r
423 the specified string.\r
424\r
425 @return The output string.\r
426\r
427**/\r
428CHAR16 *\r
429LibGetToken (\r
430 IN EFI_STRING_ID Token,\r
431 IN EFI_HII_HANDLE HiiHandle\r
432 )\r
433{\r
434 EFI_STRING String;\r
435\r
436 String = HiiGetString (HiiHandle, Token, NULL);\r
437 if (String == NULL) {\r
438 String = AllocateCopyPool (StrSize (mLibUnknownString), mLibUnknownString);\r
439 ASSERT (String != NULL);\r
440 }\r
441\r
442 return (CHAR16 *) String;\r
443}\r
444\r
445\r
446/**\r
447 Count the storage space of a Unicode string.\r
448\r
449 This function handles the Unicode string with NARROW_CHAR\r
450 and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR\r
451 does not count in the resultant output. If a WIDE_CHAR is\r
452 hit, then 2 Unicode character will consume an output storage\r
453 space with size of CHAR16 till a NARROW_CHAR is hit.\r
454\r
455 If String is NULL, then ASSERT ().\r
456\r
457 @param String The input string to be counted.\r
458\r
459 @return Storage space for the input string.\r
460\r
461**/\r
462UINTN\r
463LibGetStringWidth (\r
464 IN CHAR16 *String\r
465 )\r
466{\r
467 UINTN Index;\r
468 UINTN Count;\r
469 UINTN IncrementValue;\r
470\r
471 ASSERT (String != NULL);\r
472 if (String == NULL) {\r
473 return 0;\r
474 }\r
475\r
476 Index = 0;\r
477 Count = 0;\r
478 IncrementValue = 1;\r
479\r
480 do {\r
481 //\r
482 // Advance to the null-terminator or to the first width directive\r
483 //\r
484 for (;\r
485 (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);\r
486 Index++, Count = Count + IncrementValue\r
487 )\r
488 ;\r
489\r
490 //\r
491 // We hit the null-terminator, we now have a count\r
492 //\r
493 if (String[Index] == 0) {\r
494 break;\r
495 }\r
496 //\r
497 // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed\r
498 // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)\r
499 //\r
500 if (String[Index] == NARROW_CHAR) {\r
501 //\r
502 // Skip to the next character\r
503 //\r
504 Index++;\r
505 IncrementValue = 1;\r
506 } else {\r
507 //\r
508 // Skip to the next character\r
509 //\r
510 Index++;\r
511 IncrementValue = 2;\r
512 }\r
513 } while (String[Index] != 0);\r
514\r
515 //\r
516 // Increment by one to include the null-terminator in the size\r
517 //\r
518 Count++;\r
519\r
520 return Count * sizeof (CHAR16);\r
521}\r
522\r
523/**\r
524 Show all registered HotKey help strings on bottom Rows.\r
525\r
526 @param FormData The curent input form data info.\r
527\r
528**/\r
529VOID\r
530PrintHotKeyHelpString (\r
531 IN FORM_DISPLAY_ENGINE_FORM *FormData\r
532 )\r
533{\r
534 UINTN CurrentCol;\r
535 UINTN CurrentRow;\r
536 UINTN BottomRowOfHotKeyHelp;\r
537 UINTN ColumnWidth;\r
538 UINTN Index;\r
539 EFI_SCREEN_DESCRIPTOR LocalScreen;\r
540 LIST_ENTRY *Link;\r
541 BROWSER_HOT_KEY *HotKey;\r
542\r
543 if (IsListEmpty (&FormData->HotKeyListHead)) {\r
544 return;\r
545 }\r
546\r
547 CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
548 ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
549 BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;\r
550\r
551 //\r
552 // Calculate total number of Register HotKeys. \r
553 //\r
554 Index = 0;\r
555 Link = GetFirstNode (&FormData->HotKeyListHead);\r
556 while (!IsNull (&FormData->HotKeyListHead, Link)) {\r
557 HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
558 //\r
559 // Help string can't exceed ColumnWidth. One Row will show three Help information. \r
560 //\r
561 if (StrLen (HotKey->HelpString) > ColumnWidth) {\r
562 HotKey->HelpString[ColumnWidth] = L'\0';\r
563 }\r
564 //\r
565 // Calculate help information Column and Row.\r
566 //\r
567 if ((Index % 3) != 2) {\r
568 CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;\r
569 } else {\r
570 CurrentCol = LocalScreen.LeftColumn + 2;\r
571 }\r
572 CurrentRow = BottomRowOfHotKeyHelp - Index / 3;\r
573 //\r
574 // Print HotKey help string on bottom Row.\r
575 //\r
576 PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);\r
577\r
578 //\r
579 // Get Next Hot Key.\r
580 //\r
581 Link = GetNextNode (&FormData->HotKeyListHead, Link);\r
582 Index ++;\r
583 }\r
584 \r
585 return;\r
586}\r
587\r
588/**\r
589 Get step info from numeric opcode.\r
590 \r
591 @param[in] OpCode The input numeric op code.\r
592\r
593 @return step info for this opcode.\r
594**/\r
595UINT64\r
596LibGetFieldFromNum (\r
597 IN EFI_IFR_OP_HEADER *OpCode\r
598 )\r
599{\r
600 EFI_IFR_NUMERIC *NumericOp;\r
601 UINT64 Step;\r
602\r
603 NumericOp = (EFI_IFR_NUMERIC *) OpCode;\r
604 \r
605 switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {\r
606 case EFI_IFR_NUMERIC_SIZE_1:\r
607 Step = NumericOp->data.u8.Step;\r
608 break;\r
609 \r
610 case EFI_IFR_NUMERIC_SIZE_2:\r
611 Step = NumericOp->data.u16.Step;\r
612 break;\r
613 \r
614 case EFI_IFR_NUMERIC_SIZE_4:\r
615 Step = NumericOp->data.u32.Step;\r
616 break;\r
617 \r
618 case EFI_IFR_NUMERIC_SIZE_8:\r
619 Step = NumericOp->data.u64.Step;\r
620 break;\r
621 \r
622 default:\r
623 Step = 0;\r
624 break;\r
625 }\r
626\r
627 return Step;\r
628}\r
629\r
630/**\r
631 Initialize the HII String Token to the correct values.\r
632\r
633**/\r
634VOID\r
635InitializeLibStrings (\r
636 VOID\r
637 )\r
638{\r
639 mLibUnknownString = L"!";\r
640\r
641 gEnterString = LibGetToken (STRING_TOKEN (ENTER_STRING), mCDLStringPackHandle);\r
642 gEnterCommitString = LibGetToken (STRING_TOKEN (ENTER_COMMIT_STRING), mCDLStringPackHandle);\r
643 gEnterEscapeString = LibGetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), mCDLStringPackHandle);\r
644 gEscapeString = LibGetToken (STRING_TOKEN (ESCAPE_STRING), mCDLStringPackHandle);\r
645 gMoveHighlight = LibGetToken (STRING_TOKEN (MOVE_HIGHLIGHT), mCDLStringPackHandle);\r
646 gDecNumericInput = LibGetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), mCDLStringPackHandle);\r
647 gHexNumericInput = LibGetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), mCDLStringPackHandle);\r
648 gToggleCheckBox = LibGetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), mCDLStringPackHandle);\r
649\r
650 gAreYouSure = LibGetToken (STRING_TOKEN (ARE_YOU_SURE), mCDLStringPackHandle);\r
651 gYesResponse = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_YES), mCDLStringPackHandle);\r
652 gNoResponse = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_NO), mCDLStringPackHandle);\r
653 gPlusString = LibGetToken (STRING_TOKEN (PLUS_STRING), mCDLStringPackHandle);\r
654 gMinusString = LibGetToken (STRING_TOKEN (MINUS_STRING), mCDLStringPackHandle);\r
655 gAdjustNumber = LibGetToken (STRING_TOKEN (ADJUST_NUMBER), mCDLStringPackHandle);\r
656 gSaveChanges = LibGetToken (STRING_TOKEN (SAVE_CHANGES), mCDLStringPackHandle);\r
657\r
658 gLibEmptyString = LibGetToken (STRING_TOKEN (EMPTY_STRING), mCDLStringPackHandle);\r
659\r
660 gNvUpdateMessage = LibGetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), mCDLStringPackHandle);\r
661 gInputErrorMessage = LibGetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), mCDLStringPackHandle);\r
662 \r
663 //\r
664 // SpaceBuffer;\r
665 //\r
666 mSpaceBuffer = AllocatePool ((SPACE_BUFFER_SIZE + 1) * sizeof (CHAR16));\r
667 ASSERT (mSpaceBuffer != NULL);\r
668 LibSetUnicodeMem (mSpaceBuffer, SPACE_BUFFER_SIZE, L' ');\r
669 mSpaceBuffer[SPACE_BUFFER_SIZE] = L'\0';\r
670}\r
671\r
672\r
673/**\r
674 Free the HII String.\r
675\r
676**/\r
677VOID\r
678FreeLibStrings (\r
679 VOID\r
680 )\r
681{\r
682 FreePool (gEnterString);\r
683 FreePool (gEnterCommitString);\r
684 FreePool (gEnterEscapeString);\r
685 FreePool (gEscapeString);\r
686 FreePool (gMoveHighlight);\r
687 FreePool (gDecNumericInput);\r
688 FreePool (gHexNumericInput);\r
689 FreePool (gToggleCheckBox);\r
690\r
691 FreePool (gAreYouSure);\r
692 FreePool (gYesResponse);\r
693 FreePool (gNoResponse);\r
694 FreePool (gPlusString);\r
695 FreePool (gMinusString);\r
696 FreePool (gAdjustNumber);\r
697 FreePool (gSaveChanges);\r
698\r
699 FreePool (gLibEmptyString);\r
700\r
701 FreePool (gNvUpdateMessage);\r
702 FreePool (gInputErrorMessage);\r
703 \r
704 FreePool (mSpaceBuffer);\r
705}\r
706\r
707/**\r
708 Wait for a key to be pressed by user.\r
709\r
710 @param Key The key which is pressed by user.\r
711\r
712 @retval EFI_SUCCESS The function always completed successfully.\r
713\r
714**/\r
715EFI_STATUS\r
716WaitForKeyStroke (\r
717 OUT EFI_INPUT_KEY *Key\r
718 )\r
719{\r
720 EFI_STATUS Status;\r
721 UINTN Index;\r
722\r
723 while (TRUE) {\r
724 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);\r
725 if (!EFI_ERROR (Status)) {\r
726 break;\r
727 }\r
728\r
729 if (Status != EFI_NOT_READY) {\r
730 continue;\r
731 }\r
732 \r
733 gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);\r
734 }\r
735 return Status;\r
736}\r
737\r
738\r
739/**\r
740 Set Buffer to Value for Size bytes.\r
741\r
742 @param Buffer Memory to set.\r
743 @param Size Number of bytes to set\r
744 @param Value Value of the set operation.\r
745\r
746**/\r
747VOID\r
748LibSetUnicodeMem (\r
749 IN VOID *Buffer,\r
750 IN UINTN Size,\r
751 IN CHAR16 Value\r
752 )\r
753{\r
754 CHAR16 *Ptr;\r
755\r
756 Ptr = Buffer;\r
757 while ((Size--) != 0) {\r
758 *(Ptr++) = Value;\r
759 }\r
760}\r
761\r
762/**\r
763 The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
764 protocol instance.\r
765\r
766 @param Width Width of string to be print.\r
767 @param Column The position of the output string.\r
768 @param Row The position of the output string.\r
769 @param Out The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.\r
770 @param Fmt The format string.\r
771 @param Args The additional argument for the variables in the format string.\r
772\r
773 @return Number of Unicode character printed.\r
774\r
775**/\r
776UINTN\r
777PrintInternal (\r
778 IN UINTN Width, \r
779 IN UINTN Column,\r
780 IN UINTN Row,\r
781 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Out,\r
782 IN CHAR16 *Fmt,\r
783 IN VA_LIST Args\r
784 )\r
785{\r
786 CHAR16 *Buffer;\r
787 CHAR16 *BackupBuffer;\r
788 UINTN Index;\r
789 UINTN PreviousIndex;\r
790 UINTN Count;\r
791 UINTN PrintWidth;\r
792 UINTN CharWidth;\r
793\r
794 //\r
795 // For now, allocate an arbitrarily long buffer\r
796 //\r
797 Buffer = AllocateZeroPool (0x10000);\r
798 BackupBuffer = AllocateZeroPool (0x10000);\r
799 ASSERT (Buffer);\r
800 ASSERT (BackupBuffer);\r
801\r
802 if (Column != (UINTN) -1) {\r
803 Out->SetCursorPosition (Out, Column, Row);\r
804 }\r
805\r
806 UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);\r
807\r
808 Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
809\r
810 Out->SetAttribute (Out, Out->Mode->Attribute);\r
811\r
812 Index = 0;\r
813 PreviousIndex = 0;\r
814 Count = 0;\r
815 PrintWidth = 0;\r
816 CharWidth = 1;\r
817\r
818 do {\r
819 for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {\r
820 BackupBuffer[Index] = Buffer[Index];\r
821 }\r
822\r
823 if (Buffer[Index] == 0) {\r
824 break;\r
825 }\r
826 //\r
827 // Null-terminate the temporary string\r
828 //\r
829 BackupBuffer[Index] = 0;\r
830\r
831 //\r
832 // Print this out, we are about to switch widths\r
833 //\r
834 Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
835 Count += StrLen (&BackupBuffer[PreviousIndex]);\r
836 PrintWidth += Count * CharWidth;\r
837\r
838 //\r
839 // Preserve the current index + 1, since this is where we will start printing from next\r
840 //\r
841 PreviousIndex = Index + 1;\r
842\r
843 //\r
844 // We are at a narrow or wide character directive. Set attributes and strip it and print it\r
845 //\r
846 if (Buffer[Index] == NARROW_CHAR) {\r
847 //\r
848 // Preserve bits 0 - 6 and zero out the rest\r
849 //\r
850 Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
851 Out->SetAttribute (Out, Out->Mode->Attribute);\r
852 CharWidth = 1;\r
853 } else {\r
854 //\r
855 // Must be wide, set bit 7 ON\r
856 //\r
857 Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;\r
858 Out->SetAttribute (Out, Out->Mode->Attribute);\r
859 CharWidth = 2;\r
860 }\r
861\r
862 Index++;\r
863\r
864 } while (Buffer[Index] != 0);\r
865\r
866 //\r
867 // We hit the end of the string - print it\r
868 //\r
869 Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
870 Count += StrLen (&BackupBuffer[PreviousIndex]);\r
871 PrintWidth += Count * CharWidth;\r
872 if (PrintWidth < Width) {\r
873 Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
874 Out->SetAttribute (Out, Out->Mode->Attribute);\r
875 Out->OutputString (Out, &mSpaceBuffer[SPACE_BUFFER_SIZE - Width + PrintWidth]);\r
876 }\r
877\r
878 FreePool (Buffer);\r
879 FreePool (BackupBuffer);\r
880 return Count;\r
881}\r
882\r
883/**\r
884 Prints a formatted unicode string to the default console, at\r
885 the supplied cursor position.\r
886\r
887 @param Width Width of String to be printed.\r
888 @param Column The cursor position to print the string at.\r
889 @param Row The cursor position to print the string at.\r
890 @param Fmt Format string.\r
891 @param ... Variable argument list for format string.\r
892\r
893 @return Length of string printed to the console\r
894\r
895**/\r
896UINTN\r
897EFIAPI\r
898PrintAt (\r
899 IN UINTN Width,\r
900 IN UINTN Column,\r
901 IN UINTN Row,\r
902 IN CHAR16 *Fmt,\r
903 ...\r
904 )\r
905{\r
906 VA_LIST Args;\r
907 UINTN LengthOfPrinted;\r
908\r
909 VA_START (Args, Fmt);\r
910 LengthOfPrinted = PrintInternal (Width, Column, Row, gST->ConOut, Fmt, Args);\r
911 VA_END (Args);\r
912 return LengthOfPrinted;\r
913}\r
914\r