/** @file | |
Defines the Main Editor data type - | |
- Global variables | |
- Instances of the other objects of the editor | |
- Main Interfaces | |
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "HexEditor.h" | |
#include "EditStatusBar.h" | |
#include "EditInputBar.h" | |
HEFI_EDITOR_COLOR_ATTRIBUTES HOriginalColors; | |
INTN HOriginalMode; | |
// | |
// the first time editor launch | |
// | |
BOOLEAN HEditorFirst; | |
// | |
// it's time editor should exit | |
// | |
BOOLEAN HEditorExit; | |
BOOLEAN HEditorMouseAction; | |
extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage; | |
extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar; | |
extern BOOLEAN HBufferImageMouseNeedRefresh; | |
extern BOOLEAN HBufferImageNeedRefresh; | |
extern BOOLEAN HBufferImageOnlyLineNeedRefresh; | |
HEFI_EDITOR_GLOBAL_EDITOR HMainEditor; | |
HEFI_EDITOR_GLOBAL_EDITOR HMainEditorBackupVar; | |
// | |
// basic initialization for MainEditor | |
// | |
HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = { | |
&HBufferImage, | |
{ | |
{ 0, 0} | |
}, | |
{ | |
0, | |
0 | |
}, | |
NULL, | |
FALSE, | |
NULL, | |
0, | |
0, | |
1, | |
1 | |
}; | |
/** | |
Help info that will be displayed. | |
**/ | |
EFI_STRING_ID HexMainMenuHelpInfo[] = { | |
STRING_TOKEN (STR_HEXEDIT_HELP_TITLE), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_LIST_TITLE), | |
STRING_TOKEN (STR_HEXEDIT_HELP_DIV), | |
STRING_TOKEN (STR_HEXEDIT_HELP_GO_TO_OFFSET), | |
STRING_TOKEN (STR_HEXEDIT_HELP_SAVE_BUFFER), | |
STRING_TOKEN (STR_HEXEDIT_HELP_EXIT), | |
STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_START), | |
STRING_TOKEN (STR_HEXEDIT_HELP_SELECT_END), | |
STRING_TOKEN (STR_HEXEDIT_HELP_CUT), | |
STRING_TOKEN (STR_HEXEDIT_HELP_PASTE), | |
STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_FILE), | |
STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_DISK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_OPEN_MEMORY), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_EXIT_HELP), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_BLANK), | |
STRING_TOKEN (STR_HEXEDIT_HELP_DIV), | |
0 | |
}; | |
/** | |
show help menu. | |
@retval EFI_SUCCESS The operation was successful. | |
**/ | |
EFI_STATUS | |
HMainCommandDisplayHelp ( | |
VOID | |
) | |
{ | |
INT32 CurrentLine; | |
CHAR16 *InfoString; | |
EFI_KEY_DATA KeyData; | |
EFI_STATUS Status; | |
UINTN EventIndex; | |
// | |
// print helpInfo | |
// | |
for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) { | |
InfoString = HiiGetString ( | |
gShellDebug1HiiHandle, | |
HexMainMenuHelpInfo[CurrentLine] | |
, | |
NULL | |
); | |
ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString); | |
} | |
// | |
// scan for ctrl+w | |
// | |
while (TRUE) { | |
Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx->WaitForKeyEx, &EventIndex); | |
if (EFI_ERROR (Status) || (EventIndex != 0)) { | |
continue; | |
} | |
Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || | |
(KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) | |
{ | |
// | |
// For consoles that don't support/report shift state, | |
// CTRL+W is translated to L'W' - L'A' + 1. | |
// | |
if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) { | |
break; | |
} | |
} else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && | |
((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) && | |
((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) | |
{ | |
// | |
// For consoles that supports/reports shift state, | |
// make sure that only CONTROL shift key is pressed. | |
// | |
if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) { | |
break; | |
} | |
} | |
} | |
// update screen with buffer's info | |
HBufferImageNeedRefresh = TRUE; | |
HBufferImageOnlyLineNeedRefresh = FALSE; | |
HBufferImageRefresh (); | |
return EFI_SUCCESS; | |
} | |
/** | |
Move cursor to specified lines. | |
@retval EFI_SUCCESS The operation was successful. | |
**/ | |
EFI_STATUS | |
HMainCommandGoToOffset ( | |
VOID | |
) | |
{ | |
UINTN Size; | |
UINT64 Offset; | |
EFI_STATUS Status; | |
UINTN FRow; | |
UINTN FCol; | |
// | |
// variable initialization | |
// | |
Size = 0; | |
Offset = 0; | |
FRow = 0; | |
FCol = 0; | |
// | |
// get offset | |
// | |
Status = InputBarSetPrompt (L"Go To Offset: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (8); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE); | |
if (EFI_ERROR (Status)) { | |
StatusBarSetStatusString (L"Invalid Offset"); | |
return EFI_SUCCESS; | |
} | |
break; | |
} | |
} | |
Size = HBufferImageGetTotalSize (); | |
if (Offset >= Size) { | |
StatusBarSetStatusString (L"Invalid Offset"); | |
return EFI_SUCCESS; | |
} | |
FRow = (UINTN)DivU64x32 (Offset, 0x10) + 1; | |
FCol = (UINTN)ModU64x32 (Offset, 0x10) + 1; | |
HBufferImageMovePosition (FRow, FCol, TRUE); | |
HBufferImageNeedRefresh = TRUE; | |
HBufferImageOnlyLineNeedRefresh = FALSE; | |
HBufferImageMouseNeedRefresh = TRUE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Save current opened buffer. | |
If is file buffer, you can save to current file name or | |
save to another file name. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandSaveBuffer ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
BOOLEAN Done; | |
CHAR16 *FileName; | |
BOOLEAN OldFile; | |
CHAR16 *Str; | |
EFI_FILE_INFO *Info; | |
SHELL_FILE_HANDLE ShellFileHandle; | |
if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) { | |
if (!HMainEditor.BufferImage->Modified) { | |
return EFI_SUCCESS; | |
} | |
Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// the answer is just one character | |
// | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// loop for user's answer | |
// valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' | |
// | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
// | |
// want to save this buffer first | |
// | |
Status = HBufferImageSave ( | |
NULL, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
HMainEditor.BufferImage->BufferType | |
); | |
if (EFI_ERROR (Status)) { | |
StatusBarSetStatusString (L"BufferSave: Problems Writing"); | |
return Status; | |
} | |
return EFI_SUCCESS; | |
case L'n': | |
case L'N': | |
// | |
// the file won't be saved | |
// | |
return EFI_SUCCESS; | |
case L'c': | |
case L'C': | |
return EFI_SUCCESS; | |
} | |
// | |
// end of switch | |
// | |
} | |
// | |
// ENDOF WHILE | |
// | |
} | |
// | |
// ENDOF != FILEBUFFER | |
// | |
// This command will save currently opened file to disk. | |
// You can choose save to another file name or just save to | |
// current file name. | |
// Below is the scenario of Save File command: ( | |
// Suppose the old file name is A ) | |
// 1. An Input Bar will be prompted: "File To Save: [ old file name]" | |
// IF user press ESC, Save File command ends . | |
// IF user press Enter, input file name will be A. | |
// IF user inputs a new file name B, input file name will be B. | |
// | |
// 2. IF input file name is A, go to do Step 3. | |
// IF input file name is B, go to do Step 4. | |
// | |
// 3. IF A is read only, Status Bar will show "Access Denied" | |
// and Save File commands ends. | |
// IF A is not read only, save file buffer to disk | |
// and remove Modified flag in Title Bar , then Save File command ends. | |
// | |
// 4. IF B does not exist, create this file and save file buffer to it. | |
// Go to do Step 7. | |
// IF B exits, do Step 5. | |
// | |
// 5. An Input Bar will be prompted: | |
// "File Exists. Overwrite ( Yes/No/Cancel ) ?" | |
// IF user press 'y' or 'Y', do Step 6. | |
// IF user press 'n' or 'N', Save File commands ends. | |
// IF user press 'c' or 'C' or ESC, Save File commands ends. | |
// | |
// 6. IF B is a read-only file, Status Bar will show "Access Denied" | |
// and Save File commands ends. | |
// IF B can be read and write, save file buffer to B. | |
// | |
// 7. Update File Name field in Title Bar to B | |
// and remove the Modified flag in Title Bar. | |
// | |
Str = CatSPrint ( | |
NULL, | |
L"File to Save: [%s]", | |
HMainEditor.BufferImage->FileImage->FileName | |
); | |
if (Str == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
if (StrLen (Str) >= 50) { | |
// | |
// replace the long file name with "..." | |
// | |
Str[46] = L'.'; | |
Str[47] = L'.'; | |
Str[48] = L'.'; | |
Str[49] = L']'; | |
Str[50] = L'\0'; | |
} | |
Status = InputBarSetPrompt (Str); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (100); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// get new file name | |
// | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// if user pressed ESC | |
// | |
if (Status == EFI_NOT_READY) { | |
SHELL_FREE_NON_NULL (Str); | |
return EFI_SUCCESS; | |
} | |
SHELL_FREE_NON_NULL (Str); | |
// | |
// if just enter pressed, so think save to current file name | |
// | |
if (StrLen (InputBarGetString ()) == 0) { | |
FileName = CatSPrint ( | |
NULL, | |
L"%s", | |
HMainEditor.BufferImage->FileImage->FileName | |
); | |
} else { | |
FileName = CatSPrint (NULL, L"%s", InputBarGetString ()); | |
} | |
if (FileName == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
if (!IsValidFileName (FileName)) { | |
StatusBarSetStatusString (L"Invalid File Name"); | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
} | |
OldFile = FALSE; | |
// | |
// save to the old file | |
// | |
if (StringNoCaseCompare ( | |
&FileName, | |
&HMainEditor.BufferImage->FileImage->FileName | |
) == 0) | |
{ | |
OldFile = TRUE; | |
} | |
if (OldFile) { | |
// | |
// if the file is read only, so can not write back to it. | |
// | |
if (HMainEditor.BufferImage->FileImage->ReadOnly) { | |
StatusBarSetStatusString (L"Access Denied"); | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
} | |
} else { | |
Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0); | |
if (!EFI_ERROR (Status)) { | |
Info = ShellGetFileInfo (ShellFileHandle); | |
ShellCloseFile (&ShellFileHandle); | |
// | |
// check if read only | |
// | |
if (Info->Attribute & EFI_FILE_READ_ONLY) { | |
StatusBarSetStatusString (L"Access Denied"); | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
} | |
SHELL_FREE_NON_NULL (Info); | |
// | |
// ask user whether to overwrite this file | |
// | |
Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
SHELL_FREE_NON_NULL (FileName); | |
return Status; | |
} | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
SHELL_FREE_NON_NULL (FileName); | |
return Status; | |
} | |
Done = FALSE; | |
while (!Done) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
if (Status == EFI_NOT_READY) { | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
Done = TRUE; | |
break; | |
case L'n': | |
case L'N': | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
case L'c': | |
case L'C': | |
SHELL_FREE_NON_NULL (FileName); | |
return EFI_SUCCESS; | |
} // switch | |
} // while | |
} // if opened existing file | |
} // if OldFile | |
// | |
// save file back to disk | |
// | |
Status = HBufferImageSave ( | |
FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
FileTypeFileBuffer | |
); | |
SHELL_FREE_NON_NULL (FileName); | |
if (EFI_ERROR (Status)) { | |
return EFI_LOAD_ERROR; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Load a disk buffer editor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandSelectStart ( | |
VOID | |
) | |
{ | |
UINTN Start; | |
Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column; | |
// | |
// last line | |
// | |
if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { | |
if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) { | |
StatusBarSetStatusString (L"Invalid Block Start"); | |
return EFI_LOAD_ERROR; | |
} | |
} | |
if ((HMainEditor.SelectEnd != 0) && (Start > HMainEditor.SelectEnd)) { | |
StatusBarSetStatusString (L"Invalid Block Start"); | |
return EFI_LOAD_ERROR; | |
} | |
HMainEditor.SelectStart = Start; | |
HBufferImageNeedRefresh = TRUE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Load a disk buffer editor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandSelectEnd ( | |
VOID | |
) | |
{ | |
UINTN End; | |
End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column; | |
// | |
// last line | |
// | |
if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) { | |
if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) { | |
StatusBarSetStatusString (L"Invalid Block End"); | |
return EFI_LOAD_ERROR; | |
} | |
} | |
if ((HMainEditor.SelectStart != 0) && (End < HMainEditor.SelectStart)) { | |
StatusBarSetStatusString (L"Invalid Block End"); | |
return EFI_SUCCESS; | |
} | |
HMainEditor.SelectEnd = End; | |
HBufferImageNeedRefresh = TRUE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Cut current line to clipboard. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandCut ( | |
VOID | |
) | |
{ | |
UINTN Index; | |
LIST_ENTRY *Link; | |
UINT8 *Buffer; | |
UINTN Count; | |
// | |
// not select, so not allowed to cut | |
// | |
if (HMainEditor.SelectStart == 0) { | |
StatusBarSetStatusString (L"No Block is Selected"); | |
return EFI_SUCCESS; | |
} | |
// | |
// not select, so not allowed to cut | |
// | |
if (HMainEditor.SelectEnd == 0) { | |
StatusBarSetStatusString (L"No Block is Selected"); | |
return EFI_SUCCESS; | |
} | |
Link = HMainEditor.BufferImage->ListHead->ForwardLink; | |
for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) { | |
Link = Link->ForwardLink; | |
} | |
Count = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1; | |
Buffer = AllocateZeroPool (Count); | |
if (Buffer == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// | |
// cut the selected area | |
// | |
HBufferImageDeleteCharacterFromBuffer ( | |
HMainEditor.SelectStart - 1, | |
Count, | |
Buffer | |
); | |
// | |
// put to clipboard | |
// | |
HClipBoardSet (Buffer, Count); | |
HBufferImageNeedRefresh = TRUE; | |
HBufferImageOnlyLineNeedRefresh = FALSE; | |
if (!HMainEditor.BufferImage->Modified) { | |
HMainEditor.BufferImage->Modified = TRUE; | |
} | |
// | |
// now no select area | |
// | |
HMainEditor.SelectStart = 0; | |
HMainEditor.SelectEnd = 0; | |
return EFI_SUCCESS; | |
} | |
/** | |
Paste line to file buffer. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandPaste ( | |
VOID | |
) | |
{ | |
BOOLEAN OnlyLineRefresh; | |
HEFI_EDITOR_LINE *Line; | |
UINT8 *Buffer; | |
UINTN Count; | |
UINTN FPos; | |
Count = HClipBoardGet (&Buffer); | |
if ((Count == 0) || (Buffer == NULL)) { | |
StatusBarSetStatusString (L"Nothing to Paste"); | |
return EFI_SUCCESS; | |
} | |
Line = HMainEditor.BufferImage->CurrentLine; | |
OnlyLineRefresh = FALSE; | |
if ((Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) && (Line->Size + Count < 0x10)) { | |
// | |
// is at last line, and after paste will not exceed | |
// so only this line need to be refreshed | |
// | |
// if after add, the line is 0x10, then will append a new line | |
// so the whole page will need be refreshed | |
// | |
OnlyLineRefresh = TRUE; | |
} | |
FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1; | |
HBufferImageAddCharacterToBuffer (FPos, Count, Buffer); | |
if (OnlyLineRefresh) { | |
HBufferImageNeedRefresh = FALSE; | |
HBufferImageOnlyLineNeedRefresh = TRUE; | |
} else { | |
HBufferImageNeedRefresh = TRUE; | |
HBufferImageOnlyLineNeedRefresh = FALSE; | |
} | |
if (!HMainEditor.BufferImage->Modified) { | |
HMainEditor.BufferImage->Modified = TRUE; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Exit editor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandExit ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// Below is the scenario of Exit command: | |
// 1. IF currently opened file is not modified, exit the editor and | |
// Exit command ends. | |
// IF currently opened file is modified, do Step 2 | |
// | |
// 2. An Input Bar will be prompted: | |
// "File modified. Save ( Yes/No/Cancel )?" | |
// IF user press 'y' or 'Y', currently opened file will be saved and | |
// Editor exits | |
// IF user press 'n' or 'N', currently opened file will not be saved | |
// and Editor exits. | |
// IF user press 'c' or 'C' or ESC, Exit command ends. | |
// | |
// | |
// if file has been modified, so will prompt user | |
// whether to save the changes | |
// | |
if (HMainEditor.BufferImage->Modified) { | |
Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
// | |
// write file back to disk | |
// | |
Status = HBufferImageSave ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
HMainEditor.BufferImage->BufferType | |
); | |
if (!EFI_ERROR (Status)) { | |
HEditorExit = TRUE; | |
} | |
return Status; | |
case L'n': | |
case L'N': | |
HEditorExit = TRUE; | |
return EFI_SUCCESS; | |
case L'c': | |
case L'C': | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
HEditorExit = TRUE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Load a file from disk to editor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainCommandOpenFile ( | |
VOID | |
) | |
{ | |
BOOLEAN Done; | |
EFI_STATUS Status; | |
EDIT_FILE_TYPE BufferType; | |
BufferType = HMainEditor.BufferImage->BufferType; | |
// | |
// This command will open a file from current working directory. | |
// Read-only file can also be opened. But it can not be modified. | |
// Below is the scenario of Open File command: | |
// 1. IF currently opened file has not been modified, directly go to step . | |
// IF currently opened file has been modified, an Input Bar will be | |
// prompted as : | |
// "File Modified. Save ( Yes/No/Cancel) ?" | |
// IF user press 'y' or 'Y', currently opened file will be saved. | |
// IF user press 'n' or 'N', currently opened file will | |
// not be saved. | |
// IF user press 'c' or 'C' or ESC, Open File command ends and | |
// currently opened file is still opened. | |
// | |
// 2. An Input Bar will be prompted as : "File Name to Open: " | |
// IF user press ESC, Open File command ends and | |
// currently opened file is still opened. | |
// Any other inputs with a Return will cause | |
// currently opened file close. | |
// | |
// 3. IF user input file name is an existing file , | |
// this file will be read and opened. | |
// IF user input file name is a new file, this file will be created | |
// and opened. This file's type ( UNICODE or ASCII ) is the same with | |
// the old file. | |
// | |
// | |
// if current file is modified, so you need to choose whether to | |
// save it first. | |
// | |
if (HMainEditor.BufferImage->Modified) { | |
Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// the answer is just one character | |
// | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// loop for user's answer | |
// valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' | |
// | |
Done = FALSE; | |
while (!Done) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
// | |
// want to save this buffer first | |
// | |
Status = HBufferImageSave ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
HMainEditor.BufferImage->BufferType | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
MainTitleBarRefresh ( | |
HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL, | |
HMainEditor.BufferImage->BufferType, | |
HMainEditor.BufferImage->FileImage->ReadOnly, | |
FALSE, | |
HMainEditor.ScreenSize.Column, | |
HMainEditor.ScreenSize.Row, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0 | |
); | |
Done = TRUE; | |
break; | |
case L'n': | |
case L'N': | |
// | |
// the file won't be saved | |
// | |
Done = TRUE; | |
break; | |
case L'c': | |
case L'C': | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
// | |
// TO get the open file name | |
// | |
Status = InputBarSetPrompt (L"File Name to Open: "); | |
if (EFI_ERROR (Status)) { | |
HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return Status; | |
} | |
Status = InputBarSetStringSize (100); | |
if (EFI_ERROR (Status)) { | |
Status = HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
Status = HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return Status; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
// | |
// CHECK if filename's valid | |
// | |
if (!IsValidFileName (InputBarGetString ())) { | |
HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
StatusBarSetStatusString (L"Invalid File Name"); | |
return EFI_SUCCESS; | |
} | |
break; | |
} | |
} | |
// | |
// read from disk | |
// | |
Status = HBufferImageRead ( | |
InputBarGetString (), | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
FileTypeFileBuffer, | |
FALSE | |
); | |
if (EFI_ERROR (Status)) { | |
HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return EFI_LOAD_ERROR; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Load a disk buffer editor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
@retval EFI_NOT_FOUND The disk was not found. | |
**/ | |
EFI_STATUS | |
HMainCommandOpenDisk ( | |
VOID | |
) | |
{ | |
UINT64 Size; | |
UINT64 Offset; | |
CHAR16 *DeviceName; | |
EFI_STATUS Status; | |
BOOLEAN Done; | |
EDIT_FILE_TYPE BufferType; | |
// | |
// variable initialization | |
// | |
Size = 0; | |
Offset = 0; | |
BufferType = HMainEditor.BufferImage->BufferType; | |
// | |
// if current file is modified, so you need to choose | |
// whether to save it first. | |
// | |
if (HMainEditor.BufferImage->Modified) { | |
Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// the answer is just one character | |
// | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// loop for user's answer | |
// valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' | |
// | |
Done = FALSE; | |
while (!Done) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
// | |
// want to save this buffer first | |
// | |
Status = HBufferImageSave ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
MainTitleBarRefresh ( | |
HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL, | |
HMainEditor.BufferImage->BufferType, | |
HMainEditor.BufferImage->FileImage->ReadOnly, | |
FALSE, | |
HMainEditor.ScreenSize.Column, | |
HMainEditor.ScreenSize.Row, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0 | |
); | |
Done = TRUE; | |
break; | |
case L'n': | |
case L'N': | |
// | |
// the file won't be saved | |
// | |
Done = TRUE; | |
break; | |
case L'c': | |
case L'C': | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
// | |
// get disk block device name | |
// | |
Status = InputBarSetPrompt (L"Block Device to Open: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (100); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
break; | |
} | |
} | |
DeviceName = CatSPrint (NULL, L"%s", InputBarGetString ()); | |
if (DeviceName == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// | |
// get starting offset | |
// | |
Status = InputBarSetPrompt (L"First Block No.: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (16); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
break; | |
} | |
} | |
// | |
// get Number of Blocks: | |
// | |
Status = InputBarSetPrompt (L"Number of Blocks: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (8); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
Status = ShellConvertStringToUint64 (InputBarGetString (), &Size, TRUE, FALSE); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
if (Size == 0) { | |
continue; | |
} | |
break; | |
} | |
} | |
Status = HBufferImageRead ( | |
NULL, | |
DeviceName, | |
(UINTN)Offset, | |
(UINTN)Size, | |
0, | |
0, | |
FileTypeDiskBuffer, | |
FALSE | |
); | |
if (EFI_ERROR (Status)) { | |
HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return EFI_NOT_FOUND; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Load memory content to editor | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
@retval EFI_NOT_FOUND The disk was not found. | |
**/ | |
EFI_STATUS | |
HMainCommandOpenMemory ( | |
VOID | |
) | |
{ | |
UINT64 Size; | |
UINT64 Offset; | |
EFI_STATUS Status; | |
BOOLEAN Done; | |
EDIT_FILE_TYPE BufferType; | |
// | |
// variable initialization | |
// | |
Size = 0; | |
Offset = 0; | |
BufferType = HMainEditor.BufferImage->BufferType; | |
// | |
// if current buffer is modified, so you need to choose | |
// whether to save it first. | |
// | |
if (HMainEditor.BufferImage->Modified) { | |
Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// the answer is just one character | |
// | |
Status = InputBarSetStringSize (1); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// loop for user's answer | |
// valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C' | |
// | |
Done = FALSE; | |
while (!Done) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
switch (InputBarGetString ()[0]) { | |
case L'y': | |
case L'Y': | |
// | |
// want to save this buffer first | |
// | |
Status = HBufferImageSave ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
MainTitleBarRefresh ( | |
HMainEditor.BufferImage->BufferType == FileTypeFileBuffer ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Name : NULL, | |
HMainEditor.BufferImage->BufferType, | |
HMainEditor.BufferImage->FileImage->ReadOnly, | |
FALSE, | |
HMainEditor.ScreenSize.Column, | |
HMainEditor.ScreenSize.Row, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Offset : 0, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer ? HMainEditor.BufferImage->MemImage->Size : 0 | |
); | |
Done = TRUE; | |
break; | |
case L'n': | |
case L'N': | |
// | |
// the file won't be saved | |
// | |
Done = TRUE; | |
break; | |
case L'c': | |
case L'C': | |
return EFI_SUCCESS; | |
} | |
} | |
} | |
// | |
// get starting offset | |
// | |
Status = InputBarSetPrompt (L"Starting Offset: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (8); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
Status = ShellConvertStringToUint64 (InputBarGetString (), &Offset, TRUE, FALSE); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
break; | |
} | |
} | |
// | |
// get Number of Blocks: | |
// | |
Status = InputBarSetPrompt (L"Buffer Size: "); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = InputBarSetStringSize (8); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
while (1) { | |
Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column); | |
// | |
// ESC pressed | |
// | |
if (Status == EFI_NOT_READY) { | |
return EFI_SUCCESS; | |
} | |
// | |
// THE input string length should > 0 | |
// | |
if (StrLen (InputBarGetString ()) > 0) { | |
Status = ShellConvertStringToUint64 (InputBarGetString (), &Size, TRUE, FALSE); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
if (Size == 0) { | |
continue; | |
} | |
break; | |
} | |
} | |
if ((Offset + Size - 1) > 0xffffffff) { | |
StatusBarSetStatusString (L"Invalid parameter"); | |
return EFI_LOAD_ERROR; | |
} | |
Status = HBufferImageRead ( | |
NULL, | |
NULL, | |
0, | |
0, | |
(UINTN)Offset, | |
(UINTN)Size, | |
FileTypeMemBuffer, | |
FALSE | |
); | |
if (EFI_ERROR (Status)) { | |
StatusBarSetStatusString (L"Read Device Error!"); | |
HBufferImageRead ( | |
HMainEditor.BufferImage->FileImage->FileName, | |
HMainEditor.BufferImage->DiskImage->Name, | |
HMainEditor.BufferImage->DiskImage->Offset, | |
HMainEditor.BufferImage->DiskImage->Size, | |
HMainEditor.BufferImage->MemImage->Offset, | |
HMainEditor.BufferImage->MemImage->Size, | |
BufferType, | |
TRUE | |
); | |
return EFI_NOT_FOUND; | |
} | |
return EFI_SUCCESS; | |
} | |
MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = { | |
NULL, | |
NULL, /* Ctrl - A */ | |
NULL, /* Ctrl - B */ | |
NULL, /* Ctrl - C */ | |
HMainCommandSelectEnd, /* Ctrl - D */ | |
HMainCommandDisplayHelp, /* Ctrl - E */ | |
NULL, /* Ctrl - F */ | |
HMainCommandGoToOffset, /* Ctrl - G */ | |
NULL, /* Ctrl - H */ | |
HMainCommandOpenDisk, /* Ctrl - I */ | |
NULL, /* Ctrl - J */ | |
NULL, /* Ctrl - K */ | |
NULL, /* Ctrl - L */ | |
HMainCommandOpenMemory, /* Ctrl - M */ | |
NULL, /* Ctrl - N */ | |
HMainCommandOpenFile, /* Ctrl - O */ | |
NULL, /* Ctrl - P */ | |
HMainCommandExit, /* Ctrl - Q */ | |
NULL, /* Ctrl - R */ | |
HMainCommandSaveBuffer, /* Ctrl - S */ | |
HMainCommandSelectStart, /* Ctrl - T */ | |
NULL, /* Ctrl - U */ | |
HMainCommandPaste, /* Ctrl - V */ | |
NULL, /* Ctrl - W */ | |
HMainCommandCut, /* Ctrl - X */ | |
NULL, /* Ctrl - Y */ | |
NULL, /* Ctrl - Z */ | |
}; | |
CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = { | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F1), | |
HMainCommandGoToOffset | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F2), | |
HMainCommandSaveBuffer | |
}, | |
{ | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_EXIT), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F3), | |
HMainCommandExit | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SELECT_START), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F4), | |
HMainCommandSelectStart | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_SELECT_END), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F5), | |
HMainCommandSelectEnd | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_CUT), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F6), | |
HMainCommandCut | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_PASTE), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F7), | |
HMainCommandPaste | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_FILE), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F8), | |
HMainCommandOpenFile | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_DISK), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F9), | |
HMainCommandOpenDisk | |
}, | |
{ | |
STRING_TOKEN (STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY), | |
STRING_TOKEN (STR_EDIT_LIBMENUBAR_F10), | |
HMainCommandOpenMemory | |
}, | |
{ | |
0, | |
0, | |
NULL | |
} | |
}; | |
/** | |
Init function for MainEditor | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainEditorInit ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_HANDLE *HandleBuffer; | |
UINTN HandleCount; | |
UINTN Index; | |
// | |
// basic initialization | |
// | |
CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor)); | |
// | |
// set screen attributes | |
// | |
HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff; | |
HMainEditor.ColorAttributes.Colors.Background = (UINT8)(gST->ConOut->Mode->Attribute >> 4); | |
HOriginalColors = HMainEditor.ColorAttributes.Colors; | |
HOriginalMode = gST->ConOut->Mode->Mode; | |
// | |
// query screen size | |
// | |
gST->ConOut->QueryMode ( | |
gST->ConOut, | |
gST->ConOut->Mode->Mode, | |
&(HMainEditor.ScreenSize.Column), | |
&(HMainEditor.ScreenSize.Row) | |
); | |
// | |
// Find TextInEx in System Table ConsoleInHandle | |
// Per UEFI Spec, TextInEx is required for a console capable platform. | |
// | |
Status = gBS->HandleProtocol ( | |
gST->ConsoleInHandle, | |
&gEfiSimpleTextInputExProtocolGuid, | |
(VOID **)&HMainEditor.TextInputEx | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Find mouse in System Table ConsoleInHandle | |
// | |
Status = gBS->HandleProtocol ( | |
gST->ConsoleInHandle, | |
&gEfiSimplePointerProtocolGuid, | |
(VOID **)&HMainEditor.MouseInterface | |
); | |
if (EFI_ERROR (Status)) { | |
// | |
// If there is no Simple Pointer Protocol on System Table | |
// | |
HandleBuffer = NULL; | |
HMainEditor.MouseInterface = NULL; | |
Status = gBS->LocateHandleBuffer ( | |
ByProtocol, | |
&gEfiSimplePointerProtocolGuid, | |
NULL, | |
&HandleCount, | |
&HandleBuffer | |
); | |
if (!EFI_ERROR (Status) && (HandleCount > 0)) { | |
// | |
// Try to find the first available mouse device | |
// | |
for (Index = 0; Index < HandleCount; Index++) { | |
Status = gBS->HandleProtocol ( | |
HandleBuffer[Index], | |
&gEfiSimplePointerProtocolGuid, | |
(VOID **)&HMainEditor.MouseInterface | |
); | |
if (!EFI_ERROR (Status)) { | |
break; | |
} | |
} | |
} | |
if (HandleBuffer != NULL) { | |
FreePool (HandleBuffer); | |
} | |
} | |
if (!EFI_ERROR (Status) && (HMainEditor.MouseInterface != NULL)) { | |
HMainEditor.MouseAccumulatorX = 0; | |
HMainEditor.MouseAccumulatorY = 0; | |
HMainEditor.MouseSupported = TRUE; | |
} | |
// | |
// below will call the five components' init function | |
// | |
Status = MainTitleBarInit (L"UEFI HEXEDIT"); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
Status = MenuBarInit (HexEditorMenuItems); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
Status = StatusBarInit (); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
InputBarInit (HMainEditor.TextInputEx); | |
Status = HBufferImageInit (); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
Status = HClipBoardInit (); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle); | |
return EFI_LOAD_ERROR; | |
} | |
// | |
// clear whole screen and enable cursor | |
// | |
gST->ConOut->ClearScreen (gST->ConOut); | |
gST->ConOut->EnableCursor (gST->ConOut, TRUE); | |
// | |
// initialize EditorFirst and EditorExit | |
// | |
HEditorFirst = TRUE; | |
HEditorExit = FALSE; | |
HEditorMouseAction = FALSE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Cleanup function for MainEditor. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainEditorCleanup ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// call the five components' cleanup function | |
// | |
MainTitleBarCleanup (); | |
MenuBarCleanup (); | |
StatusBarCleanup (); | |
InputBarCleanup (); | |
Status = HBufferImageCleanup (); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle); | |
} | |
Status = HClipBoardCleanup (); | |
if (EFI_ERROR (Status)) { | |
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle); | |
} | |
// | |
// restore old mode | |
// | |
if (HOriginalMode != gST->ConOut->Mode->Mode) { | |
gST->ConOut->SetMode (gST->ConOut, HOriginalMode); | |
} | |
gST->ConOut->SetAttribute ( | |
gST->ConOut, | |
EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background) | |
); | |
gST->ConOut->ClearScreen (gST->ConOut); | |
return EFI_SUCCESS; | |
} | |
/** | |
Refresh function for MainEditor. | |
@retval EFI_SUCCESS The operation was successful. | |
**/ | |
EFI_STATUS | |
HMainEditorRefresh ( | |
VOID | |
) | |
{ | |
BOOLEAN NameChange; | |
BOOLEAN ReadChange; | |
NameChange = FALSE; | |
ReadChange = FALSE; | |
if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) { | |
if ((HMainEditor.BufferImage->DiskImage != NULL) && | |
(HBufferImageBackupVar.DiskImage != NULL) && | |
((HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset) || | |
(HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size))) | |
{ | |
NameChange = TRUE; | |
} | |
} else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) { | |
if ((HMainEditor.BufferImage->MemImage != NULL) && | |
(HBufferImageBackupVar.MemImage != NULL) && | |
((HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset) || | |
(HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size))) | |
{ | |
NameChange = TRUE; | |
} | |
} else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) { | |
if ((HMainEditor.BufferImage->FileImage != NULL) && | |
(HMainEditor.BufferImage->FileImage->FileName != NULL) && | |
(HBufferImageBackupVar.FileImage != NULL) && | |
(HBufferImageBackupVar.FileImage->FileName != NULL) && | |
(StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0)) | |
{ | |
NameChange = TRUE; | |
} | |
} | |
if ((HMainEditor.BufferImage->FileImage != NULL) && | |
(HBufferImageBackupVar.FileImage != NULL) && | |
(HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly)) | |
{ | |
ReadChange = TRUE; | |
} | |
// | |
// to aVOID screen flicker | |
// the stall value is from experience | |
// | |
gBS->Stall (50); | |
// | |
// call the components refresh function | |
// | |
if ( HEditorFirst | |
|| NameChange | |
|| (HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType) | |
|| (HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified) | |
|| ReadChange ) | |
{ | |
MainTitleBarRefresh ( | |
HMainEditor.BufferImage->BufferType == FileTypeFileBuffer && HMainEditor.BufferImage->FileImage != NULL ? HMainEditor.BufferImage->FileImage->FileName : HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Name : NULL, | |
HMainEditor.BufferImage->BufferType, | |
(BOOLEAN)(HMainEditor.BufferImage->FileImage != NULL ? HMainEditor.BufferImage->FileImage->ReadOnly : FALSE), | |
HMainEditor.BufferImage->Modified, | |
HMainEditor.ScreenSize.Column, | |
HMainEditor.ScreenSize.Row, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Offset : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer && HMainEditor.BufferImage->MemImage != NULL ? HMainEditor.BufferImage->MemImage->Offset : 0, | |
HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer && HMainEditor.BufferImage->DiskImage != NULL ? HMainEditor.BufferImage->DiskImage->Size : HMainEditor.BufferImage->BufferType == FileTypeMemBuffer && HMainEditor.BufferImage->MemImage != NULL ? HMainEditor.BufferImage->MemImage->Size : 0 | |
); | |
HBufferImageRefresh (); | |
} | |
if ( HEditorFirst | |
|| (HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row) | |
|| (HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column) | |
|| StatusBarGetRefresh ()) | |
{ | |
StatusBarRefresh ( | |
HEditorFirst, | |
HMainEditor.ScreenSize.Row, | |
HMainEditor.ScreenSize.Column, | |
(UINTN)(-1), | |
(UINTN)(-1), | |
FALSE | |
); | |
HBufferImageRefresh (); | |
} | |
if (HEditorFirst) { | |
HBufferImageRefresh (); | |
} | |
// | |
// EditorFirst is now set to FALSE | |
// | |
HEditorFirst = FALSE; | |
return EFI_SUCCESS; | |
} | |
/** | |
Handle the mouse input. | |
@param[in] MouseState The current mouse state. | |
@param[out] BeforeLeftButtonDown helps with selections. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
@retval EFI_NOT_FOUND The disk was not found. | |
**/ | |
EFI_STATUS | |
HMainEditorHandleMouseInput ( | |
IN EFI_SIMPLE_POINTER_STATE MouseState, | |
OUT BOOLEAN *BeforeLeftButtonDown | |
) | |
{ | |
INT32 TextX; | |
INT32 TextY; | |
UINTN FRow; | |
UINTN FCol; | |
BOOLEAN HighBits; | |
LIST_ENTRY *Link; | |
HEFI_EDITOR_LINE *Line; | |
UINTN Index; | |
BOOLEAN Action; | |
Action = FALSE; | |
// | |
// have mouse movement | |
// | |
if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) { | |
// | |
// handle | |
// | |
TextX = HGetTextX (MouseState.RelativeMovementX); | |
TextY = HGetTextY (MouseState.RelativeMovementY); | |
HBufferImageAdjustMousePosition (TextX, TextY); | |
Action = TRUE; | |
} | |
if (MouseState.LeftButton) { | |
HighBits = HBufferImageIsAtHighBits ( | |
HMainEditor.BufferImage->MousePosition.Column, | |
&FCol | |
); | |
// | |
// not at an movable place | |
// | |
if (FCol == 0) { | |
// | |
// now just move mouse pointer to legal position | |
// | |
// | |
// move mouse position to legal position | |
// | |
HMainEditor.BufferImage->MousePosition.Column -= 10; | |
if (HMainEditor.BufferImage->MousePosition.Column > 24) { | |
HMainEditor.BufferImage->MousePosition.Column--; | |
FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1; | |
} else { | |
if (HMainEditor.BufferImage->MousePosition.Column < 24) { | |
FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1; | |
} else { | |
// | |
// == 24 | |
// | |
FCol = 9; | |
} | |
} | |
HighBits = TRUE; | |
} | |
FRow = HMainEditor.BufferImage->BufferPosition.Row + | |
HMainEditor.BufferImage->MousePosition.Row - | |
HMainEditor.BufferImage->DisplayPosition.Row; | |
if (HMainEditor.BufferImage->NumLines < FRow) { | |
// | |
// dragging | |
// | |
// | |
// now just move mouse pointer to legal position | |
// | |
FRow = HMainEditor.BufferImage->NumLines; | |
HighBits = TRUE; | |
} | |
Link = HMainEditor.BufferImage->ListHead->ForwardLink; | |
for (Index = 0; Index < FRow - 1; Index++) { | |
Link = Link->ForwardLink; | |
} | |
Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST); | |
// | |
// dragging | |
// | |
// | |
// now just move mouse pointer to legal position | |
// | |
if (FCol > Line->Size) { | |
if (*BeforeLeftButtonDown) { | |
HighBits = FALSE; | |
if (Line->Size == 0) { | |
if (FRow > 1) { | |
FRow--; | |
FCol = 16; | |
} else { | |
FRow = 1; | |
FCol = 1; | |
} | |
} else { | |
FCol = Line->Size; | |
} | |
} else { | |
FCol = Line->Size + 1; | |
HighBits = TRUE; | |
} | |
} | |
HBufferImageMovePosition (FRow, FCol, HighBits); | |
HMainEditor.BufferImage->MousePosition.Row = HMainEditor.BufferImage->DisplayPosition.Row; | |
HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column; | |
*BeforeLeftButtonDown = TRUE; | |
Action = TRUE; | |
} else { | |
// | |
// else of if LButton | |
// | |
// release LButton | |
// | |
if (*BeforeLeftButtonDown) { | |
Action = TRUE; | |
} | |
// | |
// mouse up | |
// | |
*BeforeLeftButtonDown = FALSE; | |
} | |
if (Action) { | |
return EFI_SUCCESS; | |
} | |
return EFI_NOT_FOUND; | |
} | |
/** | |
Handle user key input. will route it to other components handle function. | |
@retval EFI_SUCCESS The operation was successful. | |
@retval EFI_OUT_OF_RESOURCES A memory allocation occurred. | |
@retval EFI_LOAD_ERROR A load error occurred. | |
**/ | |
EFI_STATUS | |
HMainEditorKeyInput ( | |
VOID | |
) | |
{ | |
EFI_KEY_DATA KeyData; | |
EFI_STATUS Status; | |
EFI_SIMPLE_POINTER_STATE MouseState; | |
BOOLEAN NoShiftState; | |
BOOLEAN LengthChange; | |
UINTN Size; | |
UINTN OldSize; | |
BOOLEAN BeforeMouseIsDown; | |
BOOLEAN MouseIsDown; | |
BOOLEAN FirstDown; | |
BOOLEAN MouseDrag; | |
UINTN FRow; | |
UINTN FCol; | |
UINTN SelectStartBackup; | |
UINTN SelectEndBackup; | |
// | |
// variable initialization | |
// | |
OldSize = 0; | |
FRow = 0; | |
FCol = 0; | |
LengthChange = FALSE; | |
MouseIsDown = FALSE; | |
FirstDown = FALSE; | |
MouseDrag = FALSE; | |
do { | |
Status = EFI_SUCCESS; | |
HEditorMouseAction = FALSE; | |
// | |
// backup some key elements, so that can aVOID some refresh work | |
// | |
HMainEditorBackup (); | |
// | |
// wait for user key input | |
// | |
// | |
// change priority of checking mouse/keyboard activity dynamically | |
// so prevent starvation of keyboard. | |
// if last time, mouse moves then this time check keyboard | |
// | |
if (HMainEditor.MouseSupported) { | |
Status = HMainEditor.MouseInterface->GetState ( | |
HMainEditor.MouseInterface, | |
&MouseState | |
); | |
if (!EFI_ERROR (Status)) { | |
BeforeMouseIsDown = MouseIsDown; | |
Status = HMainEditorHandleMouseInput (MouseState, &MouseIsDown); | |
if (!EFI_ERROR (Status)) { | |
if (!BeforeMouseIsDown) { | |
// | |
// mouse down | |
// | |
if (MouseIsDown) { | |
FRow = HBufferImage.BufferPosition.Row; | |
FCol = HBufferImage.BufferPosition.Column; | |
SelectStartBackup = HMainEditor.SelectStart; | |
SelectEndBackup = HMainEditor.SelectEnd; | |
FirstDown = TRUE; | |
} | |
} else { | |
SelectStartBackup = HMainEditor.SelectStart; | |
SelectEndBackup = HMainEditor.SelectEnd; | |
// | |
// begin to drag | |
// | |
if (MouseIsDown) { | |
if (FirstDown) { | |
if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) { | |
HMainEditor.SelectStart = 0; | |
HMainEditor.SelectEnd = 0; | |
HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol; | |
MouseDrag = TRUE; | |
FirstDown = FALSE; | |
} | |
} else { | |
if (( | |
(HBufferImage.BufferPosition.Row - 1) * | |
0x10 + | |
HBufferImage.BufferPosition.Column | |
) >= HMainEditor.SelectStart | |
) | |
{ | |
HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) * | |
0x10 + | |
HBufferImage.BufferPosition.Column; | |
} else { | |
HMainEditor.SelectEnd = 0; | |
} | |
} | |
// | |
// end of if RelativeX/Y | |
// | |
} else { | |
// | |
// mouse is up | |
// | |
if (MouseDrag) { | |
if (HBufferImageGetTotalSize () == 0) { | |
HMainEditor.SelectStart = 0; | |
HMainEditor.SelectEnd = 0; | |
FirstDown = FALSE; | |
MouseDrag = FALSE; | |
} | |
if (( | |
(HBufferImage.BufferPosition.Row - 1) * | |
0x10 + | |
HBufferImage.BufferPosition.Column | |
) >= HMainEditor.SelectStart | |
) | |
{ | |
HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) * | |
0x10 + | |
HBufferImage.BufferPosition.Column; | |
} else { | |
HMainEditor.SelectEnd = 0; | |
} | |
if (HMainEditor.SelectEnd == 0) { | |
HMainEditor.SelectStart = 0; | |
} | |
} | |
FirstDown = FALSE; | |
MouseDrag = FALSE; | |
} | |
if ((SelectStartBackup != HMainEditor.SelectStart) || (SelectEndBackup != HMainEditor.SelectEnd)) { | |
if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) { | |
HBufferImageNeedRefresh = TRUE; | |
} else { | |
if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) { | |
HBufferImageNeedRefresh = TRUE; | |
} else { | |
HBufferImageOnlyLineNeedRefresh = TRUE; | |
} | |
} | |
} | |
} | |
HEditorMouseAction = TRUE; | |
HBufferImageMouseNeedRefresh = TRUE; | |
} else if (Status == EFI_LOAD_ERROR) { | |
StatusBarSetStatusString (L"Invalid Mouse Movement "); | |
} | |
} | |
} | |
// | |
// CheckEvent() returns Success when non-partial key is pressed. | |
// | |
Status = gBS->CheckEvent (HMainEditor.TextInputEx->WaitForKeyEx); | |
if (!EFI_ERROR (Status)) { | |
Status = HMainEditor.TextInputEx->ReadKeyStrokeEx (HMainEditor.TextInputEx, &KeyData); | |
if (!EFI_ERROR (Status)) { | |
// | |
// dispatch to different components' key handling function | |
// so not everywhere has to set this variable | |
// | |
HBufferImageMouseNeedRefresh = TRUE; | |
// | |
// clear previous status string | |
// | |
StatusBarSetRefresh (); | |
// | |
// NoShiftState: TRUE when no shift key is pressed. | |
// | |
NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID); | |
// | |
// dispatch to different components' key handling function | |
// | |
if (EFI_SUCCESS == MenuBarDispatchControlHotKey (&KeyData)) { | |
Status = EFI_SUCCESS; | |
} else if (NoShiftState && (KeyData.Key.ScanCode == SCAN_NULL)) { | |
Status = HBufferImageHandleInput (&KeyData.Key); | |
} else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) { | |
Status = HBufferImageHandleInput (&KeyData.Key); | |
} else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12))) { | |
Status = MenuBarDispatchFunctionKey (&KeyData.Key); | |
} else { | |
StatusBarSetStatusString (L"Unknown Command"); | |
HBufferImageMouseNeedRefresh = FALSE; | |
} | |
if ((Status != EFI_SUCCESS) && (Status != EFI_OUT_OF_RESOURCES)) { | |
// | |
// not already has some error status | |
// | |
if (StrCmp (L"", StatusBarGetString ()) == 0) { | |
StatusBarSetStatusString (L"Disk Error. Try Again"); | |
} | |
} | |
} | |
// | |
// decide if has to set length warning | |
// | |
if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) { | |
LengthChange = FALSE; | |
} else { | |
// | |
// still the old buffer | |
// | |
if (HBufferImage.BufferType != FileTypeFileBuffer) { | |
Size = HBufferImageGetTotalSize (); | |
switch (HBufferImage.BufferType) { | |
case FileTypeDiskBuffer: | |
OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize; | |
break; | |
case FileTypeMemBuffer: | |
OldSize = HBufferImage.MemImage->Size; | |
break; | |
default: | |
OldSize = 0; | |
break; | |
} | |
if (!LengthChange) { | |
if (OldSize != Size) { | |
StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed"); | |
} | |
} | |
if (OldSize != Size) { | |
LengthChange = TRUE; | |
} else { | |
LengthChange = FALSE; | |
} | |
} | |
} | |
} | |
// | |
// after handling, refresh editor | |
// | |
HMainEditorRefresh (); | |
} while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit); | |
return Status; | |
} | |
/** | |
Backup function for MainEditor. | |
**/ | |
VOID | |
HMainEditorBackup ( | |
VOID | |
) | |
{ | |
HMainEditorBackupVar.SelectStart = HMainEditor.SelectStart; | |
HMainEditorBackupVar.SelectEnd = HMainEditor.SelectEnd; | |
HBufferImageBackup (); | |
} |