mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 03:58:31 +00:00 
			
		
		
		
	 47d20b54f9
			
		
	
	
		47d20b54f9
		
	
	
	
	
		
			
			REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the ShellPkg 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: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			2473 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2473 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 occurred.
 | |
| **/
 | |
| 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 occurred.
 | |
| 
 | |
| **/
 | |
| 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 occurred.
 | |
|   @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 occurred.
 | |
|   @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;
 | |
| }
 |