USB mouse cursor cannot move unless the left button is down. The patch refresh the FileBuffer of Editor every time when the 'MainEditorRefresh' is called to fix this bug. Cc: Jaben Carsey <jaben.carsey@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qiu Shumin <shumin.qiu@intel.com>
		
			
				
	
	
		
			1937 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1937 lines
		
	
	
		
			49 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Implements editor interface functions.
 | 
						|
 | 
						|
  Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved. <BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "TextEditor.h"
 | 
						|
#include "EditStatusBar.h"
 | 
						|
#include "EditInputBar.h"
 | 
						|
#include "EditMenuBar.h"
 | 
						|
 | 
						|
//
 | 
						|
// the first time editor launch
 | 
						|
//
 | 
						|
BOOLEAN                       EditorFirst;
 | 
						|
 | 
						|
//
 | 
						|
// it's time editor should exit
 | 
						|
//
 | 
						|
BOOLEAN                       EditorExit;
 | 
						|
 | 
						|
BOOLEAN                       EditorMouseAction;
 | 
						|
 | 
						|
extern EFI_EDITOR_FILE_BUFFER FileBuffer;
 | 
						|
 | 
						|
extern BOOLEAN                FileBufferNeedRefresh;
 | 
						|
 | 
						|
extern BOOLEAN                FileBufferOnlyLineNeedRefresh;
 | 
						|
 | 
						|
extern BOOLEAN                FileBufferMouseNeedRefresh;
 | 
						|
 | 
						|
extern EFI_EDITOR_FILE_BUFFER FileBufferBackupVar;
 | 
						|
 | 
						|
