mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-03 21:17:23 +01:00 
			
		
		
		
	https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
		
			
				
	
	
		
			2470 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2470 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Defines HBufferImage - the view of the file that is visible at any point,
 | 
						|
  as well as the event handlers for editing the file
 | 
						|
 | 
						|
  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "HexEditor.h"
 | 
						|
 | 
						|
extern EFI_HANDLE                 HImageHandleBackup;
 | 
						|
 | 
						|
extern HEFI_EDITOR_FILE_IMAGE     HFileImage;
 | 
						|
extern HEFI_EDITOR_DISK_IMAGE     HDiskImage;
 | 
						|
extern HEFI_EDITOR_MEM_IMAGE      HMemImage;
 | 
						|
 | 
						|
extern HEFI_EDITOR_FILE_IMAGE     HFileImageBackupVar;
 | 
						|
extern HEFI_EDITOR_DISK_IMAGE     HDiskImageBackupVar;
 | 
						|
extern HEFI_EDITOR_MEM_IMAGE      HMemImageBackupVar;
 | 
						|
 | 
						|
extern BOOLEAN                    HEditorMouseAction;
 | 
						|
 | 
						|
extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditor;
 | 
						|
extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditorBackupVar;
 | 
						|
 | 
						|
HEFI_EDITOR_BUFFER_IMAGE          HBufferImage;
 | 
						|
HEFI_EDITOR_BUFFER_IMAGE          HBufferImageBackupVar;
 | 
						|
 | 
						|
//
 | 
						|
// for basic initialization of HBufferImage
 | 
						|
//
 | 
						|
HEFI_EDITOR_BUFFER_IMAGE          HBufferImageConst = {
 | 
						|
  NULL,
 | 
						|
  NULL,
 | 
						|
  0,
 | 
						|
  NULL,
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    0
 | 
						|
  },
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    0
 | 
						|
  },
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    0
 | 
						|
  },
 | 
						|
  0,
 | 
						|
  TRUE,
 | 
						|
  FALSE,
 | 
						|
  FileTypeNone,
 | 
						|
  NULL,
 | 
						|
  NULL,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// the whole edit area needs to be refreshed
 | 
						|
//
 | 
						|
BOOLEAN                           HBufferImageNeedRefresh;
 | 
						|
 | 
						|
//
 | 
						|
// only the current line in edit area needs to be refresh
 | 
						|
//
 | 
						|
BOOLEAN                           HBufferImageOnlyLineNeedRefresh;
 | 
						|
 | 
						|
BOOLEAN                           HBufferImageMouseNeedRefresh;
 | 
						|
 | 
						|
