REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			988 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			988 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
 | 
						|
  This library class defines a set of interfaces to customize Display module
 | 
						|
 | 
						|
Copyright (c) 2013-2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
#include "CustomizedDisplayLibInternal.h"
 | 
						|
 | 
						|
EFI_SCREEN_DESCRIPTOR  gScreenDimensions;
 | 
						|
CHAR16                 *mLibUnknownString;
 | 
						|
extern EFI_HII_HANDLE  mCDLStringPackHandle;
 | 
						|
CHAR16                 *mSpaceBuffer;
 | 
						|
#define SPACE_BUFFER_SIZE  1000
 | 
						|
 | 
						|
//
 | 
						|
// Browser Global Strings
 | 
						|
//
 | 
						|
CHAR16  *gEnterString;
 | 
						|
CHAR16  *gEnterCommitString;
 | 
						|
CHAR16  *gEnterEscapeString;
 | 
						|
CHAR16  *gEscapeString;
 | 
						|
CHAR16  *gMoveHighlight;
 | 
						|
CHAR16  *gDecNumericInput;
 | 
						|
CHAR16  *gHexNumericInput;
 | 
						|
CHAR16  *gToggleCheckBox;
 | 
						|
CHAR16  *gLibEmptyString;
 | 
						|
CHAR16  *gAreYouSure;
 | 
						|
CHAR16  *gYesResponse;
 | 
						|
CHAR16  *gNoResponse;
 | 
						|
CHAR16  *gPlusString;
 | 
						|
CHAR16  *gMinusString;
 | 
						|
CHAR16  *gAdjustNumber;
 | 
						|
CHAR16  *gSaveChanges;
 | 
						|
CHAR16  *gNvUpdateMessage;
 | 
						|
