consplitter.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,473 行 · 第 1/5 页

C
2,473
字号
    }
    Index --;
    TextOutList ++;
  }

  //
  // The specified TextOut is not managed by the ConSplitter driver
  //
  if ( Index < 0 ) {
    return EFI_NOT_FOUND;
  }

  if ( CurrentNumOfConsoles == 0 ) {
    //
    // If the number of consoles is zero clear the Dev NULL device
    //
    Private->CurrentNumberOfConsoles = 0;
    Private->TextOutMode.MaxMode = 1;
    Private->TextOutQueryData[0].Columns = 80;
    Private->TextOutQueryData[0].Rows = 25;
    DevNullTextOutSetMode (Private, 0);

    return EFI_SUCCESS;
  }

  //
  // Max Mode is realy an intersection of the QueryMode command to all
  // devices. So we must copy the QueryMode of the first device to
  // QueryData.
  //
  EfiZeroMem (
    Private->TextOutQueryData, 
    Private->TextOutQueryDataCount * sizeof(TEXT_OUT_SPLITTER_QUERY_DATA)
    );

  gBS->FreePool (Private->TextOutModeMap);
  Private->TextOutModeMap           = NULL;
  TextOutList                       = Private->TextOutList;

  //
  // Add the first TextOut to the QueryData array and ModeMap table
  //
  Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);

  //
  // Now add one by one
  //
  Index                             = 1;
  Private->CurrentNumberOfConsoles  = 1;
  TextOutList ++;
  while ( (UINTN)Index < CurrentNumOfConsoles ) {
    ConSplitterSyncOutputMode (Private, TextOutList->TextOut);
    Index ++;
    Private->CurrentNumberOfConsoles ++;
    TextOutList ++;
  }

  ConSplitterGetIntersectionBetweenConOutAndStrErr();

  return Status;
}


//
// ConSplitter TextIn member functions
//

EFI_STATUS 
EFIAPI
ConSplitterTextInReset (
  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,
  IN  BOOLEAN                         ExtendedVerification
  )
/*++

  Routine Description:
    Reset the input device and optionaly run diagnostics

  Arguments:
    This                 - Protocol instance pointer.
    ExtendedVerification - Driver may perform diagnostics on reset.

  Returns:
    EFI_SUCCES            - The device was reset.
    EFI_DEVICE_ERROR      - The device is not functioning properly and could 
                            not be reset.

--*/
{
  EFI_STATUS                          Status;
  EFI_STATUS                          ReturnStatus;
  TEXT_IN_SPLITTER_PRIVATE_DATA       *Private;
  UINTN                               Index;

  Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
  
  //
  // return the worst status met
  //
  for ( Index = 0, ReturnStatus = EFI_SUCCESS;
          Index < Private->CurrentNumberOfConsoles; Index ++ ) {
    Status  = Private->TextInList[Index]->Reset (
                        Private->TextInList[Index],
                        ExtendedVerification
                        );
    if (EFI_ERROR (Status)) {
      ReturnStatus = Status;
    }
  }

  return ReturnStatus;
}

EFI_STATUS 
EFIAPI
ConSplitterTextInPrivateReadKeyStroke (
  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,
  OUT EFI_INPUT_KEY                   *Key
  )
/*++

  Routine Description:
    Reads the next keystroke from the input device. The WaitForKey Event can 
    be used to test for existance of a keystroke via WaitForEvent () call.

  Arguments:
    This   - Protocol instance pointer.
    Key    - Driver may perform diagnostics on reset.

  Returns:
    EFI_SUCCES        - The keystroke information was returned.
    EFI_NOT_READY     - There was no keystroke data availiable.
    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 
                        hardware errors.

--*/
{
  EFI_STATUS                          Status;
  UINTN                               Index;
  EFI_INPUT_KEY                       CurrentKey;
    
  Key->UnicodeChar = 0;
  Key->ScanCode    = SCAN_NULL;
  
  //
  // if no physical console input device exists, return EFI_NOT_READY;
  // if any physical console input device has key input, 
  // return the key and EFI_SUCCESS.
  //
  for ( Index = 0; Index < Private->CurrentNumberOfConsoles; Index ++ ) {
    Status  = Private->TextInList[Index]->ReadKeyStroke (
                        Private->TextInList[Index],
                        &CurrentKey
                        );
    if (!EFI_ERROR (Status)) {
      *Key = CurrentKey;
      return Status;
    }
  }
  
  return EFI_NOT_READY;
}

