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