EFI_EDITOR_GLOBAL_EDITOR      MainEditor;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Load a file from disk to editor
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandOpenFile (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Switch a file from ASCII to UNICODE or vise-versa.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The switch was ok or a warning was presented.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSwitchFileType (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  move cursor to specified lines
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandGotoLine (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Save current file to disk, you can save to current file name or
 | 
						|
  save to another file name.
 | 
						|
  
 | 
						|
  @retval EFI_SUCCESS           The file was saved correctly.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A file access error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSaveFile (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Show help information for the editor.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandDisplayHelp (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  exit editor
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandExit (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  search string in file buffer
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSearch (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  search string in file buffer, and replace it with another str
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSearchReplace (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  cut current line to clipboard
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandCutLine (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  paste line to file buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandPasteLine (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Help info that will be displayed.
 | 
						|
**/
 | 
						|
EFI_STRING_ID  MainMenuHelpInfo[] = {
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_TITLE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_LIST_TITLE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_DIV),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_GO_TO_LINE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_SAVE_FILE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_EXIT),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_SEARCH),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_SEARCH_REPLACE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_CUT_LINE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_PASTE_LINE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_OPEN_FILE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_FILE_TYPE),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_EXIT_HELP),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_BLANK),
 | 
						|
  STRING_TOKEN(STR_EDIT_HELP_DIV),
 | 
						|
0
 | 
						|
};
 | 
						|
 | 
						|
MENU_ITEM_FUNCTION MainControlBasedMenuFunctions[] = {
 | 
						|
  NULL,
 | 
						|
  NULL,                      /* Ctrl - A */
 | 
						|
  NULL,                      /* Ctrl - B */
 | 
						|
  NULL,                      /* Ctrl - C */
 | 
						|
  NULL,                      /* Ctrl - D */
 | 
						|
  MainCommandDisplayHelp,    /* Ctrl - E */
 | 
						|
  MainCommandSearch,         /* Ctrl - F */
 | 
						|
  MainCommandGotoLine,       /* Ctrl - G */
 | 
						|
  NULL,                      /* Ctrl - H */
 | 
						|
  NULL,                      /* Ctrl - I */
 | 
						|
  NULL,                      /* Ctrl - J */
 | 
						|
  MainCommandCutLine,        /* Ctrl - K */
 | 
						|
  NULL,                      /* Ctrl - L */
 | 
						|
  NULL,                      /* Ctrl - M */
 | 
						|
  NULL,                      /* Ctrl - N */
 | 
						|
  MainCommandOpenFile,       /* Ctrl - O */
 | 
						|
  NULL,                      /* Ctrl - P */
 | 
						|
  MainCommandExit,           /* Ctrl - Q */
 | 
						|
  MainCommandSearchReplace,  /* Ctrl - R */
 | 
						|
  MainCommandSaveFile,       /* Ctrl - S */
 | 
						|
  MainCommandSwitchFileType, /* Ctrl - T */
 | 
						|
  MainCommandPasteLine,      /* Ctrl - U */
 | 
						|
  NULL,                      /* Ctrl - V */
 | 
						|
  NULL,                      /* Ctrl - W */
 | 
						|
  NULL,                      /* Ctrl - X */
 | 
						|
  NULL,                      /* Ctrl - Y */
 | 
						|
  NULL,                      /* Ctrl - Z */
 | 
						|
};
 | 
						|
 | 
						|
EDITOR_MENU_ITEM  MainMenuItems[] = {
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_GO_TO_LINE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
 | 
						|
    MainCommandGotoLine
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_SAVE_FILE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
 | 
						|
    MainCommandSaveFile
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
 | 
						|
    MainCommandExit
 | 
						|
  },
 | 
						|
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
 | 
						|
    MainCommandSearch
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_SEARCH_REPLACE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
 | 
						|
    MainCommandSearchReplace
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_CUT_LINE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
 | 
						|
    MainCommandCutLine
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_PASTE_LINE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
 | 
						|
    MainCommandPasteLine
 | 
						|
  },
 | 
						|
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_OPEN_FILE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
 | 
						|
    MainCommandOpenFile
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
 | 
						|
    MainCommandSwitchFileType
 | 
						|
  },
 | 
						|
  {
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_FILE_TYPE),
 | 
						|
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F11),
 | 
						|
    MainCommandSwitchFileType
 | 
						|
  },
 | 
						|
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    0,
 | 
						|
    NULL
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Load a file from disk to editor
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandOpenFile (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN     Done;
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  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 (MainEditor.FileBuffer->FileModified) {
 | 
						|
 | 
						|
    Status = InputBarSetPrompt (L"File 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 (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // ESC pressed
 | 
						|
      //
 | 
						|
      if (Status == EFI_NOT_READY) {
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      switch (InputBarGetString()[0]) {
 | 
						|
      case L'y':
 | 
						|
      case L'Y':
 | 
						|
        //
 | 
						|
        // want to save this file first
 | 
						|
        //
 | 
						|
        Status = FileBufferSave (MainEditor.FileBuffer->FileName);
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          return Status;
 | 
						|
        }
 | 
						|
 | 
						|
        MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
 | 
						|
        FileBufferRestorePosition ();
 | 
						|
        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)) {
 | 
						|
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarSetStringSize (100);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  while (1) {
 | 
						|
    Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
    StatusBarSetRefresh();
 | 
						|
 | 
						|
    //
 | 
						|
    // ESC pressed
 | 
						|
    //
 | 
						|
    if (Status == EFI_NOT_READY) {
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // The input string length should > 0
 | 
						|
    //
 | 
						|
    if (StrLen (InputBarGetString()) > 0) {
 | 
						|
      //
 | 
						|
      // CHECK if filename is valid
 | 
						|
      //
 | 
						|
      if (!IsValidFileName (InputBarGetString())) {
 | 
						|
        FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
 | 
						|
        StatusBarSetStatusString (L"Invalid File Name");
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // read from disk
 | 
						|
  //
 | 
						|
  Status = FileBufferRead (InputBarGetString(), FALSE);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Switch a file from ASCII to UNICODE or vise-versa.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The switch was ok or a warning was presented.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSwitchFileType (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Below is the scenario of File Type command:
 | 
						|
  // After File Type is executed, file type will be changed to another type
 | 
						|
  // if file is read-only, can not be modified
 | 
						|
  //
 | 
						|
  if (MainEditor.FileBuffer->ReadOnly) {
 | 
						|
    StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
 | 
						|
    MainEditor.FileBuffer->FileType = FileTypeAscii;
 | 
						|
  } else {
 | 
						|
    MainEditor.FileBuffer->FileType = FileTypeUnicode;
 | 
						|
  }
 | 
						|
 | 
						|
  MainEditor.FileBuffer->FileModified = TRUE;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  cut current line to clipboard
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandCutLine (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  EFI_EDITOR_LINE *Line;
 | 
						|
 | 
						|
  //
 | 
						|
  // This command will cut current line ( where cursor is on ) to clip board.
 | 
						|
  //      And cursor will move to the beginning of next line.
 | 
						|
  // Below is the scenario of Cut Line command:
 | 
						|
  // 1.  IF cursor is on valid line, current line will be cut to clip board.
 | 
						|
  //     IF cursor is not on valid line, an Status String will be prompted :
 | 
						|
  //        "Nothing to Cut".
 | 
						|
  //
 | 
						|
  Line = NULL;
 | 
						|
  Status = FileBufferCutLine (&Line);
 | 
						|
  if (Status == EFI_NOT_FOUND) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  MainEditor.CutLine = Line;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  paste line to file buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandPasteLine (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // Below is the scenario of Paste Line command:
 | 
						|
  // 1.  IF nothing is on clipboard, a Status String will be prompted :
 | 
						|
  //        "No Line to Paste" and Paste Line command ends.
 | 
						|
  //     IF something is on clipboard, insert it above current line.
 | 
						|
  // nothing on clipboard
 | 
						|
  //
 | 
						|
  if (MainEditor.CutLine == NULL) {
 | 
						|
    StatusBarSetStatusString (L"No Line to Paste");
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = FileBufferPasteLine ();
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  search string in file buffer
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSearch (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  CHAR16      *Buffer;
 | 
						|
  BOOLEAN     Done;
 | 
						|
  UINTN       Offset;
 | 
						|
 | 
						|
  //
 | 
						|
  // Below is the scenario of Search command:
 | 
						|
  // 1.  An Input Bar will be prompted : "Enter Search String:".
 | 
						|
  //       IF user press ESC, Search command ends.
 | 
						|
  //       IF user just press Enter, Search command ends.
 | 
						|
  //       IF user inputs the search string,  do Step 2.
 | 
						|
  //
 | 
						|
  // 2.  IF input search string is found, cursor will move to the first
 | 
						|
  //        occurrence and do Step 3.
 | 
						|
  //     IF input search string is not found, a Status String
 | 
						|
  //        "Search String Not Found" will be prompted and Search command ends.
 | 
						|
  //
 | 
						|
  // 3.  An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?".
 | 
						|
  //      IF user press ESC, Search command ends.
 | 
						|
  //       IF user press 'y' or 'Y', do Step 2.
 | 
						|
  //       IF user press 'n' or 'N', Search command ends.
 | 
						|
  //       IF user press 'c' or 'C', Search command ends.
 | 
						|
  //
 | 
						|
  Status = InputBarSetPrompt (L"Enter Search String: ");
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarSetStringSize (40);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
  StatusBarSetRefresh();
 | 
						|
 | 
						|
  //
 | 
						|
  // ESC
 | 
						|
  //
 | 
						|
  if (Status == EFI_NOT_READY) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // just enter pressed
 | 
						|
  //
 | 
						|
  if (StrLen (InputBarGetString()) == 0) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Buffer = CatSPrint (NULL, L"%s", InputBarGetString());
 | 
						|
  if (Buffer == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // the first time , search from current position
 | 
						|
  //
 | 
						|
  Offset = 0;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // since search may be continued to search multiple times
 | 
						|
    // so we need to backup editor each time
 | 
						|
    //
 | 
						|
    MainEditorBackup ();
 | 
						|
 | 
						|
    Status = FileBufferSearch (Buffer, Offset);
 | 
						|
 | 
						|
    if (Status == EFI_NOT_FOUND) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Find next
 | 
						|
    //
 | 
						|
    Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Buffer);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = InputBarSetStringSize (1);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Buffer);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Done = FALSE;
 | 
						|
    while (!Done) {
 | 
						|
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // ESC pressed
 | 
						|
      //
 | 
						|
      if (Status == EFI_NOT_READY) {
 | 
						|
        FreePool (Buffer);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      switch (InputBarGetString()[0]) {
 | 
						|
      case L'y':
 | 
						|
      case L'Y':
 | 
						|
        Done = TRUE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case L'n':
 | 
						|
      case L'N':
 | 
						|
        FreePool (Buffer);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // end of which
 | 
						|
      //
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of while !Done
 | 
						|
    // for search second, third time, search from current position + strlen
 | 
						|
    //
 | 
						|
    Offset = StrLen (Buffer);
 | 
						|
 | 
						|
  } while (1);
 | 
						|
  //
 | 
						|
  // end of do
 | 
						|
  //
 | 
						|
  FreePool (Buffer);
 | 
						|
  StatusBarSetStatusString (L"Search String Not Found");
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Search string in file buffer, and replace it with another str.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSearchReplace (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  CHAR16      *Search;
 | 
						|
  CHAR16      *Replace;
 | 
						|
  BOOLEAN     Done;
 | 
						|
  BOOLEAN     First;
 | 
						|
  BOOLEAN     ReplaceOption;
 | 
						|
  UINTN       SearchLen;
 | 
						|
  UINTN       ReplaceLen;
 | 
						|
  BOOLEAN     ReplaceAll;
 | 
						|
 | 
						|
  ReplaceOption = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Below is the scenario of Search/Replace command:
 | 
						|
  // 1.  An Input Bar is prompted : "Enter Search String:".
 | 
						|
  //       IF user press ESC, Search/Replace command ends.
 | 
						|
  //       IF user just press Enter, Search/Replace command ends.
 | 
						|
  //       IF user inputs the search string S, do Step 2.
 | 
						|
  //
 | 
						|
  // 2.  An Input Bar is prompted: "Replace With:".
 | 
						|
  //       IF user press ESC, Search/Replace command ends.
 | 
						|
  //      IF user inputs the replace string R, do Step 3.
 | 
						|
  //
 | 
						|
  // 3.  IF input search string is not found, an Status String
 | 
						|
  //        "Search String Not Found" will be prompted
 | 
						|
  //        and Search/Replace command ends
 | 
						|
  //     IF input search string is found, do Step 4.
 | 
						|
  //
 | 
						|
  // 4.  An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?"
 | 
						|
  //       IF user press 'y' or 'Y', S will be replaced with R and do Step 5
 | 
						|
  //       IF user press 'n' or 'N', S will not be replaced and do Step 5.
 | 
						|
  //       IF user press 'a' or 'A', all the S from file current position on
 | 
						|
  //          will be replaced with R and Search/Replace command ends.
 | 
						|
  //       IF user press 'c' or 'C' or ESC, Search/Replace command ends.
 | 
						|
  //
 | 
						|
  // 5.  An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?".
 | 
						|
  //       IF user press ESC, Search/Replace command ends.
 | 
						|
  //       IF user press 'y' or 'Y', do Step 3.
 | 
						|
  //       IF user press 'n' or 'N', Search/Replace command ends.
 | 
						|
  //       IF user press 'c' or 'C', Search/Replace command ends.
 | 
						|
  // input search string
 | 
						|
  //
 | 
						|
  Status = InputBarSetPrompt (L"Enter Search String: ");
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarSetStringSize (40);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
  StatusBarSetRefresh();
 | 
						|
 | 
						|
  //
 | 
						|
  // ESC
 | 
						|
  //
 | 
						|
  if (Status == EFI_NOT_READY) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // if just pressed enter
 | 
						|
  //
 | 
						|
  if (StrLen (InputBarGetString()) == 0) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Search = CatSPrint (NULL, L"%s", InputBarGetString());
 | 
						|
  if (Search == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  SearchLen = StrLen (Search);
 | 
						|
 | 
						|
  //
 | 
						|
  // input replace string
 | 
						|
  //
 | 
						|
  Status = InputBarSetPrompt (L"Replace With: ");
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarSetStringSize (40);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
  StatusBarSetRefresh();
 | 
						|
 | 
						|
  //
 | 
						|
  // ESC
 | 
						|
  //
 | 
						|
  if (Status == EFI_NOT_READY) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Replace = CatSPrint (NULL, L"%s", InputBarGetString());
 | 
						|
  if (Replace == NULL) {
 | 
						|
    FreePool (Search);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  ReplaceLen  = StrLen (Replace);
 | 
						|
 | 
						|
  First       = TRUE;
 | 
						|
  ReplaceAll  = FALSE;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // since search may be continued to search multiple times
 | 
						|
    // so we need to backup editor each time
 | 
						|
    //
 | 
						|
    MainEditorBackup ();
 | 
						|
 | 
						|
    if (First) {
 | 
						|
      Status = FileBufferSearch (Search, 0);
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // if just replace, so skip this replace string
 | 
						|
      // if replace string is an empty string, so skip to next character
 | 
						|
      //
 | 
						|
      if (ReplaceOption) {
 | 
						|
        Status = FileBufferSearch (Search, (ReplaceLen == 0) ? 1 : ReplaceLen);
 | 
						|
      } else {
 | 
						|
        Status = FileBufferSearch (Search, SearchLen);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (Status == EFI_NOT_FOUND) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // replace or not?
 | 
						|
    //
 | 
						|
    Status = InputBarSetPrompt (L"Replace (Yes/No/All/Cancel) ?");
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Search);
 | 
						|
      FreePool (Replace);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = InputBarSetStringSize (1);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Search);
 | 
						|
      FreePool (Replace);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Done = FALSE;
 | 
						|
    while (!Done) {
 | 
						|
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // ESC pressed
 | 
						|
      //
 | 
						|
      if (Status == EFI_NOT_READY) {
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      switch (InputBarGetString()[0]) {
 | 
						|
      case L'y':
 | 
						|
      case L'Y':
 | 
						|
        Done          = TRUE;
 | 
						|
        ReplaceOption = TRUE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case L'n':
 | 
						|
      case L'N':
 | 
						|
        Done          = TRUE;
 | 
						|
        ReplaceOption = FALSE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case L'a':
 | 
						|
      case L'A':
 | 
						|
        Done          = TRUE;
 | 
						|
        ReplaceOption = TRUE;
 | 
						|
        ReplaceAll    = TRUE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case L'c':
 | 
						|
      case L'C':
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // end of which
 | 
						|
      //
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of while !Done
 | 
						|
    // Decide to Replace
 | 
						|
    //
 | 
						|
    if (ReplaceOption) {
 | 
						|
      //
 | 
						|
      // file is read-only
 | 
						|
      //
 | 
						|
      if (MainEditor.FileBuffer->ReadOnly) {
 | 
						|
        StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // replace all
 | 
						|
      //
 | 
						|
      if (ReplaceAll) {
 | 
						|
        Status = FileBufferReplaceAll (Search, Replace, 0);
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return Status;
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // replace
 | 
						|
      //
 | 
						|
      Status = FileBufferReplace (Replace, SearchLen);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return Status;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Find next
 | 
						|
    //
 | 
						|
    Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Search);
 | 
						|
      FreePool (Replace);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = InputBarSetStringSize (1);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      FreePool (Search);
 | 
						|
      FreePool (Replace);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Done = FALSE;
 | 
						|
    while (!Done) {
 | 
						|
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // ESC pressed
 | 
						|
      //
 | 
						|
      if (Status == EFI_NOT_READY) {
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      switch (InputBarGetString()[0]) {
 | 
						|
      case L'y':
 | 
						|
      case L'Y':
 | 
						|
        Done = TRUE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case L'n':
 | 
						|
      case L'N':
 | 
						|
        FreePool (Search);
 | 
						|
        FreePool (Replace);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // end of which
 | 
						|
      //
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // end of while !Done
 | 
						|
    //
 | 
						|
    First = FALSE;
 | 
						|
 | 
						|
  } while (1);
 | 
						|
  //
 | 
						|
  // end of do
 | 
						|
  //
 | 
						|
  FreePool (Search);
 | 
						|
  FreePool (Replace);
 | 
						|
 | 
						|
  StatusBarSetStatusString (L"Search String Not Found");
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  exit editor
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandExit (
 | 
						|
  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 (MainEditor.FileBuffer->FileModified) {
 | 
						|
 | 
						|
    Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = InputBarSetStringSize (1);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    while (1) {
 | 
						|
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // 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 = FileBufferSave (MainEditor.FileBuffer->FileName);
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          EditorExit = TRUE;
 | 
						|
        }
 | 
						|
 | 
						|
        return Status;
 | 
						|
 | 
						|
      case L'n':
 | 
						|
      case L'N':
 | 
						|
        EditorExit = TRUE;
 | 
						|
        return EFI_SUCCESS;
 | 
						|
 | 
						|
      case L'c':
 | 
						|
      case L'C':
 | 
						|
        return EFI_SUCCESS;
 | 
						|
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  EditorExit = TRUE;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  move cursor to specified lines
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandGotoLine (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINTN       Row;
 | 
						|
 | 
						|
  //
 | 
						|
  // Below is the scenario of Go To Line command:
 | 
						|
  // 1.  An Input Bar will be prompted : "Go To Line:".
 | 
						|
  //       IF user press ESC, Go To Line command ends.
 | 
						|
  //       IF user just press Enter, cursor remains unchanged.
 | 
						|
  //       IF user inputs line number, do Step 2.
 | 
						|
  //
 | 
						|
  // 2.  IF input line number is valid, move cursor to the beginning
 | 
						|
  //        of specified line and Go To Line command ends.
 | 
						|
  //    IF input line number is invalid, a Status String will be prompted:
 | 
						|
  //        "No Such Line" and Go To Line command ends.
 | 
						|
  //
 | 
						|
  Status = InputBarSetPrompt (L"Go To Line: ");
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // line number's digit <= 6
 | 
						|
  //
 | 
						|
  Status = InputBarSetStringSize (6);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
  StatusBarSetRefresh();
 | 
						|
 | 
						|
  //
 | 
						|
  // press ESC
 | 
						|
  //
 | 
						|
  if (Status == EFI_NOT_READY) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // if JUST press enter
 | 
						|
  //
 | 
						|
  if (StrLen (InputBarGetString()) == 0) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Row = ShellStrToUintn (InputBarGetString());
 | 
						|
 | 
						|
  //
 | 
						|
  // invalid line number
 | 
						|
  //
 | 
						|
  if (Row > MainEditor.FileBuffer->NumLines || Row <= 0) {
 | 
						|
    StatusBarSetStatusString (L"No Such Line");
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // move cursor to that line's start
 | 
						|
  //
 | 
						|
  FileBufferMovePosition (Row, 1);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Save current file to disk, you can save to current file name or
 | 
						|
  save to another file name.
 | 
						|
  
 | 
						|
  @retval EFI_SUCCESS           The file was saved correctly.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | 
						|
  @retval EFI_LOAD_ERROR          A file access error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandSaveFile (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  CHAR16            *FileName;
 | 
						|
  BOOLEAN           OldFile;
 | 
						|
  CHAR16            *Str;
 | 
						|
  SHELL_FILE_HANDLE FileHandle;  
 | 
						|
  EFI_FILE_INFO     *Info;
 | 
						|
 | 
						|
  //
 | 
						|
  // 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]", MainEditor.FileBuffer->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] = CHAR_NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = InputBarSetPrompt (Str);
 | 
						|
  FreePool(Str);
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  Status = InputBarSetStringSize (100);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // get new file name
 | 
						|
  //
 | 
						|
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
  StatusBarSetRefresh();
 | 
						|
 | 
						|
  //
 | 
						|
  // if user pressed ESC
 | 
						|
  //
 | 
						|
  if (Status == EFI_NOT_READY) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // if just enter pressed, so think save to current file name
 | 
						|
  //
 | 
						|
  if (StrLen (InputBarGetString()) == 0) {
 | 
						|
    FileName = CatSPrint (NULL, L"%s", MainEditor.FileBuffer->FileName);
 | 
						|
  } else {
 | 
						|
    FileName = CatSPrint (NULL, L"%s", InputBarGetString());
 | 
						|
  }
 | 
						|
 | 
						|
  if (FileName == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!IsValidFileName (FileName)) {
 | 
						|
    StatusBarSetStatusString (L"Invalid File Name");
 | 
						|
    FreePool (FileName);
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  OldFile = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // save to the old file
 | 
						|
  //
 | 
						|
  if (StringNoCaseCompare (&FileName, &MainEditor.FileBuffer->FileName) == 0) {
 | 
						|
    OldFile = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (OldFile) {
 | 
						|
    //
 | 
						|
    // if the file is read only, so can not write back to it.
 | 
						|
    //
 | 
						|
    if (MainEditor.FileBuffer->ReadOnly == TRUE) {
 | 
						|
      StatusBarSetStatusString (L"Access Denied");
 | 
						|
      FreePool (FileName);
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // if the file exists
 | 
						|
    //
 | 
						|
    if (ShellFileExists(FileName) != EFI_NOT_FOUND) {
 | 
						|
      //
 | 
						|
      // check for read only
 | 
						|
      //
 | 
						|
      Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
 | 
						|
      if (EFI_ERROR(Status)) {
 | 
						|
        StatusBarSetStatusString (L"Open Failed");
 | 
						|
        FreePool (FileName);
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      } 
 | 
						|
 | 
						|
      Info = ShellGetFileInfo(FileHandle);
 | 
						|
      if (Info == NULL) {
 | 
						|
        StatusBarSetStatusString (L"Access Denied");
 | 
						|
        FreePool (FileName);
 | 
						|
        return (EFI_SUCCESS);
 | 
						|
      } 
 | 
						|
      
 | 
						|
      if (Info->Attribute & EFI_FILE_READ_ONLY) {
 | 
						|
        StatusBarSetStatusString (L"Access Denied - Read Only");
 | 
						|
        FreePool (Info);
 | 
						|
        FreePool (FileName);
 | 
						|
        return (EFI_SUCCESS);
 | 
						|
      }
 | 
						|
      FreePool (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;
 | 
						|
      }
 | 
						|
 | 
						|
      while (TRUE) {
 | 
						|
        Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
 | 
						|
        StatusBarSetRefresh();
 | 
						|
 | 
						|
        //
 | 
						|
        // ESC pressed
 | 
						|
        //
 | 
						|
        if (Status == EFI_NOT_READY) {
 | 
						|
          SHELL_FREE_NON_NULL (FileName);
 | 
						|
          return EFI_SUCCESS;
 | 
						|
        }
 | 
						|
 | 
						|
        switch (InputBarGetString()[0]) {
 | 
						|
        case L'y':
 | 
						|
        case L'Y':
 | 
						|
          break;
 | 
						|
 | 
						|
        case L'n':
 | 
						|
        case L'N':
 | 
						|
        case L'c':
 | 
						|
        case L'C':
 | 
						|
          SHELL_FREE_NON_NULL (FileName);
 | 
						|
          return EFI_SUCCESS;
 | 
						|
        } // end switch
 | 
						|
      } // while (!done)
 | 
						|
    } // file does exist
 | 
						|
  } // if old file name same
 | 
						|
 | 
						|
  //
 | 
						|
  // save file to disk with specified name
 | 
						|
  //
 | 
						|
  FileBufferSetModified();
 | 
						|
  Status = FileBufferSave (FileName);
 | 
						|
  SHELL_FREE_NON_NULL (FileName);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Show help information for the editor.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
MainCommandDisplayHelp (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  INT32           CurrentLine;
 | 
						|
  CHAR16          *InfoString;
 | 
						|
  EFI_INPUT_KEY   Key;
 | 
						|
  
 | 
						|
  //
 | 
						|
  // print helpInfo      
 | 
						|
  //
 | 
						|
  for (CurrentLine = 0; 0 != MainMenuHelpInfo[CurrentLine]; CurrentLine++) {
 | 
						|
    InfoString = HiiGetString(gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL);
 | 
						|
    ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);        
 | 
						|
  }
 | 
						|
  
 | 
						|
  //
 | 
						|
  // scan for ctrl+w
 | 
						|
  //
 | 
						|
  do {
 | 
						|
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
  } while(SCAN_CONTROL_W != Key.UnicodeChar); 
 | 
						|
 | 
						|
  //
 | 
						|
  // update screen with file buffer's info
 | 
						|
  //
 | 
						|
  FileBufferRestorePosition ();
 | 
						|
  FileBufferNeedRefresh = TRUE;
 | 
						|
  FileBufferOnlyLineNeedRefresh = FALSE;
 | 
						|
  FileBufferRefresh ();  
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_EDITOR_COLOR_ATTRIBUTES   OriginalColors;
 | 
						|
INTN                          OriginalMode;
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// basic initialization for MainEditor
 | 
						|
//
 | 
						|
EFI_EDITOR_GLOBAL_EDITOR      MainEditorConst = {
 | 
						|
  &FileBuffer,
 | 
						|
  {
 | 
						|
    {0, 0}
 | 
						|
  },
 | 
						|
  {
 | 
						|
    0,
 | 
						|
    0
 | 
						|
  },
 | 
						|
  NULL,
 | 
						|
  FALSE,
 | 
						|
  NULL
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  The initialization function for MainEditor.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorInit (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  EFI_HANDLE  *HandleBuffer;
 | 
						|
  UINTN       HandleCount;
 | 
						|
  UINTN       Index;
 | 
						|
 | 
						|
  //
 | 
						|
  // basic initialization
 | 
						|
  //
 | 
						|
  CopyMem (&MainEditor, &MainEditorConst, sizeof (MainEditor));
 | 
						|
 | 
						|
  //
 | 
						|
  // set screen attributes
 | 
						|
  //
 | 
						|
  MainEditor.ColorAttributes.Colors.Foreground  = gST->ConOut->Mode->Attribute & 0x000000ff;
 | 
						|
 | 
						|
  MainEditor.ColorAttributes.Colors.Background  = (UINT8) (gST->ConOut->Mode->Attribute >> 4);
 | 
						|
  OriginalColors = MainEditor.ColorAttributes.Colors;
 | 
						|
 | 
						|
  OriginalMode = gST->ConOut->Mode->Mode;
 | 
						|
 | 
						|
  //
 | 
						|
  // query screen size
 | 
						|
  //
 | 
						|
  gST->ConOut->QueryMode (
 | 
						|
        gST->ConOut,
 | 
						|
        gST->ConOut->Mode->Mode,
 | 
						|
        &(MainEditor.ScreenSize.Column),
 | 
						|
        &(MainEditor.ScreenSize.Row)
 | 
						|
        );
 | 
						|
 | 
						|
  //
 | 
						|
  // Find mouse in System Table ConsoleInHandle
 | 
						|
  //
 | 
						|
  Status = gBS->HandleProtocol (
 | 
						|
                gST->ConIn,
 | 
						|
                &gEfiSimplePointerProtocolGuid,
 | 
						|
                (VOID**)&MainEditor.MouseInterface
 | 
						|
                );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // If there is no Simple Pointer Protocol on System Table
 | 
						|
    //
 | 
						|
    HandleBuffer = NULL;
 | 
						|
    MainEditor.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**)&MainEditor.MouseInterface
 | 
						|
                      );
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (HandleBuffer != NULL) {
 | 
						|
      FreePool (HandleBuffer);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status) && MainEditor.MouseInterface != NULL) {
 | 
						|
    MainEditor.MouseAccumulatorX  = 0;
 | 
						|
    MainEditor.MouseAccumulatorY  = 0;
 | 
						|
    MainEditor.MouseSupported     = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // below will call the five components' init function
 | 
						|
  //
 | 
						|
  Status = MainTitleBarInit (L"UEFI EDIT");
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_TITLEBAR), gShellDebug1HiiHandle);
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = ControlHotKeyInit (MainControlBasedMenuFunctions);
 | 
						|
  Status = MenuBarInit (MainMenuItems);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_MAINMENU), gShellDebug1HiiHandle);
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = StatusBarInit ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_STATUSBAR), gShellDebug1HiiHandle);
 | 
						|
    return EFI_LOAD_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  InputBarInit ();
 | 
						|
 | 
						|
  Status = FileBufferInit ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER), 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
 | 
						|
  //
 | 
						|
  EditorFirst       = TRUE;
 | 
						|
  EditorExit        = FALSE;
 | 
						|
  EditorMouseAction = FALSE;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The cleanup function for MainEditor.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorCleanup (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  //
 | 
						|
  // call the five components' cleanup function
 | 
						|
  // if error, do not exit
 | 
						|
  // just print some warning
 | 
						|
  //
 | 
						|
  MainTitleBarCleanup();
 | 
						|
  StatusBarCleanup();
 | 
						|
  InputBarCleanup();
 | 
						|
  MenuBarCleanup ();
 | 
						|
 | 
						|
  Status = FileBufferCleanup ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP), gShellDebug1HiiHandle);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // restore old mode
 | 
						|
  //
 | 
						|
  if (OriginalMode != gST->ConOut->Mode->Mode) {
 | 
						|
    gST->ConOut->SetMode (gST->ConOut, OriginalMode);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // restore old screen color
 | 
						|
  //
 | 
						|
  gST->ConOut->SetAttribute (
 | 
						|
        gST->ConOut,
 | 
						|
        EFI_TEXT_ATTR (OriginalColors.Foreground, OriginalColors.Background)
 | 
						|
        );
 | 
						|
 | 
						|
  gST->ConOut->ClearScreen (gST->ConOut);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Refresh the main editor component.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
MainEditorRefresh (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // The Stall value is from experience. NOT from spec.  avoids 'flicker'
 | 
						|
  //
 | 
						|
  gBS->Stall (50);
 | 
						|
 | 
						|
  //
 | 
						|
  // call the components refresh function
 | 
						|
  //
 | 
						|
  if (EditorFirst 
 | 
						|
    || StrCmp (FileBufferBackupVar.FileName, FileBuffer.FileName) != 0 
 | 
						|
    || FileBufferBackupVar.FileType != FileBuffer.FileType 
 | 
						|
    || FileBufferBackupVar.FileModified != FileBuffer.FileModified 
 | 
						|
    || FileBufferBackupVar.ReadOnly != FileBuffer.ReadOnly) {
 | 
						|
 | 
						|
    MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
 | 
						|
    FileBufferRestorePosition ();
 | 
						|
  }
 | 
						|
 | 
						|
  if (EditorFirst
 | 
						|
    || FileBufferBackupVar.FilePosition.Row != FileBuffer.FilePosition.Row 
 | 
						|
    || FileBufferBackupVar.FilePosition.Column != FileBuffer.FilePosition.Column 
 | 
						|
    || FileBufferBackupVar.ModeInsert != FileBuffer.ModeInsert
 | 
						|
    || StatusBarGetRefresh()) {
 | 
						|
 | 
						|
    StatusBarRefresh (EditorFirst, MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column, MainEditor.FileBuffer->FilePosition.Row, MainEditor.FileBuffer->FilePosition.Column, MainEditor.FileBuffer->ModeInsert);
 | 
						|
    FileBufferRestorePosition ();
 | 
						|
  }
 | 
						|
 | 
						|
  if (EditorFirst) {
 | 
						|
    FileBufferRestorePosition ();
 | 
						|
  }
 | 
						|
 | 
						|
  FileBufferRefresh ();
 | 
						|
 | 
						|
  //
 | 
						|
  // EditorFirst is now set to FALSE
 | 
						|
  //
 | 
						|
  EditorFirst = FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get's the resultant location of the cursor based on the relative movement of the Mouse.
 | 
						|
 | 
						|
  @param[in] GuidX    The relative mouse movement.
 | 
						|
 | 
						|
  @return The X location of the mouse.
 | 
						|
**/
 | 
						|
INT32
 | 
						|
EFIAPI
 | 
						|
GetTextX (
 | 
						|
  IN INT32 GuidX
 | 
						|
  )
 | 
						|
{
 | 
						|
  INT32 Gap;
 | 
						|
 | 
						|
  MainEditor.MouseAccumulatorX += GuidX;
 | 
						|
  Gap = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);
 | 
						|
  MainEditor.MouseAccumulatorX = (MainEditor.MouseAccumulatorX * (INT32) MainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionX);
 | 
						|
  MainEditor.MouseAccumulatorX = MainEditor.MouseAccumulatorX / (INT32) MainEditor.ScreenSize.Column;
 | 
						|
  return Gap;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get's the resultant location of the cursor based on the relative movement of the Mouse.
 | 
						|
 | 
						|
  @param[in] GuidY    The relative mouse movement.
 | 
						|
 | 
						|
  @return The Y location of the mouse.
 | 
						|
**/
 | 
						|
INT32
 | 
						|
EFIAPI
 | 
						|
GetTextY (
 | 
						|
  IN INT32 GuidY
 | 
						|
  )
 | 
						|
{
 | 
						|
  INT32 Gap;
 | 
						|
 | 
						|
  MainEditor.MouseAccumulatorY += GuidY;
 | 
						|
  Gap = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);
 | 
						|
  MainEditor.MouseAccumulatorY = (MainEditor.MouseAccumulatorY * (INT32) MainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) MainEditor.MouseInterface->Mode->ResolutionY);
 | 
						|
  MainEditor.MouseAccumulatorY = MainEditor.MouseAccumulatorY / (INT32) MainEditor.ScreenSize.Row;
 | 
						|
 | 
						|
  return Gap;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Support mouse movement.  Move the cursor.
 | 
						|
 | 
						|
  @param[in] MouseState     The current mouse state.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The operation was successful.
 | 
						|
  @retval EFI_NOT_FOUND     There was no mouse support found.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorHandleMouseInput (
 | 
						|
  IN EFI_SIMPLE_POINTER_STATE       MouseState
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  INT32           TextX;
 | 
						|
  INT32           TextY;
 | 
						|
  UINTN           FRow;
 | 
						|
  UINTN           FCol;
 | 
						|
 | 
						|
  LIST_ENTRY  *Link;
 | 
						|
  EFI_EDITOR_LINE *Line;
 | 
						|
 | 
						|
  UINTN           Index;
 | 
						|
  BOOLEAN         Action;
 | 
						|
 | 
						|
  //
 | 
						|
  // mouse action means:
 | 
						|
  //    mouse movement
 | 
						|
  //    mouse left button
 | 
						|
  //
 | 
						|
  Action = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // have mouse movement
 | 
						|
  //
 | 
						|
  if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
 | 
						|
    //
 | 
						|
    // handle
 | 
						|
    //
 | 
						|
    TextX = GetTextX (MouseState.RelativeMovementX);
 | 
						|
    TextY = GetTextY (MouseState.RelativeMovementY);
 | 
						|
 | 
						|
    FileBufferAdjustMousePosition (TextX, TextY);
 | 
						|
 | 
						|
    Action = TRUE;
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // if left button pushed down
 | 
						|
  //
 | 
						|
  if (MouseState.LeftButton) {
 | 
						|
 | 
						|
    FCol = MainEditor.FileBuffer->MousePosition.Column - 1 + 1;
 | 
						|
 | 
						|
    FRow = MainEditor.FileBuffer->FilePosition.Row +
 | 
						|
      MainEditor.FileBuffer->MousePosition.Row -
 | 
						|
      MainEditor.FileBuffer->DisplayPosition.Row;
 | 
						|
 | 
						|
    //
 | 
						|
    // beyond the file line length
 | 
						|
    //
 | 
						|
    if (MainEditor.FileBuffer->NumLines < FRow) {
 | 
						|
      FRow = MainEditor.FileBuffer->NumLines;
 | 
						|
    }
 | 
						|
 | 
						|
    Link = MainEditor.FileBuffer->ListHead->ForwardLink;
 | 
						|
    for (Index = 0; Index < FRow - 1; Index++) {
 | 
						|
      Link = Link->ForwardLink;
 | 
						|
    }
 | 
						|
 | 
						|
    Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
 | 
						|
 | 
						|
    //
 | 
						|
    // beyond the line's column length
 | 
						|
    //
 | 
						|
    if (FCol > Line->Size + 1) {
 | 
						|
      FCol = Line->Size + 1;
 | 
						|
    }
 | 
						|
 | 
						|
    FileBufferMovePosition (FRow, FCol);
 | 
						|
 | 
						|
    MainEditor.FileBuffer->MousePosition.Row    = MainEditor.FileBuffer->DisplayPosition.Row;
 | 
						|
 | 
						|
    MainEditor.FileBuffer->MousePosition.Column = MainEditor.FileBuffer->DisplayPosition.Column;
 | 
						|
 | 
						|
    Action = TRUE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // mouse has action
 | 
						|
  //
 | 
						|
  if (Action) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // no mouse action
 | 
						|
  //
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Handle user key input. This routes to other functions for the actions.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_LOAD_ERROR          A load error occured.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorKeyInput (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_INPUT_KEY             Key;
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  EFI_SIMPLE_POINTER_STATE  MouseState;
 | 
						|
 | 
						|
  do {
 | 
						|
 | 
						|
    Status            = EFI_SUCCESS;
 | 
						|
    EditorMouseAction = FALSE;
 | 
						|
 | 
						|
    //
 | 
						|
    // backup some key elements, so that can aVOID some refresh work
 | 
						|
    //
 | 
						|
    MainEditorBackup ();
 | 
						|
 | 
						|
    //
 | 
						|
    // change priority of checking mouse/keyboard activity dynamically
 | 
						|
    // so prevent starvation of keyboard.
 | 
						|
    // if last time, mouse moves then this time check keyboard
 | 
						|
    //
 | 
						|
    if (MainEditor.MouseSupported) {
 | 
						|
      Status = MainEditor.MouseInterface->GetState (
 | 
						|
                                            MainEditor.MouseInterface,
 | 
						|
                                            &MouseState
 | 
						|
                                            );
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
 | 
						|
        Status = MainEditorHandleMouseInput (MouseState);
 | 
						|
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          EditorMouseAction           = TRUE;
 | 
						|
          FileBufferMouseNeedRefresh  = TRUE;
 | 
						|
        } else if (Status == EFI_LOAD_ERROR) {
 | 
						|
          StatusBarSetStatusString (L"Invalid Mouse Movement ");
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // dispatch to different components' key handling function
 | 
						|
      // so not everywhere has to set this variable
 | 
						|
      //
 | 
						|
      FileBufferMouseNeedRefresh = TRUE;
 | 
						|
      //
 | 
						|
      // clear previous status string
 | 
						|
      //
 | 
						|
      StatusBarSetRefresh();
 | 
						|
 | 
						|
      //
 | 
						|
      // dispatch to different components' key handling function
 | 
						|
      //
 | 
						|
      if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&Key)) {
 | 
						|
        Status = EFI_SUCCESS;
 | 
						|
      } else if ((Key.ScanCode == SCAN_NULL) || ((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
 | 
						|
        Status = FileBufferHandleInput (&Key);
 | 
						|
      } else if ((Key.ScanCode >= SCAN_F1) && (Key.ScanCode <= SCAN_F12)) {
 | 
						|
        Status = MenuBarDispatchFunctionKey (&Key);
 | 
						|
      } else {
 | 
						|
        StatusBarSetStatusString (L"Unknown Command");
 | 
						|
        FileBufferMouseNeedRefresh = FALSE;  
 | 
						|
      }
 | 
						|
      
 | 
						|
      if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
 | 
						|
        //
 | 
						|
        // not already has some error status
 | 
						|
        //
 | 
						|
        if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) {
 | 
						|
          StatusBarSetStatusString (L"Disk Error. Try Again");
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // after handling, refresh editor
 | 
						|
    //
 | 
						|
    MainEditorRefresh ();
 | 
						|
 | 
						|
  } while (Status != EFI_OUT_OF_RESOURCES && !EditorExit);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set clipboard
 | 
						|
 | 
						|
  @param[in] Line   A pointer to the line to be set to clipboard
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The operation was successful.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorSetCutLine (
 | 
						|
  EFI_EDITOR_LINE *Line
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Line == NULL) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  if (MainEditor.CutLine != NULL) {
 | 
						|
    //
 | 
						|
    // free the old clipboard
 | 
						|
    //
 | 
						|
    LineFree (MainEditor.CutLine);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // duplicate the line to clipboard
 | 
						|
  //
 | 
						|
  MainEditor.CutLine = LineDup (Line);
 | 
						|
  if (MainEditor.CutLine == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Backup function for MainEditor
 | 
						|
 | 
						|
  @retval EFI_SUCCESS The operation was successful.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
MainEditorBackup (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  FileBufferBackup ();
 | 
						|
  
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 |