BOOLEAN
ConSpliterConssoleControlStdInLocked (
  VOID
  )
/*++

Routine Description:
  Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
  the only device locked.

Arguments:
  NONE

Returns:
  TRUE  - StdIn locked
  FALSE - StdIn working normally

--*/
{
  return mConIn.PasswordEnabled;                
}

VOID 
EFIAPI
ConSpliterConsoleControlLockStdInEvent (
  IN  EFI_EVENT                       Event,
  IN  VOID                            *Context
  )
/*++

Routine Description:
  This timer event will fire when StdIn is locked. It will check the key 
  sequence on StdIn to see if it matches the password. Any error in the
  password will cause the check to reset. As long a mConIn.PasswordEnabled is
  TRUE the StdIn splitter will not report any input.

Arguments:
  (Standard EFI_EVENT_NOTIFY)
  
Returns:
  None

--*/
{
  EFI_STATUS      Status;
  EFI_INPUT_KEY   Key;

  do {
    Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);
    if (!EFI_ERROR (Status)) {
      //
      // if it's an ENTER, match password
      //
      if ( (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)
        && (Key.ScanCode == SCAN_NULL) ) {
        mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;
        if ( EfiStrCmp(mConIn.Password, mConIn.PwdAttempt) ) {
          //
          // Password not match
          //
          ConSplitterTextOutOutputString (&mConOut.TextOut, L"\n\rPassword not correct\n\r");
          mConIn.PwdIndex = 0;
        } else {
          //
          // Key matches password sequence
          //
          gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);
          mConIn.PasswordEnabled = FALSE;
          Status = EFI_NOT_READY;
        }
      } else {
        //
        // If it's not an ENTER, record the input
        //
        if ( mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1) ) {
          if ( mConIn.PwdIndex == 0 ) {
            ConSplitterTextOutOutputString (&mConOut.TextOut, L"\n\r");
          }
          ConSplitterTextOutOutputString (&mConOut.TextOut, L"*");
          mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;
          mConIn.PwdIndex++;
        }
      }
    }
  } while (!EFI_ERROR (Status));
}

EFI_STATUS
EFIAPI
ConSpliterConsoleControlLockStdIn (
  IN  EFI_CONSOLE_CONTROL_PROTOCOL    *This,
  IN  CHAR16                          *Password
  )
/*++

Routine Description:
  If Password is NULL unlock the password state variable and set the event 
  timer. If the Password is too big return an error. If the Password is valid
  Copy the Password and enable state variable and then arm the periodic timer

Arguments:

Returns:
  EFI_SUCCESS           - Lock the StdIn device
  EFI_INVALID_PARAMETER - Password is NULL
  EFI_OUT_OF_RESOURCES  - Buffer allocation to store the password fails

--*/
{
  if (Password == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (EfiStrLen (Password) >= MAX_STD_IN_PASSWORD) {
    //
    // Currently have a max password size
    //
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Save the password, initialize state variables and arm event timer
  //
  EfiStrCpy (mConIn.Password, Password);
  mConIn.PasswordEnabled  = TRUE;
  mConIn.PwdIndex         = 0;
  gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
ConSplitterTextInReadKeyStroke (
  IN  EFI_SIMPLE_TEXT_IN_PROTOCOL     *This,
  OUT EFI_INPUT_KEY                   *Key
  )
/*++

  Routine Description:
    Reads the next keystroke from the input device. The WaitForKey Event can 
    be used to test for existance of a keystroke via WaitForEvent () call.
    If the ConIn is password locked make it look like no keystroke is availible

  Arguments:
    This   - Protocol instance pointer.
    Key    - Driver may perform diagnostics on reset.

  Returns:
    EFI_SUCCES        - The keystroke information was returned.
    EFI_NOT_READY     - There was no keystroke data availiable.
    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 
                        hardware errors.

--*/
{
  TEXT_IN_SPLITTER_PRIVATE_DATA       *Private;
 
  Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
  if (Private->PasswordEnabled) {
    //
    // If StdIn Locked return not ready
    //
    return EFI_NOT_READY;
  }
  
  return ConSplitterTextInPrivateReadKeyStroke (Private, Key);
}

VOID 
EFIAPI
ConSplitterTextInWaitForKey (
  IN  EFI_EVENT                       Event,
  IN  VOID                            *Context
  )
/*++

Routine Description:
  This event agregates all the events of the ConIn devices in the spliter.
  If the ConIn is password locked then return.
  If any events of physical ConIn devices are signaled, signal the ConIn
  spliter event. This will cause the calling code to call 
  ConSplitterTextInReadKeyStroke ().

Arguments:
  Event   - The Event assoicated with callback.
  Context - Context registered when Event was created.

Returns:
  None

--*/
{
  EFI_STATUS                          Status;
  TEXT_IN_SPLITTER_PRIVATE_DATA       *Private;
  UINTN                               Index;

  Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *)Context;
  if (Private->PasswordEnabled) {
    //
    // If StdIn Locked return not ready
    //
    return;
  }

  //
  // if any physical console input device has key input, signal the event. 
  //
  for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
    Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);
    if (!EFI_ERROR (Status)) {
      gBS->SignalEvent (Event);
    }
  }
}



EFI_STATUS 
EFIAPI
ConSplitterSimplePointerReset (
  IN  EFI_SIMPLE_POINTER_PROTOCOL     *This,
  IN  BOOLEAN                         ExtendedVerification
  )
/*++

  Routine Description:
    Reset the input device and optionaly run diagnostics

  Arguments:
    This                 - Protocol instance pointer.
    ExtendedVerification - Driver may perform diagnostics on reset.

  Returns:
    EFI_SUCCES            - The device was reset.
    EFI_DEVICE_ERROR      - The device is not functioning properly and could 
                            not be reset.

--*/
{
  EFI_STATUS                          Status;
  EFI_STATUS                          ReturnStatus;
  TEXT_IN_SPLITTER_PRIVATE_DATA       *Private;
  UINTN                               Index;

  Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);
  
  if (Private->CurrentNumberOfPointers == 0) {
    return EFI_SUCCESS;
  }
  
  //
  // return the worst status met
  //
  for (Index = 0, ReturnStatus = EFI_SUCCESS; 
        Index < Private->CurrentNumberOfPointers; Index++ ) {
    Status = Private->PointerList[Index]->Reset (
                                      Private->PointerList[Index], 
                                      ExtendedVerification
                                      );
    if (EFI_ERROR (Status)) {
      ReturnStatus = Status;
    }
  }
  
  return ReturnStatus;
}

EFI_STATUS 
EFIAPI
ConSplitterSimplePointerPrivateGetState (
  IN  TEXT_IN_SPLITTER_PRIVATE_DATA   *Private,
  IN OUT EFI_SIMPLE_POINTER_STATE     *State
  )
/*++

  Routine Description:
    Reads the next keystroke from the input device. The WaitForKey Event can 
    be used to test for existance of a keystroke via WaitForEvent () call.

  Arguments:
    This   - Protocol instance pointer.
    State  - 

  Returns:
    EFI_SUCCES        - The keystroke information was returned.
    EFI_NOT_READY     - There was no keystroke data availiable.
    EFI_DEVICE_ERROR  - The keydtroke information was not returned due to 
                        hardware errors.

--*/
{
  EFI_STATUS                          Status;
  EFI_STATUS                          ReturnStatus;
  UINTN                               Index;
  EFI_SIMPLE_POINTER_STATE            CurrentState;

  State->RelativeMovementX = 0;
  State->RelativeMovementY = 0;
  State->RelativeMovementZ = 0;
  State->LeftButton        = FALSE;
  State->RightButton       = FALSE;
  
  //
  // if no physical console input device exists, return EFI_NOT_READY;
  // if any physical console input device has key input, 
  // return the key and EFI_SUCCESS.
  //
  ReturnStatus = EFI_NOT_READY;
  for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++ ) {
          
    Status = Private->PointerList[Index]->GetState (
                                            Private->PointerList[Index], 
                                            &CurrentState
                                            );
    if (!EFI_ERROR (Status)) {
      ReturnStatus = EFI_SUCCESS;
      if (CurrentState.LeftButton) {
        State->LeftButton = TRUE;
      }
      if (CurrentState.RightButton) {
        State->RightButton = TRUE;
      }
      if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {
        State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32)Private->SimplePointerMode.ResolutionX) / (INT32)Private->PointerList[Index]->Mode->ResolutionX;
      }
      if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {
        State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32)Private->SimplePointerMode.ResolutionY) / (INT32)Private->PointerList[Index]->Mode->ResolutionY;
      }
      if (CurrentState.Rela

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?