/**
 | 
						|
  Initialization function for HBufferImage
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR    A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageInit (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // basically initialize the HBufferImage
 | 
						|
  //
 | 
						|
  CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage));
 | 
						|
 | 
						|
  //
 | 
						|
  // INIT listhead
 | 
						|
  //
 | 
						|
  HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY));
 | 
						|
  if (HBufferImage.ListHead == NULL) {
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  InitializeListHead (HBufferImage.ListHead);
 | 
						|
 | 
						|
  HBufferImage.DisplayPosition.Row    = 2;
 | 
						|
  HBufferImage.DisplayPosition.Column = 10;
 | 
						|
  HBufferImage.MousePosition.Row      = 2;
 | 
						|
  HBufferImage.MousePosition.Column   = 10;
 | 
						|
 | 
						|
  HBufferImage.FileImage              = &HFileImage;
 | 
						|
  HBufferImage.DiskImage              = &HDiskImage;
 | 
						|
  HBufferImage.MemImage               = &HMemImage;
 | 
						|
 | 
						|
  HBufferImageNeedRefresh             = FALSE;
 | 
						|
  HBufferImageOnlyLineNeedRefresh     = FALSE;
 | 
						|
  HBufferImageMouseNeedRefresh        = FALSE;
 | 
						|
 | 
						|
  HBufferImageBackupVar.FileImage     = &HFileImageBackupVar;
 | 
						|
  HBufferImageBackupVar.DiskImage     = &HDiskImageBackupVar;
 | 
						|
  HBufferImageBackupVar.MemImage      = &HMemImageBackupVar;
 | 
						|
 | 
						|
  Status = HFileImageInit ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = HDiskImageInit ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = HMemImageInit ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Backup function for HBufferImage. Only a few fields need to be backup.
 | 
						|
  This is for making the file buffer refresh as few as possible.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageBackup (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HBufferImageBackupVar.MousePosition   = HBufferImage.MousePosition;
 | 
						|
 | 
						|
  HBufferImageBackupVar.BufferPosition  = HBufferImage.BufferPosition;
 | 
						|
 | 
						|
  HBufferImageBackupVar.Modified        = HBufferImage.Modified;
 | 
						|
 | 
						|
  HBufferImageBackupVar.BufferType      = HBufferImage.BufferType;
 | 
						|
  HBufferImageBackupVar.LowVisibleRow   = HBufferImage.LowVisibleRow;
 | 
						|
  HBufferImageBackupVar.HighBits        = HBufferImage.HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // three kinds of buffer supported
 | 
						|
  //   file buffer
 | 
						|
  //   disk buffer
 | 
						|
  //   memory buffer
 | 
						|
  //
 | 
						|
  switch (HBufferImage.BufferType) {
 | 
						|
  case FileTypeFileBuffer:
 | 
						|
    HFileImageBackup ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FileTypeDiskBuffer:
 | 
						|
    HDiskImageBackup ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FileTypeMemBuffer:
 | 
						|
    HMemImageBackup ();
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Free all the lines in HBufferImage.
 | 
						|
    Fields affected:
 | 
						|
    Lines
 | 
						|
    CurrentLine
 | 
						|
    NumLines
 | 
						|
    ListHead
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageFreeLines (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HFreeLines (HBufferImage.ListHead, HBufferImage.Lines);
 | 
						|
 | 
						|
  HBufferImage.Lines        = NULL;
 | 
						|
  HBufferImage.CurrentLine  = NULL;
 | 
						|
  HBufferImage.NumLines     = 0;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Cleanup function for HBufferImage
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageCleanup (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // free all the lines
 | 
						|
  //
 | 
						|
  Status = HBufferImageFreeLines ();
 | 
						|
 | 
						|
  SHELL_FREE_NON_NULL (HBufferImage.ListHead);
 | 
						|
  HBufferImage.ListHead = NULL;
 | 
						|
 | 
						|
  HFileImageCleanup ();
 | 
						|
  HDiskImageCleanup ();
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Print Line on Row
 | 
						|
 | 
						|
  @param[in] Line     The lline to print.
 | 
						|
  @param[in] Row      The row on screen ( begin from 1 ).
 | 
						|
  @param[in] FRow     The FRow.
 | 
						|
  @param[in] Orig     The original color.
 | 
						|
  @param[in] New      The color to print with.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImagePrintLine (
 | 
						|
  IN HEFI_EDITOR_LINE           *Line,
 | 
						|
  IN UINTN                      Row,
 | 
						|
  IN UINTN                      FRow,
 | 
						|
  IN HEFI_EDITOR_COLOR_UNION    Orig,
 | 
						|
  IN HEFI_EDITOR_COLOR_UNION    New
 | 
						|
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  UINTN   Index;
 | 
						|
  UINTN   Pos;
 | 
						|
  BOOLEAN Selected;
 | 
						|
  BOOLEAN BeNewColor;
 | 
						|
  UINTN   RowStart;
 | 
						|
  UINTN   RowEnd;
 | 
						|
  UINTN   ColStart;
 | 
						|
  UINTN   ColEnd;
 | 
						|
 | 
						|
  //
 | 
						|
  // variable initialization
 | 
						|
  //
 | 
						|
  ColStart  = 0;
 | 
						|
  ColEnd    = 0;
 | 
						|
  Selected  = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // print the selected area in opposite color
 | 
						|
  //
 | 
						|
  if (HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
 | 
						|
    RowStart  = (HMainEditor.SelectStart - 1) / 0x10 + 1;
 | 
						|
    RowEnd    = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
 | 
						|
 | 
						|
    ColStart  = (HMainEditor.SelectStart - 1) % 0x10 + 1;
 | 
						|
    ColEnd    = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
 | 
						|
 | 
						|
    if (FRow >= RowStart && FRow <= RowEnd) {
 | 
						|
      Selected = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
    if (FRow > RowStart) {
 | 
						|
      ColStart = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (FRow < RowEnd) {
 | 
						|
      ColEnd = 0x10;
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  if (!HEditorMouseAction) {
 | 
						|
    ShellPrintEx (
 | 
						|
      0,
 | 
						|
      (INT32)Row - 1,
 | 
						|
      L"%8X ",
 | 
						|
      ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10
 | 
						|
      );
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) {
 | 
						|
 | 
						|
    BeNewColor = FALSE;
 | 
						|
 | 
						|
    if (Selected) {
 | 
						|
      if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
 | 
						|
        BeNewColor = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (BeNewColor) {
 | 
						|
      gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
 | 
						|
    } else {
 | 
						|
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
 | 
						|
    }
 | 
						|
 | 
						|
    Pos = 10 + (Index * 3);
 | 
						|
    if (Line->Buffer[Index] < 0x10) {
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
 | 
						|
      Pos++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Index < 0x07) {
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
 | 
						|
    } else {
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x  ", Line->Buffer[Index]);
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
 | 
						|
  while (Index < 0x08) {
 | 
						|
    Pos = 10 + (Index * 3);
 | 
						|
    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"    ");
 | 
						|
    Index++;
 | 
						|
  }
 | 
						|
 | 
						|
  while (Index < 0x10 && Index < Line->Size) {
 | 
						|
 | 
						|
    BeNewColor = FALSE;
 | 
						|
 | 
						|
    if (Selected) {
 | 
						|
      if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
 | 
						|
        BeNewColor = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (BeNewColor) {
 | 
						|
      gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
 | 
						|
    } else {
 | 
						|
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
 | 
						|
    }
 | 
						|
 | 
						|
    Pos = 10 + (Index * 3) + 1;
 | 
						|
    if (Line->Buffer[Index] < 0x10) {
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
 | 
						|
      Pos++;
 | 
						|
    }
 | 
						|
 | 
						|
    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
 | 
						|
    Index++;
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
 | 
						|
  while (Index < 0x10) {
 | 
						|
    Pos = 10 + (Index * 3) + 1;
 | 
						|
    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"   ");
 | 
						|
    Index++;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // restore the original color
 | 
						|
  //
 | 
						|
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
 | 
						|
 | 
						|
  //
 | 
						|
  // PRINT the buffer content
 | 
						|
  //
 | 
						|
  if (!HEditorMouseAction) {
 | 
						|
    for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) {
 | 
						|
      Pos = ASCII_POSITION + Index;
 | 
						|
 | 
						|
      //
 | 
						|
      // learned from shelle.h -- IsValidChar
 | 
						|
      //
 | 
						|
      if (Line->Buffer[Index] >= L' ') {
 | 
						|
        ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16) Line->Buffer[Index]);
 | 
						|
      } else {
 | 
						|
        ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.');
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    while (Index < 0x10) {
 | 
						|
      Pos = ASCII_POSITION + Index;
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
 | 
						|
      Index++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // restore the abundant blank in hex edit area to original color
 | 
						|
  //
 | 
						|
  if (Selected) {
 | 
						|
    if (ColEnd <= 7) {
 | 
						|
      Pos = 10 + (ColEnd - 1) * 3 + 2;
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
 | 
						|
    } else if (ColEnd == 8) {
 | 
						|
      Pos = 10 + (ColEnd - 1) * 3 + 2;
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"  ");
 | 
						|
    } else {
 | 
						|
      Pos = 10 + (ColEnd - 1) * 3 + 3;
 | 
						|
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Function to decide if a column number is stored in the high bits.
 | 
						|
 | 
						|
  @param[in] Column     The column to examine.
 | 
						|
  @param[out] FCol      The actual column number.
 | 
						|
 | 
						|
  @retval TRUE      The actual column was in high bits and is now in FCol.
 | 
						|
  @retval FALSE     There was not a column number in the high bits.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
HBufferImageIsAtHighBits (
 | 
						|
  IN  UINTN Column,
 | 
						|
  OUT UINTN *FCol
 | 
						|
  )
 | 
						|
{
 | 
						|
  Column -= 10;
 | 
						|
 | 
						|
  //
 | 
						|
  // NOW AFTER THE SUB, Column start from 0
 | 
						|
  // 23 AND 24 ARE BOTH BLANK
 | 
						|
  //
 | 
						|
  if (Column == 24) {
 | 
						|
    *FCol = 0;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Column > 24) {
 | 
						|
    Column--;
 | 
						|
  }
 | 
						|
 | 
						|
  *FCol = (Column / 3) + 1;
 | 
						|
 | 
						|
  if (Column % 3 == 0) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Column % 3 == 2)) {
 | 
						|
    *FCol = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Decide if a point is in the already selected area.
 | 
						|
 | 
						|
  @param[in] MouseRow     The row of the point to test.
 | 
						|
  @param[in] MouseCol     The col of the point to test.
 | 
						|
 | 
						|
  @retval TRUE      The point is in the selected area.
 | 
						|
  @retval FALSE     The point is not in the selected area.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
HBufferImageIsInSelectedArea (
 | 
						|
  IN UINTN MouseRow,
 | 
						|
  IN UINTN MouseCol
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN FRow;
 | 
						|
  UINTN RowStart;
 | 
						|
  UINTN RowEnd;
 | 
						|
  UINTN ColStart;
 | 
						|
  UINTN ColEnd;
 | 
						|
  UINTN MouseColStart;
 | 
						|
  UINTN MouseColEnd;
 | 
						|
 | 
						|
  //
 | 
						|
  // judge mouse position whether is in selected area
 | 
						|
  //
 | 
						|
  //
 | 
						|
  // not select
 | 
						|
  //
 | 
						|
  if (HMainEditor.SelectStart == 0 || HMainEditor.SelectEnd == 0) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // calculate the select area
 | 
						|
  //
 | 
						|
  RowStart  = (HMainEditor.SelectStart - 1) / 0x10 + 1;
 | 
						|
  RowEnd    = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
 | 
						|
 | 
						|
  ColStart  = (HMainEditor.SelectStart - 1) % 0x10 + 1;
 | 
						|
  ColEnd    = (HMainEditor.SelectEnd - 1) % 0x10 + 1;
 | 
						|
 | 
						|
  FRow      = HBufferImage.LowVisibleRow + MouseRow - 2;
 | 
						|
  if (FRow < RowStart || FRow > RowEnd) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FRow > RowStart) {
 | 
						|
    ColStart = 1;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FRow < RowEnd) {
 | 
						|
    ColEnd = 0x10;
 | 
						|
  }
 | 
						|
 | 
						|
  MouseColStart = 10 + (ColStart - 1) * 3;
 | 
						|
  if (ColStart > 8) {
 | 
						|
    MouseColStart++;
 | 
						|
  }
 | 
						|
 | 
						|
  MouseColEnd = 10 + (ColEnd - 1) * 3 + 1;
 | 
						|
  if (ColEnd > 8) {
 | 
						|
    MouseColEnd++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MouseCol < MouseColStart || MouseCol > MouseColEnd) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set mouse position according to HBufferImage.MousePosition.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageRestoreMousePosition (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_COLOR_UNION Orig;
 | 
						|
  HEFI_EDITOR_COLOR_UNION New;
 | 
						|
  UINTN                   FRow;
 | 
						|
  UINTN                   FColumn;
 | 
						|
  BOOLEAN                 HasCharacter;
 | 
						|
  HEFI_EDITOR_LINE        *CurrentLine;
 | 
						|
  HEFI_EDITOR_LINE        *Line;
 | 
						|
  UINT8                   Value;
 | 
						|
  BOOLEAN                 HighBits;
 | 
						|
 | 
						|
  Line = NULL;
 | 
						|
  if (HMainEditor.MouseSupported) {
 | 
						|
 | 
						|
    if (HBufferImageMouseNeedRefresh) {
 | 
						|
 | 
						|
      HBufferImageMouseNeedRefresh = FALSE;
 | 
						|
 | 
						|
      //
 | 
						|
      // if mouse position not moved and only mouse action
 | 
						|
      // so do not need to refresh mouse position
 | 
						|
      //
 | 
						|
      if ((
 | 
						|
            HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row &&
 | 
						|
          HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column
 | 
						|
        ) &&
 | 
						|
          HEditorMouseAction
 | 
						|
          ) {
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // backup the old screen attributes
 | 
						|
      //
 | 
						|
      Orig                  = HMainEditor.ColorAttributes;
 | 
						|
      New.Data              = 0;
 | 
						|
      New.Colors.Foreground = Orig.Colors.Background & 0xF;
 | 
						|
      New.Colors.Background = Orig.Colors.Foreground & 0x7;
 | 
						|
 | 
						|
      //
 | 
						|
      // if in selected area,
 | 
						|
      // so do not need to refresh mouse
 | 
						|
      //
 | 
						|
      if (!HBufferImageIsInSelectedArea (
 | 
						|
            HBufferImageBackupVar.MousePosition.Row,
 | 
						|
            HBufferImageBackupVar.MousePosition.Column
 | 
						|
            )) {
 | 
						|
        gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
 | 
						|
      } else {
 | 
						|
        gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // clear the old mouse position
 | 
						|
      //
 | 
						|
      FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2;
 | 
						|
 | 
						|
      HighBits = HBufferImageIsAtHighBits (
 | 
						|
                  HBufferImageBackupVar.MousePosition.Column,
 | 
						|
                  &FColumn
 | 
						|
                  );
 | 
						|
 | 
						|
      HasCharacter = TRUE;
 | 
						|
      if (FRow > HBufferImage.NumLines || FColumn == 0) {
 | 
						|
        HasCharacter = FALSE;
 | 
						|
      } else {
 | 
						|
        CurrentLine = HBufferImage.CurrentLine;
 | 
						|
        Line        = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
 | 
						|
 | 
						|
        if (Line == NULL || FColumn > Line->Size) {
 | 
						|
          HasCharacter = FALSE;
 | 
						|
        }
 | 
						|
 | 
						|
        HBufferImage.CurrentLine = CurrentLine;
 | 
						|
      }
 | 
						|
 | 
						|
      ShellPrintEx (
 | 
						|
        (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
 | 
						|
        (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
 | 
						|
        L" "
 | 
						|
        );
 | 
						|
 | 
						|
      if (HasCharacter) {
 | 
						|
        if (HighBits) {
 | 
						|
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
 | 
						|
          Value = (UINT8) (Value >> 4);
 | 
						|
        } else {
 | 
						|
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
 | 
						|
        }
 | 
						|
 | 
						|
        ShellPrintEx (
 | 
						|
          (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
 | 
						|
          (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
 | 
						|
          L"%x",
 | 
						|
          Value
 | 
						|
          );
 | 
						|
      }
 | 
						|
 | 
						|
      if (!HBufferImageIsInSelectedArea (
 | 
						|
            HBufferImage.MousePosition.Row,
 | 
						|
            HBufferImage.MousePosition.Column
 | 
						|
            )) {
 | 
						|
        gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
 | 
						|
      } else {
 | 
						|
        gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // clear the old mouse position
 | 
						|
      //
 | 
						|
      FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2;
 | 
						|
 | 
						|
      HighBits = HBufferImageIsAtHighBits (
 | 
						|
                  HBufferImage.MousePosition.Column,
 | 
						|
                  &FColumn
 | 
						|
                  );
 | 
						|
 | 
						|
      HasCharacter = TRUE;
 | 
						|
      if (FRow > HBufferImage.NumLines || FColumn == 0) {
 | 
						|
        HasCharacter = FALSE;
 | 
						|
      } else {
 | 
						|
        CurrentLine = HBufferImage.CurrentLine;
 | 
						|
        Line        = HMoveLine (FRow - HBufferImage.BufferPosition.Row);
 | 
						|
 | 
						|
        if (Line == NULL || FColumn > Line->Size) {
 | 
						|
          HasCharacter = FALSE;
 | 
						|
        }
 | 
						|
 | 
						|
        HBufferImage.CurrentLine = CurrentLine;
 | 
						|
      }
 | 
						|
 | 
						|
      ShellPrintEx (
 | 
						|
        (INT32)HBufferImage.MousePosition.Column - 1,
 | 
						|
        (INT32)HBufferImage.MousePosition.Row - 1,
 | 
						|
        L" "
 | 
						|
        );
 | 
						|
 | 
						|
      if (HasCharacter) {
 | 
						|
        if (HighBits) {
 | 
						|
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
 | 
						|
          Value = (UINT8) (Value >> 4);
 | 
						|
        } else {
 | 
						|
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
 | 
						|
        }
 | 
						|
 | 
						|
        ShellPrintEx (
 | 
						|
          (INT32)HBufferImage.MousePosition.Column - 1,
 | 
						|
          (INT32)HBufferImage.MousePosition.Row - 1,
 | 
						|
          L"%x",
 | 
						|
          Value
 | 
						|
          );
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // end of HasCharacter
 | 
						|
      //
 | 
						|
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of MouseNeedRefresh
 | 
						|
    //
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // end of MouseSupported
 | 
						|
  //
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set cursor position according to HBufferImage.DisplayPosition.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageRestorePosition (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // set cursor position
 | 
						|
  //
 | 
						|
  gST->ConOut->SetCursorPosition (
 | 
						|
        gST->ConOut,
 | 
						|
        HBufferImage.DisplayPosition.Column - 1,
 | 
						|
        HBufferImage.DisplayPosition.Row - 1
 | 
						|
        );
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Refresh function for HBufferImage.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS     The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR  A Load error occured.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageRefresh (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY          *Link;
 | 
						|
  HEFI_EDITOR_LINE        *Line;
 | 
						|
  UINTN                   Row;
 | 
						|
  HEFI_EDITOR_COLOR_UNION Orig;
 | 
						|
  HEFI_EDITOR_COLOR_UNION New;
 | 
						|
 | 
						|
  UINTN                   StartRow;
 | 
						|
  UINTN                   EndRow;
 | 
						|
  UINTN                   FStartRow;
 | 
						|
  UINTN                   Tmp;
 | 
						|
 | 
						|
  Orig                  = HMainEditor.ColorAttributes;
 | 
						|
  New.Data              = 0;
 | 
						|
  New.Colors.Foreground = Orig.Colors.Background;
 | 
						|
  New.Colors.Background = Orig.Colors.Foreground;
 | 
						|
 | 
						|
  //
 | 
						|
  // if it's the first time after editor launch, so should refresh
 | 
						|
  //
 | 
						|
  if (HEditorFirst == FALSE) {
 | 
						|
    //
 | 
						|
    // no definite required refresh
 | 
						|
    // and file position displayed on screen has not been changed
 | 
						|
    //
 | 
						|
    if (!HBufferImageNeedRefresh &&
 | 
						|
        !HBufferImageOnlyLineNeedRefresh &&
 | 
						|
        HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow
 | 
						|
        ) {
 | 
						|
      HBufferImageRestoreMousePosition ();
 | 
						|
      HBufferImageRestorePosition ();
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
 | 
						|
 | 
						|
  //
 | 
						|
  // only need to refresh current line
 | 
						|
  //
 | 
						|
  if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) {
 | 
						|
 | 
						|
    HBufferImagePrintLine (
 | 
						|
      HBufferImage.CurrentLine,
 | 
						|
      HBufferImage.DisplayPosition.Row,
 | 
						|
      HBufferImage.BufferPosition.Row,
 | 
						|
      Orig,
 | 
						|
      New
 | 
						|
      );
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // the whole edit area need refresh
 | 
						|
    //
 | 
						|
    if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
 | 
						|
      if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {
 | 
						|
        if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) {
 | 
						|
          StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;
 | 
						|
        } else {
 | 
						|
          StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
 | 
						|
      }
 | 
						|
 | 
						|
      if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {
 | 
						|
        EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;
 | 
						|
      } else {
 | 
						|
        EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // swap
 | 
						|
      //
 | 
						|
      if (StartRow > EndRow) {
 | 
						|
        Tmp       = StartRow;
 | 
						|
        StartRow  = EndRow;
 | 
						|
        EndRow    = Tmp;
 | 
						|
      }
 | 
						|
 | 
						|
      FStartRow = StartRow;
 | 
						|
 | 
						|
      StartRow  = 2 + StartRow - HBufferImage.LowVisibleRow;
 | 
						|
      EndRow    = 2 + EndRow - HBufferImage.LowVisibleRow;
 | 
						|
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // not mouse selection actions
 | 
						|
      //
 | 
						|
      FStartRow = HBufferImage.LowVisibleRow;
 | 
						|
      StartRow  = 2;
 | 
						|
      EndRow    = (HMainEditor.ScreenSize.Row - 1);
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // no line
 | 
						|
    //
 | 
						|
    if (HBufferImage.Lines == NULL) {
 | 
						|
      HBufferImageRestoreMousePosition ();
 | 
						|
      HBufferImageRestorePosition ();
 | 
						|
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // get the first line that will be displayed
 | 
						|
    //
 | 
						|
    Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row);
 | 
						|
    if (Line == NULL) {
 | 
						|
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);
 | 
						|
      return EFI_LOAD_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    Link  = &(Line->Link);
 | 
						|
    Row   = StartRow;
 | 
						|
    do {
 | 
						|
      Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
 | 
						|
      //
 | 
						|
      // print line at row
 | 
						|
      //
 | 
						|
      HBufferImagePrintLine (
 | 
						|
        Line,
 | 
						|
        Row,
 | 
						|
        HBufferImage.LowVisibleRow + Row - 2,
 | 
						|
        Orig,
 | 
						|
        New
 | 
						|
        );
 | 
						|
 | 
						|
      Link = Link->ForwardLink;
 | 
						|
      Row++;
 | 
						|
    } while (Link != HBufferImage.ListHead && Row <= EndRow);
 | 
						|
 | 
						|
    while (Row <= EndRow) {
 | 
						|
      EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row);
 | 
						|
      Row++;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // while not file end and not screen full
 | 
						|
    //
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageRestoreMousePosition ();
 | 
						|
  HBufferImageRestorePosition ();
 | 
						|
 | 
						|
  HBufferImageNeedRefresh         = FALSE;
 | 
						|
  HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read an image into a buffer friom a source.
 | 
						|
 | 
						|
  @param[in] FileName     Pointer to the file name.  OPTIONAL and ignored if not FileTypeFileBuffer.
 | 
						|
  @param[in] DiskName     Pointer to the disk name.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] DiskOffset   Offset into the disk.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] DiskSize     Size of the disk buffer.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] MemOffset    Offset into the Memory.  OPTIONAL and ignored if not FileTypeMemBuffer.
 | 
						|
  @param[in] MemSize      Size of the Memory buffer.  OPTIONAL and ignored if not FileTypeMemBuffer.
 | 
						|
  @param[in] BufferType   The type of buffer to save.  IGNORED.
 | 
						|
  @param[in] Recover      TRUE for recovermode, FALSE otherwise.
 | 
						|
 | 
						|
  @return EFI_SUCCESS     The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageRead (
 | 
						|
  IN CONST CHAR16                   *FileName,
 | 
						|
  IN CONST CHAR16                   *DiskName,
 | 
						|
  IN UINTN                          DiskOffset,
 | 
						|
  IN UINTN                          DiskSize,
 | 
						|
  IN UINTN                          MemOffset,
 | 
						|
  IN UINTN                          MemSize,
 | 
						|
  IN EDIT_FILE_TYPE                 BufferType,
 | 
						|
  IN BOOLEAN                        Recover
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  EDIT_FILE_TYPE                  BufferTypeBackup;
 | 
						|
 | 
						|
  //
 | 
						|
  // variable initialization
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  HBufferImage.BufferType = BufferType;
 | 
						|
 | 
						|
  //
 | 
						|
  // three types of buffer supported
 | 
						|
  //   file buffer
 | 
						|
  //   disk buffer
 | 
						|
  //   memory buffer
 | 
						|
  //
 | 
						|
  BufferTypeBackup = HBufferImage.BufferType;
 | 
						|
 | 
						|
  switch (BufferType) {
 | 
						|
  case FileTypeFileBuffer:
 | 
						|
    Status = HFileImageRead (FileName, Recover);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FileTypeDiskBuffer:
 | 
						|
    Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FileTypeMemBuffer:
 | 
						|
    Status = HMemImageRead (MemOffset, MemSize, Recover);
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    HBufferImage.BufferType = BufferTypeBackup;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Save the current image.
 | 
						|
 | 
						|
  @param[in] FileName     Pointer to the file name.  OPTIONAL and ignored if not FileTypeFileBuffer.
 | 
						|
  @param[in] DiskName     Pointer to the disk name.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] DiskOffset   Offset into the disk.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] DiskSize     Size of the disk buffer.  OPTIONAL and ignored if not FileTypeDiskBuffer.
 | 
						|
  @param[in] MemOffset    Offset into the Memory.  OPTIONAL and ignored if not FileTypeMemBuffer.
 | 
						|
  @param[in] MemSize      Size of the Memory buffer.  OPTIONAL and ignored if not FileTypeMemBuffer.
 | 
						|
  @param[in] BufferType   The type of buffer to save.  IGNORED.
 | 
						|
 | 
						|
  @return EFI_SUCCESS     The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageSave (
 | 
						|
  IN CHAR16                         *FileName,
 | 
						|
  IN CHAR16                         *DiskName,
 | 
						|
  IN UINTN                          DiskOffset,
 | 
						|
  IN UINTN                          DiskSize,
 | 
						|
  IN UINTN                          MemOffset,
 | 
						|
  IN UINTN                          MemSize,
 | 
						|
  IN EDIT_FILE_TYPE                 BufferType
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                      Status;
 | 
						|
  EDIT_FILE_TYPE                  BufferTypeBackup;
 | 
						|
 | 
						|
  //
 | 
						|
  // variable initialization
 | 
						|
  //
 | 
						|
  Status            = EFI_SUCCESS;
 | 
						|
  BufferTypeBackup  = HBufferImage.BufferType;
 | 
						|
 | 
						|
  switch (HBufferImage.BufferType) {
 | 
						|
  //
 | 
						|
  // file buffer
 | 
						|
  //
 | 
						|
  case FileTypeFileBuffer:
 | 
						|
    Status = HFileImageSave (FileName);
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // disk buffer
 | 
						|
  //
 | 
						|
  case FileTypeDiskBuffer:
 | 
						|
    Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // memory buffer
 | 
						|
  //
 | 
						|
  case FileTypeMemBuffer:
 | 
						|
    Status = HMemImageSave (MemOffset, MemSize);
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    HBufferImage.BufferType = BufferTypeBackup;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create a new line and append it to the line list.
 | 
						|
    Fields affected:
 | 
						|
    NumLines
 | 
						|
    Lines
 | 
						|
 | 
						|
  @retval NULL    create line failed.
 | 
						|
  @return         the line created.
 | 
						|
 | 
						|
**/
 | 
						|
