diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c')
| -rw-r--r-- | ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c | 4944 |
1 files changed, 2472 insertions, 2472 deletions
diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c index be77e31a40..3af53c516a 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/BufferImage.c @@ -1,2472 +1,2472 @@ -/** @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;
-}
+/** @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; +} |