CHAR16  *gInputErrorMessage;
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Print banner info for front page.
 | 
						|
 | 
						|
  @param[in]  FormData             Form Data to be shown in Page
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
PrintBannerInfo (
 | 
						|
  IN FORM_DISPLAY_ENGINE_FORM  *FormData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8   Line;
 | 
						|
  UINT8   Alignment;
 | 
						|
  CHAR16  *StrFrontPageBanner;
 | 
						|
  UINT8   RowIdx;
 | 
						|
  UINT8   ColumnIdx;
 | 
						|
 | 
						|
  //
 | 
						|
  //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
 | 
						|
  //
 | 
						|
  ClearLines (
 | 
						|
    gScreenDimensions.LeftColumn,
 | 
						|
    gScreenDimensions.RightColumn,
 | 
						|
    gScreenDimensions.TopRow,
 | 
						|
    FRONT_PAGE_HEADER_HEIGHT - 1 + gScreenDimensions.TopRow,
 | 
						|
    BANNER_TEXT | BANNER_BACKGROUND
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {
 | 
						|
  //
 | 
						|
  for (Line = (UINT8)gScreenDimensions.TopRow; Line < BANNER_HEIGHT + (UINT8)gScreenDimensions.TopRow; Line++) {
 | 
						|
    //
 | 
						|
    //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
 | 
						|
    //
 | 
						|
    for (Alignment = (UINT8)gScreenDimensions.LeftColumn;
 | 
						|
         Alignment < BANNER_COLUMNS + (UINT8)gScreenDimensions.LeftColumn;
 | 
						|
         Alignment++
 | 
						|
         )
 | 
						|
    {
 | 
						|
      RowIdx    = (UINT8)(Line - (UINT8)gScreenDimensions.TopRow);
 | 
						|
      ColumnIdx = (UINT8)(Alignment - (UINT8)gScreenDimensions.LeftColumn);
 | 
						|
 | 
						|
      ASSERT (RowIdx < BANNER_HEIGHT && ColumnIdx < BANNER_COLUMNS);
 | 
						|
 | 
						|
      if ((gBannerData != NULL) && (gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000)) {
 | 
						|
        StrFrontPageBanner = LibGetToken (gBannerData->Banner[RowIdx][ColumnIdx], FormData->HiiHandle);
 | 
						|
      } else {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      switch (Alignment - gScreenDimensions.LeftColumn) {
 | 
						|
        case 0:
 | 
						|
          //
 | 
						|
          // Handle left column
 | 
						|
          //
 | 
						|
          PrintStringAt (gScreenDimensions.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);
 | 
						|
          break;
 | 
						|
 | 
						|
        case 1:
 | 
						|
          //
 | 
						|
          // Handle center column
 | 
						|
          //
 | 
						|
          PrintStringAt (
 | 
						|
            gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3,
 | 
						|
            Line,
 | 
						|
            StrFrontPageBanner
 | 
						|
            );
 | 
						|
          break;
 | 
						|
 | 
						|
        case 2:
 | 
						|
          //
 | 
						|
          // Handle right column
 | 
						|
          //
 | 
						|
          PrintStringAt (
 | 
						|
            gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) * 2 / 3,
 | 
						|
            Line,
 | 
						|
            StrFrontPageBanner
 | 
						|
            );
 | 
						|
          break;
 | 
						|
      }
 | 
						|
 | 
						|
      FreePool (StrFrontPageBanner);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Print framework and form title for a page.
 | 
						|
 | 
						|
  @param[in]  FormData             Form Data to be shown in Page
 | 
						|
**/
 | 
						|
VOID
 | 
						|
PrintFramework (
 | 
						|
  IN FORM_DISPLAY_ENGINE_FORM  *FormData
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   Index;
 | 
						|
  CHAR16  Character;
 | 
						|
  CHAR16  *Buffer;
 | 
						|
  UINTN   Row;
 | 
						|
  CHAR16  *TitleStr;
 | 
						|
  UINTN   TitleColumn;
 | 
						|
 | 
						|
  if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) {
 | 
						|
    //
 | 
						|
    // Only Setup page needs Framework
 | 
						|
    //
 | 
						|
    ClearLines (
 | 
						|
      gScreenDimensions.LeftColumn,
 | 
						|
      gScreenDimensions.RightColumn,
 | 
						|
      gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,
 | 
						|
      gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1,
 | 
						|
      KEYHELP_TEXT | KEYHELP_BACKGROUND
 | 
						|
      );
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Buffer = AllocateZeroPool (0x10000);
 | 
						|
  ASSERT (Buffer != NULL);
 | 
						|
  Character = BOXDRAW_HORIZONTAL;
 | 
						|
  for (Index = 0; Index + 2 < (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn); Index++) {
 | 
						|
    Buffer[Index] = Character;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Print Top border line
 | 
						|
  // +------------------------------------------------------------------------------+
 | 
						|
  // ?                                                                             ?
 | 
						|
  // +------------------------------------------------------------------------------+
 | 
						|
  //
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
 | 
						|
  Character = BOXDRAW_DOWN_RIGHT;
 | 
						|
 | 
						|
  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow, Character);
 | 
						|
  PrintStringAt ((UINTN)-1, (UINTN)-1, Buffer);
 | 
						|
 | 
						|
  Character = BOXDRAW_DOWN_LEFT;
 | 
						|
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
 | 
						|
 | 
						|
  Character = BOXDRAW_VERTICAL;
 | 
						|
  for (Row = gScreenDimensions.TopRow + 1; Row <= gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
 | 
						|
    PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);
 | 
						|
    PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Print Form Title
 | 
						|
  //
 | 
						|
  TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle);
 | 
						|
  ASSERT (TitleStr != NULL);
 | 
						|
  TitleColumn = (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2;
 | 
						|
  PrintStringAtWithWidth (gScreenDimensions.LeftColumn + 1, gScreenDimensions.TopRow + 1, gLibEmptyString, TitleColumn - gScreenDimensions.LeftColumn - 1);
 | 
						|
  PrintStringAtWithWidth (
 | 
						|
    TitleColumn,
 | 
						|
    gScreenDimensions.TopRow + 1,
 | 
						|
    TitleStr,
 | 
						|
    gScreenDimensions.RightColumn - 1 - TitleColumn
 | 
						|
    );
 | 
						|
  FreePool (TitleStr);
 | 
						|
 | 
						|
  Character = BOXDRAW_UP_RIGHT;
 | 
						|
  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
 | 
						|
  PrintStringAt ((UINTN)-1, (UINTN)-1, Buffer);
 | 
						|
 | 
						|
  Character = BOXDRAW_UP_LEFT;
 | 
						|
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
 | 
						|
 | 
						|
  //
 | 
						|
  // Print Bottom border line
 | 
						|
  // +------------------------------------------------------------------------------+
 | 
						|
  // ?                                                                             ?
 | 
						|
  // +------------------------------------------------------------------------------+
 | 
						|
  //
 | 
						|
  Character = BOXDRAW_DOWN_RIGHT;
 | 
						|
  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);
 | 
						|
 | 
						|
  PrintStringAt ((UINTN)-1, (UINTN)-1, Buffer);
 | 
						|
 | 
						|
  Character = BOXDRAW_DOWN_LEFT;
 | 
						|
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
 | 
						|
  Character = BOXDRAW_VERTICAL;
 | 
						|
  for (Row = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
 | 
						|
       Row <= gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;
 | 
						|
       Row++
 | 
						|
       )
 | 
						|
  {
 | 
						|
    PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);
 | 
						|
    PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);
 | 
						|
  }
 | 
						|
 | 
						|
  Character = BOXDRAW_UP_RIGHT;
 | 
						|
  PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
 | 
						|
 | 
						|
  PrintStringAt ((UINTN)-1, (UINTN)-1, Buffer);
 | 
						|
 | 
						|
  Character = BOXDRAW_UP_LEFT;
 | 
						|
  PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
 | 
						|
 | 
						|
  FreePool (Buffer);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Process some op code which is not recognized by browser core.
 | 
						|
 | 
						|
  @param OpCodeData                  The pointer to the op code buffer.
 | 
						|
 | 
						|
  @return EFI_SUCCESS            Pass the statement success.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ProcessUserOpcode (
 | 
						|
  IN  EFI_IFR_OP_HEADER  *OpCodeData
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_GUID  *ClassGuid;
 | 
						|
  UINT8     ClassGuidNum;
 | 
						|
 | 
						|
  ClassGuid    = NULL;
 | 
						|
  ClassGuidNum = 0;
 | 
						|
 | 
						|
  switch (OpCodeData->OpCode) {
 | 
						|
    case EFI_IFR_FORM_SET_OP:
 | 
						|
      //
 | 
						|
      // process the statement outside of form,if it is formset op, get its formsetguid or classguid and compared with gFrontPageFormSetGuid
 | 
						|
      //
 | 
						|
      if (CompareMem (PcdGetPtr (PcdFrontPageFormSetGuid), &((EFI_IFR_FORM_SET *)OpCodeData)->Guid, sizeof (EFI_GUID)) == 0) {
 | 
						|
        gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
 | 
						|
      } else {
 | 
						|
        ClassGuidNum = (UINT8)(((EFI_IFR_FORM_SET *)OpCodeData)->Flags & 0x3);
 | 
						|
        ClassGuid    = (EFI_GUID *)(VOID *)((UINT8 *)OpCodeData + sizeof (EFI_IFR_FORM_SET));
 | 
						|
        while (ClassGuidNum-- > 0) {
 | 
						|
          if (CompareGuid ((EFI_GUID *)PcdGetPtr (PcdFrontPageFormSetGuid), ClassGuid)) {
 | 
						|
            gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
 | 
						|
          ClassGuid++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_GUID_OP:
 | 
						|
      if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)((CHAR8 *)OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
 | 
						|
        //
 | 
						|
        // Tiano specific GUIDed opcodes
 | 
						|
        //
 | 
						|
        switch (((EFI_IFR_GUID_LABEL *)OpCodeData)->ExtendOpCode) {
 | 
						|
          case EFI_IFR_EXTEND_OP_LABEL:
 | 
						|
            //
 | 
						|
            // just ignore label
 | 
						|
            //
 | 
						|
            break;
 | 
						|
 | 
						|
          case EFI_IFR_EXTEND_OP_BANNER:
 | 
						|
            //
 | 
						|
            // Only in front page form set, we care about the banner data.
 | 
						|
            //
 | 
						|
            if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {
 | 
						|
              //
 | 
						|
              // Initialize Driver private data
 | 
						|
              //
 | 
						|
              if (gBannerData == NULL) {
 | 
						|
                gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));
 | 
						|
                ASSERT (gBannerData != NULL);
 | 
						|
              }
 | 
						|
 | 
						|
              CopyMem (
 | 
						|
                &gBannerData->Banner[((EFI_IFR_GUID_BANNER *)OpCodeData)->LineNumber][
 | 
						|
                                                                                      ((EFI_IFR_GUID_BANNER *)OpCodeData)->Alignment],
 | 
						|
                &((EFI_IFR_GUID_BANNER *)OpCodeData)->Title,
 | 
						|
                sizeof (EFI_STRING_ID)
 | 
						|
                );
 | 
						|
            }
 | 
						|
 | 
						|
            break;
 | 
						|
 | 
						|
          case EFI_IFR_EXTEND_OP_SUBCLASS:
 | 
						|
            if (((EFI_IFR_GUID_SUBCLASS *)OpCodeData)->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
 | 
						|
              gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
 | 
						|
            }
 | 
						|
 | 
						|
            break;
 | 
						|
 | 
						|
          default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Process some op codes which is out side of current form.
 | 
						|
 | 
						|
  @param FormData                Pointer to the form data.
 | 
						|
 | 
						|
  @return EFI_SUCCESS            Pass the statement success.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
ProcessExternedOpcode (
 | 
						|
  IN FORM_DISPLAY_ENGINE_FORM  *FormData
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY                     *Link;
 | 
						|
  LIST_ENTRY                     *NestLink;
 | 
						|
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
 | 
						|
  FORM_DISPLAY_ENGINE_STATEMENT  *NestStatement;
 | 
						|
 | 
						|
  Link = GetFirstNode (&FormData->StatementListOSF);
 | 
						|
  while (!IsNull (&FormData->StatementListOSF, Link)) {
 | 
						|
    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
 | 
						|
    Link      = GetNextNode (&FormData->StatementListOSF, Link);
 | 
						|
 | 
						|
    ProcessUserOpcode (Statement->OpCode);
 | 
						|
  }
 | 
						|
 | 
						|
  Link = GetFirstNode (&FormData->StatementListHead);
 | 
						|
  while (!IsNull (&FormData->StatementListHead, Link)) {
 | 
						|
    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
 | 
						|
    Link      = GetNextNode (&FormData->StatementListHead, Link);
 | 
						|
 | 
						|
    ProcessUserOpcode (Statement->OpCode);
 | 
						|
 | 
						|
    NestLink = GetFirstNode (&Statement->NestStatementList);
 | 
						|
    while (!IsNull (&Statement->NestStatementList, NestLink)) {
 | 
						|
      NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);
 | 
						|
      NestLink      = GetNextNode (&Statement->NestStatementList, NestLink);
 | 
						|
 | 
						|
      ProcessUserOpcode (NestStatement->OpCode);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Validate the input screen diemenstion info.
 | 
						|
 | 
						|
  @param  FormData               The input form data info.
 | 
						|
 | 
						|
  @return EFI_SUCCESS            The input screen info is acceptable.
 | 
						|
  @return EFI_INVALID_PARAMETER  The input screen info is not acceptable.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
ScreenDiemensionInfoValidate (
 | 
						|
  IN FORM_DISPLAY_ENGINE_FORM  *FormData
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY  *Link;
 | 
						|
  UINTN       Index;
 | 
						|
 | 
						|
  //
 | 
						|
  // Calculate total number of Register HotKeys.
 | 
						|
  //
 | 
						|
  Index = 0;
 | 
						|
  if (!IsListEmpty (&FormData->HotKeyListHead)) {
 | 
						|
    Link = GetFirstNode (&FormData->HotKeyListHead);
 | 
						|
    while (!IsNull (&FormData->HotKeyListHead, Link)) {
 | 
						|
      Link = GetNextNode (&FormData->HotKeyListHead, Link);
 | 
						|
      Index++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Show three HotKeys help information on one row.
 | 
						|
  //
 | 
						|
  gFooterHeight = FOOTER_HEIGHT + (Index / 3);
 | 
						|
 | 
						|
  ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
  gST->ConOut->QueryMode (
 | 
						|
                 gST->ConOut,
 | 
						|
                 gST->ConOut->Mode->Mode,
 | 
						|
                 &gScreenDimensions.RightColumn,
 | 
						|
                 &gScreenDimensions.BottomRow
 | 
						|
                 );
 | 
						|
 | 
						|
  //
 | 
						|
  // Check local dimension vs. global dimension.
 | 
						|
  //
 | 
						|
  if (FormData->ScreenDimensions != NULL) {
 | 
						|
    if ((gScreenDimensions.RightColumn < FormData->ScreenDimensions->RightColumn) ||
 | 
						|
        (gScreenDimensions.BottomRow < FormData->ScreenDimensions->BottomRow)
 | 
						|
        )
 | 
						|
    {
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Local dimension validation.
 | 
						|
      //
 | 
						|
      if ((FormData->ScreenDimensions->RightColumn > FormData->ScreenDimensions->LeftColumn) &&
 | 
						|
          (FormData->ScreenDimensions->BottomRow > FormData->ScreenDimensions->TopRow) &&
 | 
						|
          ((FormData->ScreenDimensions->RightColumn - FormData->ScreenDimensions->LeftColumn) > 2) &&
 | 
						|
          ((FormData->ScreenDimensions->BottomRow - FormData->ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +
 | 
						|
           FRONT_PAGE_HEADER_HEIGHT + gFooterHeight + 3))
 | 
						|
      {
 | 
						|
        CopyMem (&gScreenDimensions, (VOID *)FormData->ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
      } else {
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get the string based on the StringId and HII Package List Handle.
 | 
						|
 | 
						|
  @param  Token                  The String's ID.
 | 
						|
  @param  HiiHandle              The package list in the HII database to search for
 | 
						|
                                 the specified string.
 | 
						|
 | 
						|
  @return The output string.
 | 
						|
 | 
						|
**/
 | 
						|
CHAR16 *
 | 
						|
LibGetToken (
 | 
						|
  IN  EFI_STRING_ID   Token,
 | 
						|
  IN  EFI_HII_HANDLE  HiiHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STRING  String;
 | 
						|
 | 
						|
  String = HiiGetString (HiiHandle, Token, NULL);
 | 
						|
  if (String == NULL) {
 | 
						|
    String = AllocateCopyPool (StrSize (mLibUnknownString), mLibUnknownString);
 | 
						|
    ASSERT (String != NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  return (CHAR16 *)String;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Count the storage space of a Unicode string.
 | 
						|
 | 
						|
  This function handles the Unicode string with NARROW_CHAR
 | 
						|
  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
 | 
						|
  does not count in the resultant output. If a WIDE_CHAR is
 | 
						|
  hit, then 2 Unicode character will consume an output storage
 | 
						|
  space with size of CHAR16 till a NARROW_CHAR is hit.
 | 
						|
 | 
						|
  If String is NULL, then ASSERT ().
 | 
						|
 | 
						|
  @param String          The input string to be counted.
 | 
						|
 | 
						|
  @return Storage space for the input string.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
LibGetStringWidth (
 | 
						|
  IN CHAR16  *String
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Index;
 | 
						|
  UINTN  Count;
 | 
						|
  UINTN  IncrementValue;
 | 
						|
 | 
						|
  ASSERT (String != NULL);
 | 
						|
  if (String == NULL) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  Index          = 0;
 | 
						|
  Count          = 0;
 | 
						|
  IncrementValue = 1;
 | 
						|
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // Advance to the null-terminator or to the first width directive
 | 
						|
    //
 | 
						|
    for ( ;
 | 
						|
          (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
 | 
						|
          Index++, Count = Count + IncrementValue
 | 
						|
          )
 | 
						|
    {
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // We hit the null-terminator, we now have a count
 | 
						|
    //
 | 
						|
    if (String[Index] == 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
 | 
						|
    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
 | 
						|
    //
 | 
						|
    if (String[Index] == NARROW_CHAR) {
 | 
						|
      //
 | 
						|
      // Skip to the next character
 | 
						|
      //
 | 
						|
      Index++;
 | 
						|
      IncrementValue = 1;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Skip to the next character
 | 
						|
      //
 | 
						|
      Index++;
 | 
						|
      IncrementValue = 2;
 | 
						|
    }
 | 
						|
  } while (String[Index] != 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // Increment by one to include the null-terminator in the size
 | 
						|
  //
 | 
						|
  Count++;
 | 
						|
 | 
						|
  return Count * sizeof (CHAR16);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Show all registered HotKey help strings on bottom Rows.
 | 
						|
 | 
						|
  @param FormData          The curent input form data info.
 | 
						|
  @param SetState          Set HotKey or Clear HotKey
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
PrintHotKeyHelpString (
 | 
						|
  IN FORM_DISPLAY_ENGINE_FORM  *FormData,
 | 
						|
  IN BOOLEAN                   SetState
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                  CurrentCol;
 | 
						|
  UINTN                  CurrentRow;
 | 
						|
  UINTN                  BottomRowOfHotKeyHelp;
 | 
						|
  UINTN                  ColumnIndexWidth;
 | 
						|
  UINTN                  ColumnWidth;
 | 
						|
  UINTN                  ColumnIndex;
 | 
						|
  UINTN                  Index;
 | 
						|
  EFI_SCREEN_DESCRIPTOR  LocalScreen;
 | 
						|
  LIST_ENTRY             *Link;
 | 
						|
  BROWSER_HOT_KEY        *HotKey;
 | 
						|
  CHAR16                 BakChar;
 | 
						|
  CHAR16                 *ColumnStr;
 | 
						|
 | 
						|
  CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | 
						|
  ColumnWidth           = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
 | 
						|
  BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;
 | 
						|
  ColumnStr             = gLibEmptyString;
 | 
						|
 | 
						|
  //
 | 
						|
  // Calculate total number of Register HotKeys.
 | 
						|
  //
 | 
						|
  Index = 0;
 | 
						|
  Link  = GetFirstNode (&FormData->HotKeyListHead);
 | 
						|
  while (!IsNull (&FormData->HotKeyListHead, Link)) {
 | 
						|
    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
 | 
						|
    //
 | 
						|
    // Calculate help information Column and Row.
 | 
						|
    //
 | 
						|
    ColumnIndex = Index % 3;
 | 
						|
    if (ColumnIndex == 0) {
 | 
						|
      CurrentCol       = LocalScreen.LeftColumn + 2 * ColumnWidth;
 | 
						|
      ColumnIndexWidth = ColumnWidth - 1;
 | 
						|
    } else if (ColumnIndex == 1) {
 | 
						|
      CurrentCol       = LocalScreen.LeftColumn + ColumnWidth;
 | 
						|
      ColumnIndexWidth = ColumnWidth;
 | 
						|
    } else {
 | 
						|
      CurrentCol       = LocalScreen.LeftColumn + 2;
 | 
						|
      ColumnIndexWidth = ColumnWidth - 2;
 | 
						|
    }
 | 
						|
 | 
						|
    CurrentRow = BottomRowOfHotKeyHelp - Index / 3;
 | 
						|
 | 
						|
    //
 | 
						|
    // Help string can't exceed ColumnWidth. One Row will show three Help information.
 | 
						|
    //
 | 
						|
    BakChar = L'\0';
 | 
						|
    if (StrLen (HotKey->HelpString) > ColumnIndexWidth) {
 | 
						|
      BakChar                              = HotKey->HelpString[ColumnIndexWidth];
 | 
						|
      HotKey->HelpString[ColumnIndexWidth] = L'\0';
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Print HotKey help string on bottom Row.
 | 
						|
    //
 | 
						|
    if (SetState) {
 | 
						|
      ColumnStr = HotKey->HelpString;
 | 
						|
    }
 | 
						|
 | 
						|
    PrintStringAtWithWidth (CurrentCol, CurrentRow, ColumnStr, ColumnIndexWidth);
 | 
						|
 | 
						|
    if (BakChar != L'\0') {
 | 
						|
      HotKey->HelpString[ColumnIndexWidth] = BakChar;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Get Next Hot Key.
 | 
						|
    //
 | 
						|
    Link = GetNextNode (&FormData->HotKeyListHead, Link);
 | 
						|
    Index++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (SetState) {
 | 
						|
    //
 | 
						|
    // Clear KeyHelp
 | 
						|
    //
 | 
						|
    CurrentRow  = BottomRowOfHotKeyHelp - Index / 3;
 | 
						|
    ColumnIndex = Index % 3;
 | 
						|
    if (ColumnIndex == 0) {
 | 
						|
      CurrentCol       = LocalScreen.LeftColumn + 2 * ColumnWidth;
 | 
						|
      ColumnIndexWidth = ColumnWidth - 1;
 | 
						|
      ColumnIndex++;
 | 
						|
      PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth);
 | 
						|
    }
 | 
						|
 | 
						|
    if (ColumnIndex == 1) {
 | 
						|
      CurrentCol       = LocalScreen.LeftColumn + ColumnWidth;
 | 
						|
      ColumnIndexWidth = ColumnWidth;
 | 
						|
      PrintStringAtWithWidth (CurrentCol, CurrentRow, gLibEmptyString, ColumnIndexWidth);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get step info from numeric opcode.
 | 
						|
 | 
						|
  @param[in] OpCode     The input numeric op code.
 | 
						|
 | 
						|
  @return step info for this opcode.
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
LibGetFieldFromNum (
 | 
						|
  IN  EFI_IFR_OP_HEADER  *OpCode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_IFR_NUMERIC  *NumericOp;
 | 
						|
  UINT64           Step;
 | 
						|
 | 
						|
  NumericOp = (EFI_IFR_NUMERIC *)OpCode;
 | 
						|
 | 
						|
  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
 | 
						|
    case EFI_IFR_NUMERIC_SIZE_1:
 | 
						|
      Step = NumericOp->data.u8.Step;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_NUMERIC_SIZE_2:
 | 
						|
      Step = NumericOp->data.u16.Step;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_NUMERIC_SIZE_4:
 | 
						|
      Step = NumericOp->data.u32.Step;
 | 
						|
      break;
 | 
						|
 | 
						|
    case EFI_IFR_NUMERIC_SIZE_8:
 | 
						|
      Step = NumericOp->data.u64.Step;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      Step = 0;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return Step;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize the HII String Token to the correct values.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
InitializeLibStrings (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  mLibUnknownString = L"!";
 | 
						|
 | 
						|
  gEnterString       = LibGetToken (STRING_TOKEN (ENTER_STRING), mCDLStringPackHandle);
 | 
						|
  gEnterCommitString = LibGetToken (STRING_TOKEN (ENTER_COMMIT_STRING), mCDLStringPackHandle);
 | 
						|
  gEnterEscapeString = LibGetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), mCDLStringPackHandle);
 | 
						|
  gEscapeString      = LibGetToken (STRING_TOKEN (ESCAPE_STRING), mCDLStringPackHandle);
 | 
						|
  gMoveHighlight     = LibGetToken (STRING_TOKEN (MOVE_HIGHLIGHT), mCDLStringPackHandle);
 | 
						|
  gDecNumericInput   = LibGetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), mCDLStringPackHandle);
 | 
						|
  gHexNumericInput   = LibGetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), mCDLStringPackHandle);
 | 
						|
  gToggleCheckBox    = LibGetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), mCDLStringPackHandle);
 | 
						|
 | 
						|
  gAreYouSure   = LibGetToken (STRING_TOKEN (ARE_YOU_SURE), mCDLStringPackHandle);
 | 
						|
  gYesResponse  = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_YES), mCDLStringPackHandle);
 | 
						|
  gNoResponse   = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_NO), mCDLStringPackHandle);
 | 
						|
  gPlusString   = LibGetToken (STRING_TOKEN (PLUS_STRING), mCDLStringPackHandle);
 | 
						|
  gMinusString  = LibGetToken (STRING_TOKEN (MINUS_STRING), mCDLStringPackHandle);
 | 
						|
  gAdjustNumber = LibGetToken (STRING_TOKEN (ADJUST_NUMBER), mCDLStringPackHandle);
 | 
						|
  gSaveChanges  = LibGetToken (STRING_TOKEN (SAVE_CHANGES), mCDLStringPackHandle);
 | 
						|
 | 
						|
  gLibEmptyString = LibGetToken (STRING_TOKEN (EMPTY_STRING), mCDLStringPackHandle);
 | 
						|
 | 
						|
  gNvUpdateMessage   = LibGetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), mCDLStringPackHandle);
 | 
						|
  gInputErrorMessage = LibGetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), mCDLStringPackHandle);
 | 
						|
 | 
						|
  //
 | 
						|
  // SpaceBuffer;
 | 
						|
  //
 | 
						|
  mSpaceBuffer = AllocatePool ((SPACE_BUFFER_SIZE + 1) * sizeof (CHAR16));
 | 
						|
  ASSERT (mSpaceBuffer != NULL);
 | 
						|
  LibSetUnicodeMem (mSpaceBuffer, SPACE_BUFFER_SIZE, L' ');
 | 
						|
  mSpaceBuffer[SPACE_BUFFER_SIZE] = L'\0';
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Free the HII String.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
FreeLibStrings (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  FreePool (gEnterString);
 | 
						|
  FreePool (gEnterCommitString);
 | 
						|
  FreePool (gEnterEscapeString);
 | 
						|
  FreePool (gEscapeString);
 | 
						|
  FreePool (gMoveHighlight);
 | 
						|
  FreePool (gDecNumericInput);
 | 
						|
  FreePool (gHexNumericInput);
 | 
						|
  FreePool (gToggleCheckBox);
 | 
						|
 | 
						|
  FreePool (gAreYouSure);
 | 
						|
  FreePool (gYesResponse);
 | 
						|
  FreePool (gNoResponse);
 | 
						|
  FreePool (gPlusString);
 | 
						|
  FreePool (gMinusString);
 | 
						|
  FreePool (gAdjustNumber);
 | 
						|
  FreePool (gSaveChanges);
 | 
						|
 | 
						|
  FreePool (gLibEmptyString);
 | 
						|
 | 
						|
  FreePool (gNvUpdateMessage);
 | 
						|
  FreePool (gInputErrorMessage);
 | 
						|
 | 
						|
  FreePool (mSpaceBuffer);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Wait for a key to be pressed by user.
 | 
						|
 | 
						|
  @param Key         The key which is pressed by user.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS The function always completed successfully.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
WaitForKeyStroke (
 | 
						|
  OUT  EFI_INPUT_KEY  *Key
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINTN       Index;
 | 
						|
 | 
						|
  while (TRUE) {
 | 
						|
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Status != EFI_NOT_READY) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set Buffer to Value for Size bytes.
 | 
						|
 | 
						|
  @param  Buffer                 Memory to set.
 | 
						|
  @param  Size                   Number of bytes to set
 | 
						|
  @param  Value                  Value of the set operation.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
LibSetUnicodeMem (
 | 
						|
  IN VOID    *Buffer,
 | 
						|
  IN UINTN   Size,
 | 
						|
  IN CHAR16  Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *Ptr;
 | 
						|
 | 
						|
  Ptr = Buffer;
 | 
						|
  while ((Size--)  != 0) {
 | 
						|
    *(Ptr++) = Value;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
 | 
						|
  protocol instance.
 | 
						|
 | 
						|
  @param Width           Width of string to be print.
 | 
						|
  @param Column          The position of the output string.
 | 
						|
  @param Row             The position of the output string.
 | 
						|
  @param Out             The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.
 | 
						|
  @param Fmt             The format string.
 | 
						|
  @param Args            The additional argument for the variables in the format string.
 | 
						|
 | 
						|
  @return Number of Unicode character printed.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
PrintInternal (
 | 
						|
  IN UINTN                            Width,
 | 
						|
  IN UINTN                            Column,
 | 
						|
  IN UINTN                            Row,
 | 
						|
  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Out,
 | 
						|
  IN CHAR16                           *Fmt,
 | 
						|
  IN VA_LIST                          Args
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  *Buffer;
 | 
						|
  CHAR16  *BackupBuffer;
 | 
						|
  UINTN   Index;
 | 
						|
  UINTN   PreviousIndex;
 | 
						|
  UINTN   Count;
 | 
						|
  UINTN   TotalCount;
 | 
						|
  UINTN   PrintWidth;
 | 
						|
  UINTN   CharWidth;
 | 
						|
 | 
						|
  //
 | 
						|
  // For now, allocate an arbitrarily long buffer
 | 
						|
  //
 | 
						|
  Buffer       = AllocateZeroPool (0x10000);
 | 
						|
  BackupBuffer = AllocateZeroPool (0x10000);
 | 
						|
  ASSERT (Buffer);
 | 
						|
  ASSERT (BackupBuffer);
 | 
						|
 | 
						|
  if (Column != (UINTN)-1) {
 | 
						|
    Out->SetCursorPosition (Out, Column, Row);
 | 
						|
  }
 | 
						|
 | 
						|
  UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);
 | 
						|
 | 
						|
  Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
 | 
						|
 | 
						|
  Out->SetAttribute (Out, Out->Mode->Attribute);
 | 
						|
 | 
						|
  Index         = 0;
 | 
						|
  PreviousIndex = 0;
 | 
						|
  Count         = 0;
 | 
						|
  TotalCount    = 0;
 | 
						|
  PrintWidth    = 0;
 | 
						|
  CharWidth     = 1;
 | 
						|
 | 
						|
  do {
 | 
						|
    for ( ; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {
 | 
						|
      BackupBuffer[Index] = Buffer[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    if (Buffer[Index] == 0) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Print this out, we are about to switch widths
 | 
						|
    //
 | 
						|
    Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
 | 
						|
    Count       = StrLen (&BackupBuffer[PreviousIndex]);
 | 
						|
    PrintWidth += Count * CharWidth;
 | 
						|
    TotalCount += Count;
 | 
						|
 | 
						|
    //
 | 
						|
    // Preserve the current index + 1, since this is where we will start printing from next
 | 
						|
    //
 | 
						|
    PreviousIndex = Index + 1;
 | 
						|
 | 
						|
    //
 | 
						|
    // We are at a narrow or wide character directive.  Set attributes and strip it and print it
 | 
						|
    //
 | 
						|
    if (Buffer[Index] == NARROW_CHAR) {
 | 
						|
      //
 | 
						|
      // Preserve bits 0 - 6 and zero out the rest
 | 
						|
      //
 | 
						|
      Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
 | 
						|
      Out->SetAttribute (Out, Out->Mode->Attribute);
 | 
						|
      CharWidth = 1;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Must be wide, set bit 7 ON
 | 
						|
      //
 | 
						|
      Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;
 | 
						|
      Out->SetAttribute (Out, Out->Mode->Attribute);
 | 
						|
      CharWidth = 2;
 | 
						|
    }
 | 
						|
 | 
						|
    Index++;
 | 
						|
  } while (Buffer[Index] != 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // We hit the end of the string - print it
 | 
						|
  //
 | 
						|
  Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
 | 
						|
  Count       = StrLen (&BackupBuffer[PreviousIndex]);
 | 
						|
  PrintWidth += Count * CharWidth;
 | 
						|
  TotalCount += Count;
 | 
						|
  if (PrintWidth < Width) {
 | 
						|
    Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
 | 
						|
    Out->SetAttribute (Out, Out->Mode->Attribute);
 | 
						|
    Out->OutputString (Out, &mSpaceBuffer[SPACE_BUFFER_SIZE - Width + PrintWidth]);
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (Buffer);
 | 
						|
  FreePool (BackupBuffer);
 | 
						|
  return TotalCount;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Prints a formatted unicode string to the default console, at
 | 
						|
  the supplied cursor position.
 | 
						|
 | 
						|
  @param  Width      Width of String to be printed.
 | 
						|
  @param  Column     The cursor position to print the string at.
 | 
						|
  @param  Row        The cursor position to print the string at.
 | 
						|
  @param  Fmt        Format string.
 | 
						|
  @param  ...        Variable argument list for format string.
 | 
						|
 | 
						|
  @return Length of string printed to the console
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
PrintAt (
 | 
						|
  IN UINTN   Width,
 | 
						|
  IN UINTN   Column,
 | 
						|
  IN UINTN   Row,
 | 
						|
  IN CHAR16  *Fmt,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  VA_LIST  Args;
 | 
						|
  UINTN    LengthOfPrinted;
 | 
						|
 | 
						|
  VA_START (Args, Fmt);
 | 
						|
  LengthOfPrinted = PrintInternal (Width, Column, Row, gST->ConOut, Fmt, Args);
 | 
						|
  VA_END (Args);
 | 
						|
  return LengthOfPrinted;
 | 
						|
}
 |