HEFI_EDITOR_LINE *
 | 
						|
HBufferImageCreateLine (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
 | 
						|
  //
 | 
						|
  // allocate for line structure
 | 
						|
  //
 | 
						|
  Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));
 | 
						|
  if (Line == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  Line->Signature = EFI_EDITOR_LINE_LIST;
 | 
						|
  Line->Size      = 0;
 | 
						|
 | 
						|
  HBufferImage.NumLines++;
 | 
						|
 | 
						|
  //
 | 
						|
  // insert to line list
 | 
						|
  //
 | 
						|
  InsertTailList (HBufferImage.ListHead, &Line->Link);
 | 
						|
 | 
						|
  if (HBufferImage.Lines == NULL) {
 | 
						|
    HBufferImage.Lines = CR (
 | 
						|
                          HBufferImage.ListHead->ForwardLink,
 | 
						|
                          HEFI_EDITOR_LINE,
 | 
						|
                          Link,
 | 
						|
                          EFI_EDITOR_LINE_LIST
 | 
						|
                          );
 | 
						|
  }
 | 
						|
 | 
						|
  return Line;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Free the current image.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageFree (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // free all lines
 | 
						|
  //
 | 
						|
  HBufferImageFreeLines ();
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  change char to int value based on Hex.
 | 
						|
 | 
						|
  @param[in] Char     The input char.
 | 
						|
 | 
						|
  @return The character's index value.
 | 
						|
  @retval -1  The operation failed.
 | 
						|
**/
 | 
						|
INTN
 | 
						|
HBufferImageCharToHex (
 | 
						|
  IN CHAR16 Char
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // change the character to hex
 | 
						|
  //
 | 
						|
  if (Char >= L'0' && Char <= L'9') {
 | 
						|
    return (Char - L'0');
 | 
						|
  }
 | 
						|
 | 
						|
  if (Char >= L'a' && Char <= L'f') {
 | 
						|
    return (Char - L'a' + 10);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Char >= L'A' && Char <= L'F') {
 | 
						|
    return (Char - L'A' + 10);
 | 
						|
  }
 | 
						|
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Add character.
 | 
						|
 | 
						|
  @param[in] Char -- input char.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageAddChar (
 | 
						|
  IN  CHAR16  Char
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  HEFI_EDITOR_LINE  *NewLine;
 | 
						|
  INTN              Value;
 | 
						|
  UINT8             Old;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  BOOLEAN           High;
 | 
						|
 | 
						|
  Value = HBufferImageCharToHex (Char);
 | 
						|
 | 
						|
  //
 | 
						|
  // invalid input
 | 
						|
  //
 | 
						|
  if (Value == -1) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Line  = HBufferImage.CurrentLine;
 | 
						|
  FRow  = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol  = HBufferImage.BufferPosition.Column;
 | 
						|
  High  = HBufferImage.HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // only needs to refresh current line
 | 
						|
  //
 | 
						|
  HBufferImageOnlyLineNeedRefresh = TRUE;
 | 
						|
 | 
						|
  //
 | 
						|
  // not a full line and beyond the last character
 | 
						|
  //
 | 
						|
  if (FCol > Line->Size) {
 | 
						|
    //
 | 
						|
    // cursor always at high 4 bits
 | 
						|
    // and always put input to the low 4 bits
 | 
						|
    //
 | 
						|
    Line->Buffer[Line->Size] = (UINT8) Value;
 | 
						|
    Line->Size++;
 | 
						|
    High = FALSE;
 | 
						|
  } else {
 | 
						|
 | 
						|
    Old = Line->Buffer[FCol - 1];
 | 
						|
 | 
						|
    //
 | 
						|
    // always put the input to the low 4 bits
 | 
						|
    //
 | 
						|
    Old                     = (UINT8) (Old & 0x0f);
 | 
						|
    Old                     = (UINT8) (Old << 4);
 | 
						|
    Old                     = (UINT8) (Value + Old);
 | 
						|
    Line->Buffer[FCol - 1]  = Old;
 | 
						|
 | 
						|
    //
 | 
						|
    // at the low 4 bits of the last character of a full line
 | 
						|
    // so if no next line, need to create a new line
 | 
						|
    //
 | 
						|
    if (!High && FCol == 0x10) {
 | 
						|
 | 
						|
      HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
      HBufferImageNeedRefresh         = TRUE;
 | 
						|
 | 
						|
      if (Line->Link.ForwardLink == HBufferImage.ListHead) {
 | 
						|
        //
 | 
						|
        // last line
 | 
						|
        //
 | 
						|
        // create a new line
 | 
						|
        //
 | 
						|
        NewLine = HBufferImageCreateLine ();
 | 
						|
        if (NewLine == NULL) {
 | 
						|
          return EFI_OUT_OF_RESOURCES;
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // end of NULL
 | 
						|
        //
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // end of == ListHead
 | 
						|
      //
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of == 0x10
 | 
						|
    //
 | 
						|
    // if already at end of this line, scroll it to the start of next line
 | 
						|
    //
 | 
						|
    if (FCol == 0x10 && !High) {
 | 
						|
      //
 | 
						|
      // definitely has next line
 | 
						|
      //
 | 
						|
      FRow++;
 | 
						|
      FCol  = 1;
 | 
						|
      High  = TRUE;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // if not at end of this line, just move to next column
 | 
						|
      //
 | 
						|
      if (!High) {
 | 
						|
        FCol++;
 | 
						|
      }
 | 
						|
 | 
						|
      if (High) {
 | 
						|
        High = FALSE;
 | 
						|
      } else {
 | 
						|
        High = TRUE;
 | 
						|
      }
 | 
						|
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of ==FALSE
 | 
						|
    //
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // move cursor to right
 | 
						|
  //
 | 
						|
  HBufferImageMovePosition (FRow, FCol, High);
 | 
						|
 | 
						|
  if (!HBufferImage.Modified) {
 | 
						|
    HBufferImage.Modified = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Delete the previous character.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operationw as successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageDoBackspace (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
 | 
						|
  UINTN             FileColumn;
 | 
						|
  UINTN             FPos;
 | 
						|
  BOOLEAN           LastLine;
 | 
						|
 | 
						|
  //
 | 
						|
  // variable initialization
 | 
						|
  //
 | 
						|
  LastLine = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // already the first character
 | 
						|
  //
 | 
						|
  if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  FPos        = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
 | 
						|
 | 
						|
  FileColumn  = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  Line        = HBufferImage.CurrentLine;
 | 
						|
  LastLine    = FALSE;
 | 
						|
  if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) {
 | 
						|
    LastLine = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // if is the last line
 | 
						|
  // then only this line need to be refreshed
 | 
						|
  //
 | 
						|
  if (LastLine) {
 | 
						|
    HBufferImageNeedRefresh         = FALSE;
 | 
						|
    HBufferImageOnlyLineNeedRefresh = TRUE;
 | 
						|
  } else {
 | 
						|
    HBufferImageNeedRefresh         = TRUE;
 | 
						|
    HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!HBufferImage.Modified) {
 | 
						|
    HBufferImage.Modified = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  ASCII key + Backspace + return.
 | 
						|
 | 
						|
  @param[in] Char               The input char.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR        A load error occured.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageDoCharInput (
 | 
						|
  IN  CHAR16  Char
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  switch (Char) {
 | 
						|
  case 0:
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x08:
 | 
						|
    Status = HBufferImageDoBackspace ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case 0x09:
 | 
						|
  case 0x0a:
 | 
						|
  case 0x0d:
 | 
						|
    //
 | 
						|
    // Tabs, Returns are thought as nothing
 | 
						|
    //
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    //
 | 
						|
    // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
 | 
						|
    //
 | 
						|
    if (Char > 127 || Char < 32) {
 | 
						|
      Status = StatusBarSetStatusString (L"Unknown Command");
 | 
						|
    } else {
 | 
						|
      Status = HBufferImageAddChar (Char);
 | 
						|
    }
 | 
						|
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check user specified FileRow is above current screen.
 | 
						|
 | 
						|
  @param[in] FileRow  Row of file position ( start from 1 ).
 | 
						|
 | 
						|
  @retval TRUE   It is above the current screen.
 | 
						|
  @retval FALSE  It is not above the current screen.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
HAboveCurrentScreen (
 | 
						|
  IN  UINTN FileRow
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (FileRow < HBufferImage.LowVisibleRow) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Check user specified FileRow is under current screen.
 | 
						|
 | 
						|
  @param[in] FileRow    Row of file position ( start from 1 ).
 | 
						|
 | 
						|
  @retval TRUE      It is under the current screen.
 | 
						|
  @retval FALSE     It is not under the current screen.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
HUnderCurrentScreen (
 | 
						|
  IN  UINTN FileRow
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) {
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  According to cursor's file position, adjust screen display.
 | 
						|
 | 
						|
  @param[in] NewFilePosRow    Row of file position ( start from 1 ).
 | 
						|
  @param[in] NewFilePosCol    Column of file position ( start from 1 ).
 | 
						|
  @param[in] HighBits         Cursor will on high4 bits or low4 bits.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
HBufferImageMovePosition (
 | 
						|
  IN UINTN    NewFilePosRow,
 | 
						|
  IN UINTN    NewFilePosCol,
 | 
						|
  IN BOOLEAN  HighBits
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN    RowGap;
 | 
						|
  UINTN   Abs;
 | 
						|
  BOOLEAN Above;
 | 
						|
  BOOLEAN Under;
 | 
						|
  UINTN   NewDisplayCol;
 | 
						|
 | 
						|
  //
 | 
						|
  // CALCULATE gap between current file position and new file position
 | 
						|
  //
 | 
						|
  RowGap                = NewFilePosRow - HBufferImage.BufferPosition.Row;
 | 
						|
 | 
						|
  Under                 = HUnderCurrentScreen (NewFilePosRow);
 | 
						|
  Above                 = HAboveCurrentScreen (NewFilePosRow);
 | 
						|
 | 
						|
  HBufferImage.HighBits = HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // if is below current screen
 | 
						|
  //
 | 
						|
  if (Under) {
 | 
						|
    //
 | 
						|
    // display row will be unchanged
 | 
						|
    //
 | 
						|
    HBufferImage.BufferPosition.Row = NewFilePosRow;
 | 
						|
  } else {
 | 
						|
    if (Above) {
 | 
						|
      //
 | 
						|
      // has enough above line, so display row unchanged
 | 
						|
      // not has enough above lines, so the first line is
 | 
						|
      // at the first display line
 | 
						|
      //
 | 
						|
      if (NewFilePosRow < (HBufferImage.DisplayPosition.Row - 2 + 1)) {
 | 
						|
        HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;
 | 
						|
      }
 | 
						|
 | 
						|
      HBufferImage.BufferPosition.Row = NewFilePosRow;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // in current screen
 | 
						|
      //
 | 
						|
      HBufferImage.BufferPosition.Row = NewFilePosRow;
 | 
						|
      if (RowGap <= 0) {
 | 
						|
        Abs = (UINTN)ABS(RowGap);
 | 
						|
        HBufferImage.DisplayPosition.Row -= Abs;
 | 
						|
      } else {
 | 
						|
        HBufferImage.DisplayPosition.Row += RowGap;
 | 
						|
      }
 | 
						|
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);
 | 
						|
 | 
						|
  //
 | 
						|
  // always in current screen
 | 
						|
  //
 | 
						|
  HBufferImage.BufferPosition.Column  = NewFilePosCol;
 | 
						|
 | 
						|
  NewDisplayCol                       = 10 + (NewFilePosCol - 1) * 3;
 | 
						|
  if (NewFilePosCol > 0x8) {
 | 
						|
    NewDisplayCol++;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!HighBits) {
 | 
						|
    NewDisplayCol++;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImage.DisplayPosition.Column = NewDisplayCol;
 | 
						|
 | 
						|
  //
 | 
						|
  // let CurrentLine point to correct line;
 | 
						|
  //
 | 
						|
  HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to right.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageScrollRight (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
 | 
						|
  //
 | 
						|
  // scroll right will always move to the high4 bits of the next character
 | 
						|
  //
 | 
						|
  HBufferImageNeedRefresh         = FALSE;
 | 
						|
  HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
 | 
						|
  Line = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  //
 | 
						|
  // this line is not full and no next line
 | 
						|
  //
 | 
						|
  if (FCol > Line->Size) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // if already at end of this line, scroll it to the start of next line
 | 
						|
  //
 | 
						|
  if (FCol == 0x10) {
 | 
						|
    //
 | 
						|
    // has next line
 | 
						|
    //
 | 
						|
    if (Line->Link.ForwardLink != HBufferImage.ListHead) {
 | 
						|
      FRow++;
 | 
						|
      FCol = 1;
 | 
						|
 | 
						|
    } else {
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // if not at end of this line, just move to next column
 | 
						|
    //
 | 
						|
    FCol++;
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, TRUE);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to left.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageScrollLeft (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
 | 
						|
  HBufferImageNeedRefresh         = FALSE;
 | 
						|
  HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
 | 
						|
  Line = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  //
 | 
						|
  // if already at start of this line, so move to the end of previous line
 | 
						|
  //
 | 
						|
  if (FCol <= 1) {
 | 
						|
    //
 | 
						|
    // has previous line
 | 
						|
    //
 | 
						|
    if (Line->Link.BackLink != HBufferImage.ListHead) {
 | 
						|
      FRow--;
 | 
						|
      Line  = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
      FCol  = Line->Size;
 | 
						|
    } else {
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // if not at start of this line, just move to previous column
 | 
						|
    //
 | 
						|
    FCol--;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, TRUE);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to the next line
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageScrollDown (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  BOOLEAN           HighBits;
 | 
						|
 | 
						|
  Line      = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow      = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol      = HBufferImage.BufferPosition.Column;
 | 
						|
  HighBits  = HBufferImage.HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // has next line
 | 
						|
  //
 | 
						|
  if (Line->Link.ForwardLink != HBufferImage.ListHead) {
 | 
						|
    FRow++;
 | 
						|
    Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
 | 
						|
    //
 | 
						|
    // if the next line is not that long, so move to end of next line
 | 
						|
    //
 | 
						|
    if (FCol > Line->Size) {
 | 
						|
      FCol      = Line->Size + 1;
 | 
						|
      HighBits  = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
  } else {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to previous line
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageScrollUp (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
 | 
						|
  Line  = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow  = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol  = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  //
 | 
						|
  // has previous line
 | 
						|
  //
 | 
						|
  if (Line->Link.BackLink != HBufferImage.ListHead) {
 | 
						|
    FRow--;
 | 
						|
 | 
						|
  } else {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to next page
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImagePageDown (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  UINTN             Gap;
 | 
						|
  BOOLEAN           HighBits;
 | 
						|
 | 
						|
  Line      = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow      = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol      = HBufferImage.BufferPosition.Column;
 | 
						|
  HighBits  = HBufferImage.HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // has next page
 | 
						|
  //
 | 
						|
  if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) {
 | 
						|
    Gap = (HMainEditor.ScreenSize.Row - 2);
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // MOVE CURSOR TO LAST LINE
 | 
						|
    //
 | 
						|
    Gap = HBufferImage.NumLines - FRow;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // get correct line
 | 
						|
  //
 | 
						|
  Line = HMoveLine (Gap);
 | 
						|
 | 
						|
  //
 | 
						|
  // if that line, is not that long, so move to the end of that line
 | 
						|
  //
 | 
						|
  if (Line != NULL && FCol > Line->Size) {
 | 
						|
    FCol      = Line->Size + 1;
 | 
						|
    HighBits  = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  FRow += Gap;
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to previous page
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImagePageUp (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  UINTN             Gap;
 | 
						|
  INTN              Retreat;
 | 
						|
 | 
						|
  FRow  = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol  = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  //
 | 
						|
  // has previous page
 | 
						|
  //
 | 
						|
  if (FRow > (HMainEditor.ScreenSize.Row - 2)) {
 | 
						|
    Gap = (HMainEditor.ScreenSize.Row - 2);
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // the first line of file will displayed on the first line of screen
 | 
						|
    //
 | 
						|
    Gap = FRow - 1;
 | 
						|
  }
 | 
						|
 | 
						|
  Retreat = Gap;
 | 
						|
  Retreat = -Retreat;
 | 
						|
 | 
						|
  FRow -= Gap;
 | 
						|
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to start of line
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageHome (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  BOOLEAN           HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // curosr will at the high bit
 | 
						|
  //
 | 
						|
  FRow      = HBufferImage.BufferPosition.Row;
 | 
						|
  FCol      = 1;
 | 
						|
  HighBits  = TRUE;
 | 
						|
 | 
						|
  //
 | 
						|
  // move cursor position
 | 
						|
  //
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Scroll cursor to end of line.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS  Teh operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageEnd (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINTN             FRow;
 | 
						|
  UINTN             FCol;
 | 
						|
  BOOLEAN           HighBits;
 | 
						|
 | 
						|
  //
 | 
						|
  // need refresh mouse
 | 
						|
  //
 | 
						|
  HBufferImageMouseNeedRefresh  = TRUE;
 | 
						|
 | 
						|
  Line                          = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  FRow                          = HBufferImage.BufferPosition.Row;
 | 
						|
 | 
						|
  if (Line->Size == 0x10) {
 | 
						|
    FCol      = Line->Size;
 | 
						|
    HighBits  = FALSE;
 | 
						|
  } else {
 | 
						|
    FCol      = Line->Size + 1;
 | 
						|
    HighBits  = TRUE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // move cursor position
 | 
						|
  //
 | 
						|
  HBufferImageMovePosition (FRow, FCol, HighBits);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get the size of the open buffer.
 | 
						|
 | 
						|
  @retval The size in bytes.
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
HBufferImageGetTotalSize (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             Size;
 | 
						|
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
 | 
						|
  //
 | 
						|
  // calculate the total size of whole line list's buffer
 | 
						|
  //
 | 
						|
  if (HBufferImage.Lines == NULL) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  Line = CR (
 | 
						|
          HBufferImage.ListHead->BackLink,
 | 
						|
          HEFI_EDITOR_LINE,
 | 
						|
          Link,
 | 
						|
          EFI_EDITOR_LINE_LIST
 | 
						|
          );
 | 
						|
  //
 | 
						|
  // one line at most 0x10
 | 
						|
  //
 | 
						|
  Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;
 | 
						|
 | 
						|
  return Size;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Delete character from buffer.
 | 
						|
 | 
						|
  @param[in] Pos      Position, Pos starting from 0.
 | 
						|
  @param[in] Count    The Count of characters to delete.
 | 
						|
  @param[out] DeleteBuffer    The DeleteBuffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Success
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageDeleteCharacterFromBuffer (
 | 
						|
  IN  UINTN         Pos,
 | 
						|
  IN  UINTN         Count,
 | 
						|
  OUT UINT8         *DeleteBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             Index;
 | 
						|
 | 
						|
  VOID              *Buffer;
 | 
						|
  UINT8             *BufferPtr;
 | 
						|
  UINTN             Size;
 | 
						|
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  LIST_ENTRY    *Link;
 | 
						|
 | 
						|
  UINTN             OldFCol;
 | 
						|
  UINTN             OldFRow;
 | 
						|
  UINTN             OldPos;
 | 
						|
 | 
						|
  UINTN             NewPos;
 | 
						|
 | 
						|
  EFI_STATUS        Status;
 | 
						|
 | 
						|
  Size      = HBufferImageGetTotalSize ();
 | 
						|
 | 
						|
  if (Size < Count) {
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Size == 0) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // relocate all the HBufferImage fields
 | 
						|
  //
 | 
						|
  OldFRow = HBufferImage.BufferPosition.Row;
 | 
						|
  OldFCol = HBufferImage.BufferPosition.Column;
 | 
						|
  OldPos  = (OldFRow - 1) * 0x10 + OldFCol - 1;
 | 
						|
 | 
						|
  if (Pos > 0) {
 | 
						|
    //
 | 
						|
    // has character before it,
 | 
						|
    // so locate according to block's previous character
 | 
						|
    //
 | 
						|
    NewPos = Pos - 1;
 | 
						|
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // has no character before it,
 | 
						|
    // so locate according to block's next character
 | 
						|
    //
 | 
						|
    NewPos = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
 | 
						|
 | 
						|
  Buffer = AllocateZeroPool (Size);
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageListToBuffer (Buffer, Size);
 | 
						|
 | 
						|
  BufferPtr = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  //
 | 
						|
  // pass deleted buffer out
 | 
						|
  //
 | 
						|
  if (DeleteBuffer != NULL) {
 | 
						|
    for (Index = 0; Index < Count; Index++) {
 | 
						|
      DeleteBuffer[Index] = BufferPtr[Pos + Index];
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // delete the part from Pos
 | 
						|
  //
 | 
						|
  for (Index = Pos; Index < Size - Count; Index++) {
 | 
						|
    BufferPtr[Index] = BufferPtr[Index + Count];
 | 
						|
  }
 | 
						|
 | 
						|
  Size -= Count;
 | 
						|
 | 
						|
  HBufferImageFreeLines ();
 | 
						|
 | 
						|
  Status = HBufferImageBufferToList (Buffer, Size);
 | 
						|
  FreePool (Buffer);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Link = HMainEditor.BufferImage->ListHead->ForwardLink;
 | 
						|
  for (Index = 0; Index < NewPos / 0x10; Index++) {
 | 
						|
    Link = Link->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  Line                      = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
  HBufferImage.CurrentLine  = Line;
 | 
						|
 | 
						|
  //
 | 
						|
  // if current cursor position if inside select area
 | 
						|
  // then move it to the block's NEXT character
 | 
						|
  //
 | 
						|
  if (OldPos >= Pos && OldPos < (Pos + Count)) {
 | 
						|
    NewPos = Pos;
 | 
						|
  } else {
 | 
						|
    if (OldPos < Pos) {
 | 
						|
      NewPos = OldPos;
 | 
						|
    } else {
 | 
						|
      NewPos = OldPos - Count;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Add character to buffer, add before pos.
 | 
						|
 | 
						|
  @param[in] Pos        Position, Pos starting from 0.
 | 
						|
  @param[in] Count      Count of characters to add.
 | 
						|
  @param[in] AddBuffer  Add buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   Success.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageAddCharacterToBuffer (
 | 
						|
  IN  UINTN          Pos,
 | 
						|
  IN  UINTN          Count,
 | 
						|
  IN  UINT8          *AddBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN              Index;
 | 
						|
 | 
						|
  VOID              *Buffer;
 | 
						|
  UINT8             *BufferPtr;
 | 
						|
  UINTN             Size;
 | 
						|
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
 | 
						|
  LIST_ENTRY    *Link;
 | 
						|
 | 
						|
  UINTN             OldFCol;
 | 
						|
  UINTN             OldFRow;
 | 
						|
  UINTN             OldPos;
 | 
						|
 | 
						|
  UINTN             NewPos;
 | 
						|
 | 
						|
  Size      = HBufferImageGetTotalSize ();
 | 
						|
 | 
						|
  //
 | 
						|
  // relocate all the HBufferImage fields
 | 
						|
  //
 | 
						|
  OldFRow = HBufferImage.BufferPosition.Row;
 | 
						|
  OldFCol = HBufferImage.BufferPosition.Column;
 | 
						|
  OldPos  = (OldFRow - 1) * 0x10 + OldFCol - 1;
 | 
						|
 | 
						|
  //
 | 
						|
  // move cursor before Pos
 | 
						|
  //
 | 
						|
  if (Pos > 0) {
 | 
						|
    NewPos = Pos - 1;
 | 
						|
  } else {
 | 
						|
    NewPos = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
 | 
						|
 | 
						|
  Buffer = AllocateZeroPool (Size + Count);
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageListToBuffer (Buffer, Size);
 | 
						|
 | 
						|
  BufferPtr = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  //
 | 
						|
  // get a place to add
 | 
						|
  //
 | 
						|
  for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {
 | 
						|
    BufferPtr[Index] = BufferPtr[Index - Count];
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // add the buffer
 | 
						|
  //
 | 
						|
  for (Index = (INTN) 0; Index < (INTN) Count; Index++) {
 | 
						|
    BufferPtr[Index + Pos] = AddBuffer[Index];
 | 
						|
  }
 | 
						|
 | 
						|
  Size += Count;
 | 
						|
 | 
						|
  HBufferImageFreeLines ();
 | 
						|
 | 
						|
  HBufferImageBufferToList (Buffer, Size);
 | 
						|
 | 
						|
  FreePool (Buffer);
 | 
						|
 | 
						|
  Link = HMainEditor.BufferImage->ListHead->ForwardLink;
 | 
						|
  for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {
 | 
						|
    Link = Link->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  Line                      = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
  HBufferImage.CurrentLine  = Line;
 | 
						|
 | 
						|
  if (OldPos >= Pos) {
 | 
						|
    NewPos = OldPos + Count;
 | 
						|
  } else {
 | 
						|
    NewPos = OldPos;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Delete current character from line.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operationw as successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageDoDelete (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
 | 
						|
  BOOLEAN           LastLine;
 | 
						|
  UINTN             FileColumn;
 | 
						|
  UINTN             FPos;
 | 
						|
 | 
						|
  FPos        = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;
 | 
						|
 | 
						|
  FileColumn  = HBufferImage.BufferPosition.Column;
 | 
						|
 | 
						|
  Line        = HBufferImage.CurrentLine;
 | 
						|
 | 
						|
  //
 | 
						|
  // if beyond the last character
 | 
						|
  //
 | 
						|
  if (FileColumn > Line->Size) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  LastLine = FALSE;
 | 
						|
  if (Line->Link.ForwardLink == HBufferImage.ListHead) {
 | 
						|
    LastLine = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // if is the last line
 | 
						|
  // then only this line need to be refreshed
 | 
						|
  //
 | 
						|
  if (LastLine) {
 | 
						|
    HBufferImageNeedRefresh         = FALSE;
 | 
						|
    HBufferImageOnlyLineNeedRefresh = TRUE;
 | 
						|
  } else {
 | 
						|
    HBufferImageNeedRefresh         = TRUE;
 | 
						|
    HBufferImageOnlyLineNeedRefresh = FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!HBufferImage.Modified) {
 | 
						|
    HBufferImage.Modified = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Change the raw buffer to a list of lines for the UI.
 | 
						|
 | 
						|
  @param[in] Buffer   The pointer to the buffer to fill.
 | 
						|
  @param[in] Bytes    The size of the buffer in bytes.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageBufferToList (
 | 
						|
  IN VOID   *Buffer,
 | 
						|
  IN UINTN  Bytes
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             TempI;
 | 
						|
  UINTN             TempJ;
 | 
						|
  UINTN             Left;
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  UINT8             *BufferPtr;
 | 
						|
 | 
						|
  TempI         = 0;
 | 
						|
  Left      = 0;
 | 
						|
  BufferPtr = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  //
 | 
						|
  // parse file content line by line
 | 
						|
  //
 | 
						|
  while (TempI < Bytes) {
 | 
						|
    if (Bytes - TempI >= 0x10) {
 | 
						|
      Left = 0x10;
 | 
						|
    } else {
 | 
						|
      Left = Bytes - TempI;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // allocate a new line
 | 
						|
    //
 | 
						|
    Line = HBufferImageCreateLine ();
 | 
						|
    if (Line == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    Line->Size = Left;
 | 
						|
 | 
						|
    for (TempJ = 0; TempJ < Left; TempJ++) {
 | 
						|
      Line->Buffer[TempJ] = BufferPtr[TempI];
 | 
						|
      TempI++;
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // last line is a full line, SO create a new line
 | 
						|
  //
 | 
						|
  if (Left == 0x10 || Bytes == 0) {
 | 
						|
    Line = HBufferImageCreateLine ();
 | 
						|
    if (Line == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Change the list of lines from the UI to a raw buffer.
 | 
						|
 | 
						|
  @param[in] Buffer   The pointer to the buffer to fill.
 | 
						|
  @param[in] Bytes    The size of the buffer in bytes.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageListToBuffer (
 | 
						|
  IN VOID   *Buffer,
 | 
						|
  IN UINTN  Bytes
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN             Count;
 | 
						|
  UINTN             Index;
 | 
						|
  HEFI_EDITOR_LINE  *Line;
 | 
						|
  LIST_ENTRY    *Link;
 | 
						|
  UINT8             *BufferPtr;
 | 
						|
 | 
						|
  //
 | 
						|
  // change the line list to a large buffer
 | 
						|
  //
 | 
						|
  if (HBufferImage.Lines == NULL) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Link      = &HBufferImage.Lines->Link;
 | 
						|
  Count     = 0;
 | 
						|
  BufferPtr = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  //
 | 
						|
  // deal line by line
 | 
						|
  //
 | 
						|
  while (Link != HBufferImage.ListHead) {
 | 
						|
 | 
						|
    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
 | 
						|
 | 
						|
    //@todo shouldn't this be an error???
 | 
						|
    if (Count + Line->Size > Bytes) {
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
 | 
						|
    for (Index = 0; Index < Line->Size; Index++) {
 | 
						|
      BufferPtr[Index] = Line->Buffer[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    Count += Line->Size;
 | 
						|
    BufferPtr += Line->Size;
 | 
						|
 | 
						|
    Link = Link->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Move the mouse in the image buffer.
 | 
						|
 | 
						|
  @param[in] TextX    The x-coordinate.
 | 
						|
  @param[in] TextY    The y-coordinate.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
HBufferImageAdjustMousePosition (
 | 
						|
  IN INT32 TextX,
 | 
						|
  IN INT32 TextY
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN TempX;
 | 
						|
  UINTN TempY;
 | 
						|
  UINTN AbsX;
 | 
						|
  UINTN AbsY;
 | 
						|
 | 
						|
  //
 | 
						|
  // TextX and TextY is mouse movement data returned by mouse driver
 | 
						|
  // This function will change it to MousePosition
 | 
						|
  //
 | 
						|
  //
 | 
						|
  // get absolute TempX value
 | 
						|
  //
 | 
						|
  if (TextX >= 0) {
 | 
						|
    AbsX = TextX;
 | 
						|
  } else {
 | 
						|
    AbsX = -TextX;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // get absolute TempY value
 | 
						|
  //
 | 
						|
  if (TextY >= 0) {
 | 
						|
    AbsY = TextY;
 | 
						|
  } else {
 | 
						|
    AbsY = -TextY;
 | 
						|
  }
 | 
						|
 | 
						|
  TempX = HBufferImage.MousePosition.Column;
 | 
						|
  TempY = HBufferImage.MousePosition.Row;
 | 
						|
 | 
						|
  if (TextX >= 0) {
 | 
						|
    TempX += TextX;
 | 
						|
  } else {
 | 
						|
    if (TempX >= AbsX) {
 | 
						|
      TempX -= AbsX;
 | 
						|
    } else {
 | 
						|
      TempX = 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (TextY >= 0) {
 | 
						|
    TempY += TextY;
 | 
						|
  } else {
 | 
						|
    if (TempY >= AbsY) {
 | 
						|
      TempY -= AbsY;
 | 
						|
    } else {
 | 
						|
      TempY = 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // check whether new mouse column position is beyond screen
 | 
						|
  // if not, adjust it
 | 
						|
  //
 | 
						|
  if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) {
 | 
						|
    HBufferImage.MousePosition.Column = TempX;
 | 
						|
  } else if (TempX < 10) {
 | 
						|
    HBufferImage.MousePosition.Column = 10;
 | 
						|
  } else if (TempX > (10 + 0x10 * 3 - 1)) {
 | 
						|
    HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // check whether new mouse row position is beyond screen
 | 
						|
  // if not, adjust it
 | 
						|
  //
 | 
						|
  if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 1)) {
 | 
						|
    HBufferImage.MousePosition.Row = TempY;
 | 
						|
  } else if (TempY < 2) {
 | 
						|
    HBufferImage.MousePosition.Row = 2;
 | 
						|
  } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) {
 | 
						|
    HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1);
 | 
						|
  }
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dispatch input to different handler
 | 
						|
 | 
						|
  @param[in] Key    The input key:
 | 
						|
                     the keys can be:
 | 
						|
                       ASCII KEY
 | 
						|
                        Backspace/Delete
 | 
						|
                        Direction key: up/down/left/right/pgup/pgdn
 | 
						|
                        Home/End
 | 
						|
                        INS
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR        A load error occured.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  A Memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HBufferImageHandleInput (
 | 
						|
  IN  EFI_INPUT_KEY *Key
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  switch (Key->ScanCode) {
 | 
						|
  //
 | 
						|
  // ordinary key
 | 
						|
  //
 | 
						|
  case SCAN_NULL:
 | 
						|
    Status = HBufferImageDoCharInput (Key->UnicodeChar);
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // up arrow
 | 
						|
  //
 | 
						|
  case SCAN_UP:
 | 
						|
    Status = HBufferImageScrollUp ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // down arrow
 | 
						|
  //
 | 
						|
  case SCAN_DOWN:
 | 
						|
    Status = HBufferImageScrollDown ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // right arrow
 | 
						|
  //
 | 
						|
  case SCAN_RIGHT:
 | 
						|
    Status = HBufferImageScrollRight ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // left arrow
 | 
						|
  //
 | 
						|
  case SCAN_LEFT:
 | 
						|
    Status = HBufferImageScrollLeft ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // page up
 | 
						|
  //
 | 
						|
  case SCAN_PAGE_UP:
 | 
						|
    Status = HBufferImagePageUp ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // page down
 | 
						|
  //
 | 
						|
  case SCAN_PAGE_DOWN:
 | 
						|
    Status = HBufferImagePageDown ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // delete
 | 
						|
  //
 | 
						|
  case SCAN_DELETE:
 | 
						|
    Status = HBufferImageDoDelete ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // home
 | 
						|
  //
 | 
						|
  case SCAN_HOME:
 | 
						|
    Status = HBufferImageHome ();
 | 
						|
    break;
 | 
						|
 | 
						|
  //
 | 
						|
  // end
 | 
						|
  //
 | 
						|
  case SCAN_END:
 | 
						|
    Status = HBufferImageEnd ();
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    Status = StatusBarSetStatusString (L"Unknown Command");
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 |