VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette