2379 lines
69 KiB
C
2379 lines
69 KiB
C
/** @file
|
|
Form browser console splitter for H2O form browser
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2013 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "FBConSplitter.h"
|
|
|
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *mOriginalConIn = NULL;
|
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mOriginalTextInEx = NULL;
|
|
EFI_SIMPLE_POINTER_PROTOCOL *mOriginalSimplePointer = NULL;
|
|
EFI_ABSOLUTE_POINTER_PROTOCOL *mOriginalAbsolutePointer = NULL;
|
|
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA mFBConIn = {
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_SIGNATURE,
|
|
{
|
|
FBTextInReset,
|
|
FBTextInReadKeyStroke,
|
|
(EFI_EVENT) NULL
|
|
},
|
|
0,
|
|
NULL,
|
|
0,
|
|
{
|
|
FBTextInExReset,
|
|
FBTextInExReadKeyStrokeEx,
|
|
(EFI_EVENT) NULL,
|
|
FBTextInExSetState,
|
|
FBTextInExRegisterKeyNotify,
|
|
FBTextInExUnregisterKeyNotify
|
|
},
|
|
0,
|
|
NULL,
|
|
0,
|
|
{
|
|
(LIST_ENTRY *) NULL,
|
|
(LIST_ENTRY *) NULL
|
|
},
|
|
0,
|
|
{
|
|
FBSimplePointerReset,
|
|
FBSimplePointerGetState,
|
|
(EFI_EVENT) NULL,
|
|
(EFI_SIMPLE_POINTER_MODE *) NULL
|
|
},
|
|
{
|
|
0x10000,
|
|
0x10000,
|
|
0x10000,
|
|
TRUE,
|
|
TRUE
|
|
},
|
|
0,
|
|
(EFI_SIMPLE_POINTER_PROTOCOL **) NULL,
|
|
0,
|
|
{
|
|
FBAbsolutePointerReset,
|
|
FBAbsolutePointerGetState,
|
|
(EFI_EVENT) NULL,
|
|
(EFI_ABSOLUTE_POINTER_MODE *) NULL
|
|
},
|
|
{
|
|
0,
|
|
0,
|
|
0,
|
|
0x10000,
|
|
0x10000,
|
|
0x10000,
|
|
0
|
|
},
|
|
0,
|
|
(EFI_ABSOLUTE_POINTER_PROTOCOL **) NULL,
|
|
0,
|
|
FALSE,
|
|
FALSE,
|
|
FALSE
|
|
};
|
|
|
|
EFI_UGA_DRAW_PROTOCOL *mOriginalUgaDraw = NULL;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *mOriginalGraphicsOutput = NULL;
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mOriginalConOut = NULL;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA mFBConOut = {
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA_SIGNATURE,
|
|
{
|
|
FBTextOutReset,
|
|
FBTextOutOutputString,
|
|
FBTextOutTestString,
|
|
FBTextOutQueryMode,
|
|
FBTextOutSetMode,
|
|
FBTextOutSetAttribute,
|
|
FBTextOutClearScreen,
|
|
FBTextOutSetCursorPosition,
|
|
FBTextOutEnableCursor,
|
|
(EFI_SIMPLE_TEXT_OUTPUT_MODE *) NULL
|
|
},
|
|
{
|
|
1,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
FALSE,
|
|
},
|
|
{
|
|
FBUgaDrawGetMode,
|
|
FBUgaDrawSetMode,
|
|
FBUgaDrawBlt
|
|
},
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
{
|
|
FBGraphicsOutputQueryMode,
|
|
FBGraphicsOutputSetMode,
|
|
FBGraphicsOutputBlt,
|
|
NULL
|
|
},
|
|
0,
|
|
0,
|
|
0,
|
|
(TEXT_OUT_AND_GOP_DATA *) NULL,
|
|
0
|
|
};
|
|
|
|
|
|
EFI_STATUS
|
|
FBGrowBuffer (
|
|
IN UINT32 ElementSize,
|
|
IN OUT UINT32 *Count,
|
|
IN OUT VOID **Buffer
|
|
)
|
|
{
|
|
VOID *Ptr;
|
|
|
|
//
|
|
// Grow the buffer to new buffer size,
|
|
// copy the old buffer's content to the new-size buffer,
|
|
// then free the old buffer.
|
|
//
|
|
Ptr = ReallocatePool (
|
|
(UINTN) (ElementSize * (*Count)),
|
|
(UINTN) (ElementSize * ((*Count) + HOT_PLUG_ALLOC_UNIT)),
|
|
*Buffer
|
|
);
|
|
if (Ptr == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
*Count += HOT_PLUG_ALLOC_UNIT;
|
|
*Buffer = Ptr;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
FBTextInWaitForKey (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = (CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *) Context;
|
|
|
|
if (Private->KeyEventSignalState) {
|
|
//
|
|
// If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
|
|
//
|
|
gBS->SignalEvent (Event);
|
|
return ;
|
|
}
|
|
|
|
//
|
|
// If any physical console input device has key input, signal the event.
|
|
//
|
|
Status = EFI_NOT_READY;
|
|
for (Index = 0; Index < Private->CurrentNumOfTextIn; Index++) {
|
|
Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->KeyEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
Status = gBS->CheckEvent (mOriginalConIn->WaitForKey);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->KeyEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInReset (
|
|
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_TEXT_IN (This);
|
|
Private->KeyEventSignalState = FALSE;
|
|
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumOfTextIn; Index++) {
|
|
Status = Private->TextInList[Index]->Reset (
|
|
Private->TextInList[Index],
|
|
ExtendedVerification
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalConIn->Reset (mOriginalConIn, ExtendedVerification);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInReadKeyStroke (
|
|
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
|
|
OUT EFI_INPUT_KEY *Key
|
|
)
|
|
{
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
EFI_INPUT_KEY CurrentKey;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_TEXT_IN (This);
|
|
Private->KeyEventSignalState = FALSE;
|
|
|
|
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->CurrentNumOfTextIn; Index++) {
|
|
Status = Private->TextInList[Index]->ReadKeyStroke (
|
|
Private->TextInList[Index],
|
|
&CurrentKey
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
CopyMem (Key, &CurrentKey, sizeof (EFI_INPUT_KEY));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalConIn->ReadKeyStroke (mOriginalConIn, &CurrentKey);
|
|
if (!EFI_ERROR (Status)) {
|
|
CopyMem (Key, &CurrentKey, sizeof (EFI_INPUT_KEY));
|
|
return Status;
|
|
}
|
|
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInExReset (
|
|
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_TEXT_IN_EX (This);
|
|
Private->KeyEventSignalState = FALSE;
|
|
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumOfTextInEx; Index++) {
|
|
Status = Private->TextInExList[Index]->Reset (
|
|
Private->TextInExList[Index],
|
|
ExtendedVerification
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalTextInEx->Reset (mOriginalTextInEx, ExtendedVerification);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInExReadKeyStrokeEx (
|
|
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
|
|
OUT EFI_KEY_DATA *KeyData
|
|
)
|
|
{
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
EFI_KEY_DATA CurrentKeyData;
|
|
|
|
|
|
if (KeyData == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_TEXT_IN_EX (This);
|
|
Private->KeyEventSignalState = FALSE;
|
|
|
|
KeyData->Key.UnicodeChar = 0;
|
|
KeyData->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->CurrentNumOfTextInEx; Index++) {
|
|
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
|
|
Private->TextInExList[Index],
|
|
&CurrentKeyData
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalTextInEx->ReadKeyStrokeEx (mOriginalTextInEx, &CurrentKeyData);
|
|
if (!EFI_ERROR (Status)) {
|
|
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
|
|
return Status;
|
|
}
|
|
|
|
return EFI_NOT_READY;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInExSetState (
|
|
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
|
|
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
|
|
)
|
|
{
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
|
|
if (KeyToggleState == NULL || (UINTN) This == (UINTN) KeyToggleState) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_TEXT_IN_EX (This);
|
|
|
|
//
|
|
// if no physical console input device exists, return EFI_SUCCESS;
|
|
// otherwise return the status of setting state of physical console input device
|
|
//
|
|
for (Index = 0; Index < Private->CurrentNumOfTextInEx; Index++) {
|
|
Status = Private->TextInExList[Index]->SetState (
|
|
Private->TextInExList[Index],
|
|
KeyToggleState
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) == EFI_TOGGLE_STATE_VALID) {
|
|
Private->KeyToggleState = *KeyToggleState;
|
|
}
|
|
|
|
Status = mOriginalTextInEx->SetState (mOriginalTextInEx, KeyToggleState);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInExRegisterKeyNotify (
|
|
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
|
|
IN EFI_KEY_DATA *KeyData,
|
|
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
|
|
OUT EFI_HANDLE *NotifyHandle
|
|
)
|
|
{
|
|
//
|
|
// BUGBUG:
|
|
// It can register key notify, but it can not unregister key notify.
|
|
// Because some key notify are registered in Consplitter and FB doesn't have the NotifyHandle.
|
|
// So, temporarily unspport RegisterKeyNotify/nregisterKeyNotify funcstions.
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextInExUnregisterKeyNotify (
|
|
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
|
|
IN EFI_HANDLE NotificationHandle
|
|
)
|
|
{
|
|
//
|
|
// BUGBUG:
|
|
// It can not unregister key notify.
|
|
// Because some key notify are registered in Consplitter and FB doesn't have the NotifyHandle.
|
|
// So, temporarily unspport RegisterKeyNotify/nregisterKeyNotify funcstions.
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
FBSimplePointerWaitForInput (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = (CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *) Context;
|
|
|
|
//
|
|
// if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()
|
|
//
|
|
if (Private->InputEventSignalState) {
|
|
gBS->SignalEvent (Event);
|
|
return ;
|
|
}
|
|
|
|
//
|
|
// if any physical console input device has key input, signal the event.
|
|
//
|
|
for (Index = 0; Index < Private->CurrentNumOfSimplePointer; Index++) {
|
|
Status = gBS->CheckEvent (Private->SimplePointerList[Index]->WaitForInput);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->InputEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
Status = gBS->CheckEvent (mOriginalSimplePointer->WaitForInput);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->KeyEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBSimplePointerReset (
|
|
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_SIMPLE_POINTER (This);
|
|
Private->InputEventSignalState = FALSE;
|
|
|
|
if (Private->CurrentNumOfSimplePointer == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumOfSimplePointer; Index++) {
|
|
Status = Private->SimplePointerList[Index]->Reset (
|
|
Private->SimplePointerList[Index],
|
|
ExtendedVerification
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalSimplePointer->Reset (mOriginalSimplePointer, ExtendedVerification);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBSimplePointerGetState (
|
|
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
|
|
IN OUT EFI_SIMPLE_POINTER_STATE *State
|
|
)
|
|
{
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
UINT32 Index;
|
|
EFI_SIMPLE_POINTER_STATE CurrentState;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_SIMPLE_POINTER (This);
|
|
Private->InputEventSignalState = FALSE;
|
|
|
|
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->CurrentNumOfSimplePointer; Index++) {
|
|
Status = Private->SimplePointerList[Index]->GetState (
|
|
Private->SimplePointerList[Index],
|
|
&CurrentState
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
if (ReturnStatus == EFI_NOT_READY) {
|
|
ReturnStatus = EFI_SUCCESS;
|
|
}
|
|
|
|
if (CurrentState.LeftButton) {
|
|
State->LeftButton = TRUE;
|
|
}
|
|
|
|
if (CurrentState.RightButton) {
|
|
State->RightButton = TRUE;
|
|
}
|
|
|
|
if (CurrentState.RelativeMovementX != 0 && Private->SimplePointerList[Index]->Mode->ResolutionX != 0) {
|
|
State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->SimplePointerList[Index]->Mode->ResolutionX;
|
|
}
|
|
|
|
if (CurrentState.RelativeMovementY != 0 && Private->SimplePointerList[Index]->Mode->ResolutionY != 0) {
|
|
State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->SimplePointerList[Index]->Mode->ResolutionY;
|
|
}
|
|
|
|
if (CurrentState.RelativeMovementZ != 0 && Private->SimplePointerList[Index]->Mode->ResolutionZ != 0) {
|
|
State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->SimplePointerList[Index]->Mode->ResolutionZ;
|
|
}
|
|
} else if (Status == EFI_DEVICE_ERROR) {
|
|
ReturnStatus = EFI_DEVICE_ERROR;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalSimplePointer->GetState (mOriginalSimplePointer, State);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
FBAbsolutePointerWaitForInput (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = (CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *) Context;
|
|
|
|
//
|
|
// if AbsoluteInputEventSignalState is flagged before,
|
|
// and not cleared by Reset() or GetState(), signal it
|
|
//
|
|
if (Private->AbsoluteInputEventSignalState) {
|
|
gBS->SignalEvent (Event);
|
|
return ;
|
|
}
|
|
//
|
|
// if any physical console input device has key input, signal the event.
|
|
//
|
|
for (Index = 0; Index < Private->CurrentNumOfAbsolutePointer; Index++) {
|
|
Status = gBS->CheckEvent (Private->AbsolutePointerList[Index]->WaitForInput);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->AbsoluteInputEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
Status = gBS->CheckEvent (mOriginalAbsolutePointer->WaitForInput);
|
|
if (!EFI_ERROR (Status)) {
|
|
gBS->SignalEvent (Event);
|
|
Private->AbsoluteInputEventSignalState = TRUE;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBAbsolutePointerReset (
|
|
IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_ABSOLUTE_POINTER (This);
|
|
Private->AbsoluteInputEventSignalState = FALSE;
|
|
|
|
if (Private->CurrentNumOfAbsolutePointer == 0) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumOfAbsolutePointer; Index++) {
|
|
Status = Private->AbsolutePointerList[Index]->Reset (
|
|
Private->AbsolutePointerList[Index],
|
|
ExtendedVerification
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalAbsolutePointer->Reset (mOriginalAbsolutePointer, ExtendedVerification);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBAbsolutePointerGetState (
|
|
IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
|
|
IN OUT EFI_ABSOLUTE_POINTER_STATE *State
|
|
)
|
|
{
|
|
CONSOLE_IN_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
UINT32 Index;
|
|
EFI_ABSOLUTE_POINTER_STATE CurrentState;
|
|
UINT64 Factor;
|
|
|
|
|
|
Private = CONSOLE_IN_HOT_PLUG_PRIVATE_DATA_FROM_ABSOLUTE_POINTER (This);
|
|
Private->AbsoluteInputEventSignalState = FALSE;
|
|
|
|
State->CurrentX = 0;
|
|
State->CurrentY = 0;
|
|
State->CurrentZ = 0;
|
|
State->ActiveButtons = 0;
|
|
|
|
//
|
|
// if no physical pointer device exists, return EFI_NOT_READY;
|
|
// if any physical pointer device has changed state,
|
|
// return the state and EFI_SUCCESS.
|
|
//
|
|
ReturnStatus = EFI_NOT_READY;
|
|
for (Index = 0; Index < Private->CurrentNumOfAbsolutePointer; Index++) {
|
|
Status = Private->AbsolutePointerList[Index]->GetState (
|
|
Private->AbsolutePointerList[Index],
|
|
&CurrentState
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
if (ReturnStatus == EFI_NOT_READY) {
|
|
ReturnStatus = EFI_SUCCESS;
|
|
}
|
|
|
|
State->ActiveButtons = CurrentState.ActiveButtons;
|
|
|
|
if (!(Private->AbsolutePointerMode.AbsoluteMinX == 0 && Private->AbsolutePointerMode.AbsoluteMaxX == 0)) {
|
|
if (!(Private->AbsolutePointerList[Index]->Mode->AbsoluteMinX == 0 && Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxX == 0)) {
|
|
Factor = DivU64x32 (LShiftU64 ((UINT64)Private->AbsolutePointerMode.AbsoluteMaxX, 32), (UINT32)(Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxX - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinX));
|
|
State->CurrentX = (UINTN)(RShiftU64 (MultU64x32 (Factor, (UINT32)(CurrentState.CurrentX - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinX)), 32));
|
|
}
|
|
}
|
|
if (!(Private->AbsolutePointerMode.AbsoluteMinY == 0 && Private->AbsolutePointerMode.AbsoluteMaxY == 0)) {
|
|
if (!(Private->AbsolutePointerList[Index]->Mode->AbsoluteMinY == 0 && Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxY == 0)) {
|
|
Factor = DivU64x32 (LShiftU64 ((UINT64)Private->AbsolutePointerMode.AbsoluteMaxY, 32), (UINT32)(Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxY - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinY));
|
|
State->CurrentY = (UINTN)(RShiftU64 (MultU64x32 (Factor, (UINT32)(CurrentState.CurrentY - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinY)), 32));
|
|
}
|
|
}
|
|
if (!(Private->AbsolutePointerMode.AbsoluteMinZ == 0 && Private->AbsolutePointerMode.AbsoluteMaxZ == 0)) {
|
|
if (!(Private->AbsolutePointerList[Index]->Mode->AbsoluteMinZ == 0 && Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxZ == 0)) {
|
|
Factor = DivU64x32 (LShiftU64 ((UINT64)Private->AbsolutePointerMode.AbsoluteMaxZ, 32), (UINT32)(Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxZ - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinZ));
|
|
State->CurrentZ = (UINTN)(RShiftU64 (MultU64x32 (Factor, (UINT32)(CurrentState.CurrentZ - Private->AbsolutePointerList[Index]->Mode->AbsoluteMinZ)), 32));
|
|
}
|
|
}
|
|
} else if (Status == EFI_DEVICE_ERROR) {
|
|
ReturnStatus = EFI_DEVICE_ERROR;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalAbsolutePointer->GetState (mOriginalAbsolutePointer, State);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForTextIn (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextInProtocolGuid, (VOID **) &TextIn);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (mFBConIn.CurrentNumOfTextIn >= mFBConIn.TextInListCount) {
|
|
Status = FBGrowBuffer (
|
|
sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *),
|
|
&mFBConIn.TextInListCount,
|
|
(VOID **) &mFBConIn.TextInList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
mFBConIn.TextInList[mFBConIn.CurrentNumOfTextIn] = TextIn;
|
|
mFBConIn.CurrentNumOfTextIn++;
|
|
|
|
//
|
|
// Extra CheckEvent added to reduce the double CheckEvent().
|
|
//
|
|
gBS->CheckEvent (TextIn->WaitForKey);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForTextInEx (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
|
|
EFI_KEY_TOGGLE_STATE KeyToggleState;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TextInEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (mFBConIn.CurrentNumOfTextInEx >= mFBConIn.TextInExListCount) {
|
|
Status = FBGrowBuffer (
|
|
sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
|
|
&mFBConIn.TextInExListCount,
|
|
(VOID **) &mFBConIn.TextInExList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
mFBConIn.TextInExList[mFBConIn.CurrentNumOfTextInEx] = TextInEx;
|
|
mFBConIn.CurrentNumOfTextInEx++;
|
|
|
|
//
|
|
// Synchronize toggle state for current input device.
|
|
//
|
|
if (mFBConIn.KeyToggleState) {
|
|
KeyToggleState = mFBConIn.KeyToggleState;
|
|
TextInEx->SetState (
|
|
TextInEx,
|
|
&KeyToggleState
|
|
);
|
|
}
|
|
|
|
//
|
|
// Extra CheckEvent added to reduce the double CheckEvent().
|
|
//
|
|
gBS->CheckEvent (TextInEx->WaitForKeyEx);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForSimplePointer (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimplePointerProtocolGuid, (VOID **) &SimplePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (mFBConIn.CurrentNumOfSimplePointer >= mFBConIn.SimplePointerListCount) {
|
|
Status = FBGrowBuffer (
|
|
sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),
|
|
&mFBConIn.SimplePointerListCount,
|
|
(VOID **) &mFBConIn.SimplePointerList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
mFBConIn.SimplePointerList[mFBConIn.CurrentNumOfSimplePointer] = SimplePointer;
|
|
mFBConIn.CurrentNumOfSimplePointer++;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForAbsolutePointer (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiAbsolutePointerProtocolGuid, (VOID **) &AbsolutePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (mFBConIn.CurrentNumOfAbsolutePointer >= mFBConIn.AbsolutePointerListCount) {
|
|
Status = FBGrowBuffer (
|
|
sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),
|
|
&mFBConIn.AbsolutePointerListCount,
|
|
(VOID **) &mFBConIn.AbsolutePointerList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
mFBConIn.AbsolutePointerList[mFBConIn.CurrentNumOfAbsolutePointer] = AbsolutePointer;
|
|
mFBConIn.CurrentNumOfAbsolutePointer++;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForConIn (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
FBAddDeviceForTextIn (ControllerHandle);
|
|
FBAddDeviceForTextInEx (ControllerHandle);
|
|
FBAddDeviceForSimplePointer (ControllerHandle);
|
|
FBAddDeviceForAbsolutePointer (ControllerHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForTextIn (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
|
UINT32 Index;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextInProtocolGuid, (VOID **) &TextIn);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Remove the specified text-in device data structure from the Text In List,
|
|
// and rearrange the remaining data structures in the Text In List.
|
|
//
|
|
for (Index = 0; Index < mFBConIn.CurrentNumOfTextIn; Index++) {
|
|
if (mFBConIn.TextInList[Index] == TextIn) {
|
|
for (; Index < mFBConIn.CurrentNumOfTextIn - 1; Index++) {
|
|
mFBConIn.TextInList[Index] = mFBConIn.TextInList[Index + 1];
|
|
}
|
|
|
|
mFBConIn.CurrentNumOfTextIn--;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForTextInEx (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
|
|
UINT32 Index;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &TextInEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Remove the specified text-in device data structure from the Text Input Ex List,
|
|
// and rearrange the remaining data structures in the Text In List.
|
|
//
|
|
for (Index = 0; Index < mFBConIn.CurrentNumOfTextInEx; Index++) {
|
|
if (mFBConIn.TextInExList[Index] == TextInEx) {
|
|
for (; Index < mFBConIn.CurrentNumOfTextInEx - 1; Index++) {
|
|
mFBConIn.TextInExList[Index] = mFBConIn.TextInExList[Index + 1];
|
|
}
|
|
|
|
mFBConIn.CurrentNumOfTextInEx--;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForSimplePointer (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
|
|
EFI_SIMPLE_POINTER_MODE *SimplePointerMode;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimplePointerProtocolGuid, (VOID **) &SimplePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Remove the specified text-in device data structure from the Simple Pointer List,
|
|
// and rearrange the remaining data structures in the Text In List.
|
|
//
|
|
for (Index = 0; Index < mFBConIn.CurrentNumOfSimplePointer; Index++) {
|
|
if (mFBConIn.SimplePointerList[Index] == SimplePointer) {
|
|
for (; Index < mFBConIn.CurrentNumOfSimplePointer - 1; Index++) {
|
|
mFBConIn.SimplePointerList[Index] = mFBConIn.SimplePointerList[Index + 1];
|
|
}
|
|
|
|
mFBConIn.CurrentNumOfSimplePointer--;
|
|
|
|
if (mFBConIn.CurrentNumOfSimplePointer == 0) {
|
|
SimplePointerMode = mOriginalSimplePointer->Mode;
|
|
} else {
|
|
SimplePointerMode = mFBConIn.SimplePointerList[0]->Mode;
|
|
}
|
|
CopyMem (mFBConIn.SimplePointer.Mode, SimplePointerMode, sizeof(EFI_SIMPLE_POINTER_MODE));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForAbsolutePointer (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;
|
|
EFI_ABSOLUTE_POINTER_MODE *AbsoluteMode;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiAbsolutePointerProtocolGuid, (VOID **) &AbsolutePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Remove the specified text-in device data structure from the Absolute Pointer List,
|
|
// and rearrange the remaining data structures from the Absolute Pointer List.
|
|
//
|
|
for (Index = 0; Index < mFBConIn.CurrentNumOfAbsolutePointer; Index++) {
|
|
if (mFBConIn.AbsolutePointerList[Index] == AbsolutePointer) {
|
|
for (; Index < mFBConIn.CurrentNumOfAbsolutePointer - 1; Index++) {
|
|
mFBConIn.AbsolutePointerList[Index] = mFBConIn.AbsolutePointerList[Index + 1];
|
|
}
|
|
|
|
mFBConIn.CurrentNumOfAbsolutePointer--;
|
|
|
|
if (mFBConIn.CurrentNumOfAbsolutePointer == 0) {
|
|
AbsoluteMode = mOriginalAbsolutePointer->Mode;
|
|
} else {
|
|
AbsoluteMode = mFBConIn.AbsolutePointerList[0]->Mode;
|
|
}
|
|
CopyMem (mFBConIn.AbsolutePointer.Mode, AbsoluteMode, sizeof(EFI_ABSOLUTE_POINTER_MODE));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForConIn (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
FBDeleteDeviceForTextIn (ControllerHandle);
|
|
FBDeleteDeviceForTextInEx (ControllerHandle);
|
|
FBDeleteDeviceForSimplePointer (ControllerHandle);
|
|
FBDeleteDeviceForAbsolutePointer (ControllerHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutReset (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN BOOLEAN ExtendedVerification
|
|
)
|
|
{
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutOutputString (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN CHAR16 *WString
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
UINTN MaxColumn;
|
|
UINTN MaxRow;
|
|
|
|
This->SetAttribute (This, This->Mode->Attribute);
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->OutputString (
|
|
Private->TextOutList[Index].TextOut,
|
|
WString
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalConOut->OutputString (mOriginalConOut, WString);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
if (Private->CurrentNumberOfConsoles > 0) {
|
|
Private->TextOutMode.CursorColumn = Private->TextOutList[0].TextOut->Mode->CursorColumn;
|
|
Private->TextOutMode.CursorRow = Private->TextOutList[0].TextOut->Mode->CursorRow;
|
|
} else {
|
|
//
|
|
// When there is no real console devices in system,
|
|
// update cursor position for the virtual device in consplitter.
|
|
//
|
|
Private->TextOut.QueryMode (
|
|
&Private->TextOut,
|
|
Private->TextOutMode.Mode,
|
|
&MaxColumn,
|
|
&MaxRow
|
|
);
|
|
for (; *WString != CHAR_NULL; WString++) {
|
|
switch (*WString) {
|
|
case CHAR_BACKSPACE:
|
|
if (Private->TextOutMode.CursorColumn == 0 && Private->TextOutMode.CursorRow > 0) {
|
|
Private->TextOutMode.CursorRow--;
|
|
Private->TextOutMode.CursorColumn = (INT32) (MaxColumn - 1);
|
|
} else if (Private->TextOutMode.CursorColumn > 0) {
|
|
Private->TextOutMode.CursorColumn--;
|
|
}
|
|
break;
|
|
|
|
case CHAR_LINEFEED:
|
|
if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {
|
|
Private->TextOutMode.CursorRow++;
|
|
}
|
|
break;
|
|
|
|
case CHAR_CARRIAGE_RETURN:
|
|
Private->TextOutMode.CursorColumn = 0;
|
|
break;
|
|
|
|
default:
|
|
if (Private->TextOutMode.CursorColumn < (INT32) (MaxColumn - 1)) {
|
|
Private->TextOutMode.CursorColumn++;
|
|
} else {
|
|
Private->TextOutMode.CursorColumn = 0;
|
|
if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {
|
|
Private->TextOutMode.CursorRow++;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutTestString (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN CHAR16 *WString
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->TestString (
|
|
Private->TextOutList[Index].TextOut,
|
|
WString
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Status = mOriginalConOut->TestString (mOriginalConOut, WString);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutQueryMode (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN ModeNumber,
|
|
OUT UINTN *Columns,
|
|
OUT UINTN *Rows
|
|
)
|
|
{
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
//
|
|
// Check whether param ModeNumber is valid.
|
|
// ModeNumber should be within range 0 ~ MaxMode - 1.
|
|
//
|
|
if ((ModeNumber > (UINTN) (((UINT32)-1)>>1)) ) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if ((INT32) ModeNumber >= This->Mode->MaxMode) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (Private->CurrentNumberOfConsoles == 0) {
|
|
mOriginalConOut->QueryMode (
|
|
mOriginalConOut,
|
|
ModeNumber,
|
|
Columns,
|
|
Rows
|
|
);
|
|
} else {
|
|
Private->TextOutList[0].TextOut->QueryMode (
|
|
Private->TextOutList[0].TextOut,
|
|
ModeNumber,
|
|
Columns,
|
|
Rows
|
|
);
|
|
}
|
|
|
|
if (*Columns <= 0 && *Rows <= 0) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutSetMode (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN ModeNumber
|
|
)
|
|
{
|
|
return mOriginalConOut->SetMode (mOriginalConOut, ModeNumber);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutSetAttribute (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN Attribute
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
if ( (Attribute > (UINTN)(((UINT32)-1)>>1)) ) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->SetAttribute (
|
|
Private->TextOutList[Index].TextOut,
|
|
Attribute
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Private->TextOutMode.Attribute = (INT32) Attribute;
|
|
|
|
Status = mOriginalConOut->SetAttribute (mOriginalConOut, Attribute);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutClearScreen (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Private->TextOutMode.CursorColumn = 0;
|
|
Private->TextOutMode.CursorRow = 0;
|
|
Private->TextOutMode.CursorVisible = TRUE;
|
|
|
|
Status = mOriginalConOut->ClearScreen (mOriginalConOut);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutSetCursorPosition (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN UINTN Column,
|
|
IN UINTN Row
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
UINTN MaxColumn;
|
|
UINTN MaxRow;
|
|
INT32 ModeNumber;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
ModeNumber = Private->TextOutMode.Mode;
|
|
|
|
//
|
|
// Get current MaxColumn and MaxRow from intersection map
|
|
//
|
|
Status = FBTextOutQueryMode (This, ModeNumber, &MaxColumn, &MaxRow);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (Column >= MaxColumn || Row >= MaxRow) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->SetCursorPosition (
|
|
Private->TextOutList[Index].TextOut,
|
|
Column,
|
|
Row
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Private->TextOutMode.CursorColumn = (INT32) Column;
|
|
Private->TextOutMode.CursorRow = (INT32) Row;
|
|
|
|
Status = mOriginalConOut->SetCursorPosition (mOriginalConOut, Column, Row);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBTextOutEnableCursor (
|
|
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
|
|
IN BOOLEAN Visible
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_TEXT_OUT (This);
|
|
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
Status = Private->TextOutList[Index].TextOut->EnableCursor (
|
|
Private->TextOutList[Index].TextOut,
|
|
Visible
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
}
|
|
|
|
Private->TextOutMode.CursorVisible = Visible;
|
|
|
|
Status = mOriginalConOut->EnableCursor (mOriginalConOut, Visible);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBUgaDrawGetMode (
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
OUT UINT32 *HorizontalResolution,
|
|
OUT UINT32 *VerticalResolution,
|
|
OUT UINT32 *ColorDepth,
|
|
OUT UINT32 *RefreshRate
|
|
)
|
|
{
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
EFI_STATUS Status;
|
|
|
|
if ((HorizontalResolution == NULL) ||
|
|
(VerticalResolution == NULL) ||
|
|
(RefreshRate == NULL) ||
|
|
(ColorDepth == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (mFBConOut.CurrentNumberOfUgaDraw != 0) {
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_UGA_DRAW (This);
|
|
*HorizontalResolution = Private->UgaHorizontalResolution;
|
|
*VerticalResolution = Private->UgaVerticalResolution;
|
|
*ColorDepth = Private->UgaColorDepth;
|
|
*RefreshRate = Private->UgaRefreshRate;
|
|
} else {
|
|
Status = mOriginalUgaDraw->GetMode (
|
|
mOriginalUgaDraw,
|
|
HorizontalResolution,
|
|
VerticalResolution,
|
|
ColorDepth,
|
|
RefreshRate
|
|
);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBUgaDrawSetMode (
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
IN UINT32 HorizontalResolution,
|
|
IN UINT32 VerticalResolution,
|
|
IN UINT32 ColorDepth,
|
|
IN UINT32 RefreshRate
|
|
)
|
|
{
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBUgaDrawBlt (
|
|
IN EFI_UGA_DRAW_PROTOCOL *This,
|
|
IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
|
|
IN EFI_UGA_BLT_OPERATION BltOperation,
|
|
IN UINTN SourceX,
|
|
IN UINTN SourceY,
|
|
IN UINTN DestinationX,
|
|
IN UINTN DestinationY,
|
|
IN UINTN Width,
|
|
IN UINTN Height,
|
|
IN UINTN Delta OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_STATUS ReturnStatus;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_UGA_DRAW (This);
|
|
|
|
ReturnStatus = EFI_SUCCESS;
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
|
|
if (GraphicsOutput != NULL) {
|
|
Status = GraphicsOutput->Blt (
|
|
GraphicsOutput,
|
|
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltBuffer,
|
|
(EFI_GRAPHICS_OUTPUT_BLT_OPERATION) BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
} else if (BltOperation == EfiUgaVideoToBltBuffer) {
|
|
//
|
|
// Only need to read the data into buffer one time
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (Private->TextOutList[Index].UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
|
|
Status = Private->TextOutList[Index].UgaDraw->Blt (
|
|
Private->TextOutList[Index].UgaDraw,
|
|
BltBuffer,
|
|
BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
} else if (BltOperation == EfiUgaVideoToBltBuffer) {
|
|
//
|
|
// Only need to read the data into buffer one time
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = mOriginalUgaDraw->Blt (
|
|
mOriginalUgaDraw,
|
|
BltBuffer,
|
|
BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBGraphicsOutputQueryMode (
|
|
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
|
IN UINT32 ModeNumber,
|
|
OUT UINTN *SizeOfInfo,
|
|
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
|
|
if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
GraphicsOutput = mOriginalGraphicsOutput;
|
|
if (mFBConOut.CurrentNumberOfGraphicsOutput != 0) {
|
|
for (Index = 0; Index < mFBConOut.CurrentNumberOfConsoles; Index++) {
|
|
if (mFBConOut.TextOutList[Index].GraphicsOutput != NULL) {
|
|
GraphicsOutput = mFBConOut.TextOutList[Index].GraphicsOutput;
|
|
break;;
|
|
}
|
|
}
|
|
}
|
|
|
|
return GraphicsOutput->QueryMode (
|
|
GraphicsOutput,
|
|
ModeNumber,
|
|
SizeOfInfo,
|
|
Info
|
|
);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBGraphicsOutputSetMode (
|
|
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
|
IN UINT32 ModeNumber
|
|
)
|
|
{
|
|
return mOriginalGraphicsOutput->SetMode (mOriginalGraphicsOutput, ModeNumber);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FBGraphicsOutputBlt (
|
|
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
|
|
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
|
|
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
|
|
IN UINTN SourceX,
|
|
IN UINTN SourceY,
|
|
IN UINTN DestinationX,
|
|
IN UINTN DestinationY,
|
|
IN UINTN Width,
|
|
IN UINTN Height,
|
|
IN UINTN Delta OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS ReturnStatus;
|
|
CONSOLE_OUT_HOT_PLUG_PRIVATE_DATA *Private;
|
|
UINT32 Index;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
|
|
|
if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = HOT_PLUG_CONSOLE_OUTPUT_PRIVATE_DATA_FROM_GRAPHIC_OUT (This);
|
|
|
|
ReturnStatus = EFI_SUCCESS;
|
|
|
|
//
|
|
// return the worst status met
|
|
//
|
|
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
|
|
GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
|
|
if (GraphicsOutput != NULL) {
|
|
Status = GraphicsOutput->Blt (
|
|
GraphicsOutput,
|
|
BltBuffer,
|
|
BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
} else if (BltOperation == EfiBltVideoToBltBuffer) {
|
|
//
|
|
// Only need to read the data into buffer one time
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
UgaDraw = Private->TextOutList[Index].UgaDraw;
|
|
if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
|
|
Status = UgaDraw->Blt (
|
|
UgaDraw,
|
|
(EFI_UGA_PIXEL *) BltBuffer,
|
|
(EFI_UGA_BLT_OPERATION) BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
} else if (BltOperation == EfiBltVideoToBltBuffer) {
|
|
//
|
|
// Only need to read the data into buffer one time
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = mOriginalGraphicsOutput->Blt (
|
|
mOriginalGraphicsOutput,
|
|
BltBuffer,
|
|
BltOperation,
|
|
SourceX,
|
|
SourceY,
|
|
DestinationX,
|
|
DestinationY,
|
|
Width,
|
|
Height,
|
|
Delta
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReturnStatus = Status;
|
|
}
|
|
|
|
return ReturnStatus;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBUpdateModeDataForTextOut (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
|
|
|
|
if (mOriginalConOut == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (mFBConOut.CurrentNumberOfConsoles == 0) {
|
|
Mode = mOriginalConOut->Mode;
|
|
} else {
|
|
Mode = mFBConOut.TextOutList[0].TextOut->Mode;
|
|
}
|
|
CopyMem (mFBConOut.TextOut.Mode, Mode, sizeof(EFI_SIMPLE_TEXT_OUTPUT_MODE));
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBUpdateModeDataForUga (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
|
|
|
if (mOriginalUgaDraw == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
UgaDraw = mOriginalUgaDraw;
|
|
if (mFBConOut.CurrentNumberOfUgaDraw != 0) {
|
|
for (Index = 0; Index < mFBConOut.CurrentNumberOfConsoles; Index++) {
|
|
if (mFBConOut.TextOutList[Index].UgaDraw != NULL) {
|
|
UgaDraw = mFBConOut.TextOutList[Index].UgaDraw;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
UgaDraw->GetMode (
|
|
UgaDraw,
|
|
&mFBConOut.UgaHorizontalResolution,
|
|
&mFBConOut.UgaVerticalResolution,
|
|
&mFBConOut.UgaColorDepth,
|
|
&mFBConOut.UgaRefreshRate
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBUpdateModeDataForGop (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
|
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
|
|
|
|
if (mOriginalGraphicsOutput == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Mode = mOriginalGraphicsOutput->Mode;
|
|
if (mFBConOut.CurrentNumberOfGraphicsOutput != 0) {
|
|
for (Index = 0; Index < mFBConOut.CurrentNumberOfConsoles; Index++) {
|
|
if (mFBConOut.TextOutList[Index].GraphicsOutput != NULL) {
|
|
Mode = mFBConOut.TextOutList[Index].GraphicsOutput->Mode;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Info = mFBConOut.GraphicsOutput.Mode->Info;
|
|
CopyMem (mFBConOut.GraphicsOutput.Mode, Mode , sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
|
|
CopyMem (Info , Mode->Info, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
|
|
mFBConOut.GraphicsOutput.Mode->Info = Info;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBAddDeviceForConOut (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
|
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
|
|
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
|
|
UINT32 CurrentNumOfConsoles;
|
|
UINT32 CurrentNumOfGraphicsOutput;
|
|
UINT32 CurrentNumOfUgaDraw;
|
|
TEXT_OUT_AND_GOP_DATA *TextAndGop;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextOutProtocolGuid, (VOID **) &TextOut);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
GraphicsOutput = NULL;
|
|
UgaDraw = NULL;
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
|
|
if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
|
|
gBS->HandleProtocol (ControllerHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
|
|
}
|
|
|
|
CurrentNumOfGraphicsOutput = mFBConOut.CurrentNumberOfGraphicsOutput;
|
|
CurrentNumOfUgaDraw = mFBConOut.CurrentNumberOfUgaDraw;
|
|
CurrentNumOfConsoles = mFBConOut.CurrentNumberOfConsoles;
|
|
|
|
while (CurrentNumOfConsoles >= mFBConOut.TextOutListCount) {
|
|
Status = FBGrowBuffer (
|
|
sizeof (TEXT_OUT_AND_GOP_DATA),
|
|
&mFBConOut.TextOutListCount,
|
|
(VOID **) &mFBConOut.TextOutList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
}
|
|
|
|
TextAndGop = &mFBConOut.TextOutList[CurrentNumOfConsoles];
|
|
TextAndGop->TextOut = TextOut;
|
|
TextAndGop->GraphicsOutput = GraphicsOutput;
|
|
TextAndGop->UgaDraw = UgaDraw;
|
|
|
|
mFBConOut.CurrentNumberOfConsoles++;
|
|
if (CurrentNumOfConsoles == 0) {
|
|
FBUpdateModeDataForTextOut ();
|
|
}
|
|
|
|
if (GraphicsOutput != NULL) {
|
|
mFBConOut.CurrentNumberOfGraphicsOutput++;
|
|
if (CurrentNumOfGraphicsOutput == 0) {
|
|
FBUpdateModeDataForGop ();
|
|
}
|
|
}
|
|
|
|
if (UgaDraw != NULL) {
|
|
mFBConOut.CurrentNumberOfUgaDraw++;
|
|
if (CurrentNumOfUgaDraw == 0) {
|
|
FBUpdateModeDataForUga ();
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBDeleteDeviceForConOut (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
INT32 Index;
|
|
UINT32 CurrentNumOfConsoles;
|
|
TEXT_OUT_AND_GOP_DATA *TextOutList;
|
|
EFI_STATUS Status;
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
|
|
|
|
Status = gBS->HandleProtocol (ControllerHandle, &gEfiSimpleTextOutProtocolGuid, (VOID **) &TextOut);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Remove the specified text-out device data structure from the Text out List,
|
|
// and rearrange the remaining data structures in the Text out List.
|
|
//
|
|
CurrentNumOfConsoles = mFBConOut.CurrentNumberOfConsoles;
|
|
Index = (INT32) CurrentNumOfConsoles - 1;
|
|
TextOutList = mFBConOut.TextOutList;
|
|
while (Index >= 0) {
|
|
if (TextOutList->TextOut == TextOut) {
|
|
if (TextOutList->UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
|
|
mFBConOut.CurrentNumberOfUgaDraw--;
|
|
}
|
|
if (TextOutList->GraphicsOutput != NULL) {
|
|
mFBConOut.CurrentNumberOfGraphicsOutput--;
|
|
}
|
|
CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);
|
|
mFBConOut.CurrentNumberOfConsoles--;
|
|
break;
|
|
}
|
|
|
|
Index--;
|
|
TextOutList++;
|
|
}
|
|
|
|
if (Index < 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
FBUpdateModeDataForTextOut ();
|
|
FBUpdateModeDataForUga ();
|
|
FBUpdateModeDataForGop ();
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConInConstructor (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Size;
|
|
|
|
//
|
|
// Simple text input protocol
|
|
//
|
|
Size = sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *);
|
|
Status = FBGrowBuffer (Size, &mFBConIn.TextInListCount, (VOID **) &mFBConIn.TextInList);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_NOTIFY, FBTextInWaitForKey, &mFBConIn, &mFBConIn.TextIn.WaitForKey);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mOriginalConIn = gST->ConIn;
|
|
|
|
//
|
|
// Simple text input ex protocol
|
|
//
|
|
Size = sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *);
|
|
Status = FBGrowBuffer (Size, &mFBConIn.TextInExListCount, (VOID **) &mFBConIn.TextInExList);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_NOTIFY, FBTextInWaitForKey, &mFBConIn, &mFBConIn.TextInEx.WaitForKeyEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextInputExProtocolGuid, (VOID **) &mOriginalTextInEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Simple pointer protocol
|
|
//
|
|
Size = sizeof (EFI_SIMPLE_POINTER_PROTOCOL *);
|
|
Status = FBGrowBuffer (Size, &mFBConIn.SimplePointerListCount, (VOID **) &mFBConIn.SimplePointerList);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_NOTIFY, FBSimplePointerWaitForInput, &mFBConIn, &mFBConIn.SimplePointer.WaitForInput);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mFBConIn.SimplePointer.Mode = &mFBConIn.SimplePointerMode;
|
|
Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimplePointerProtocolGuid, (VOID **) &mOriginalSimplePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Absolute pointer protocol
|
|
//
|
|
Size = sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *);
|
|
Status = FBGrowBuffer (Size, &mFBConIn.AbsolutePointerListCount, (VOID **) &mFBConIn.AbsolutePointerList);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_NOTIFY, FBAbsolutePointerWaitForInput, &mFBConIn, &mFBConIn.AbsolutePointer.WaitForInput);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mFBConIn.AbsolutePointer.Mode = &mFBConIn.AbsolutePointerMode;
|
|
Status = gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiAbsolutePointerProtocolGuid, (VOID **) &mOriginalAbsolutePointer);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConInDeconstructor (
|
|
VOID
|
|
)
|
|
{
|
|
mFBConIn.TextInListCount = 0;
|
|
mFBConIn.TextInExListCount = 0;
|
|
mFBConIn.SimplePointerListCount = 0;
|
|
mFBConIn.AbsolutePointerListCount = 0;
|
|
|
|
FBFreePool ((VOID **) &mFBConIn.TextInList);
|
|
if (mFBConIn.TextIn.WaitForKey != NULL) {
|
|
gBS->CloseEvent (mFBConIn.TextIn.WaitForKey);
|
|
mFBConIn.TextIn.WaitForKey = NULL;
|
|
}
|
|
|
|
FBFreePool ((VOID **) &mFBConIn.TextInExList);
|
|
if (mFBConIn.TextInEx.WaitForKeyEx != NULL) {
|
|
gBS->CloseEvent (mFBConIn.TextInEx.WaitForKeyEx);
|
|
mFBConIn.TextInEx.WaitForKeyEx = NULL;
|
|
}
|
|
|
|
FBFreePool ((VOID **) &mFBConIn.SimplePointerList);
|
|
if (mFBConIn.SimplePointer.WaitForInput != NULL) {
|
|
gBS->CloseEvent (mFBConIn.SimplePointer.WaitForInput);
|
|
mFBConIn.SimplePointer.WaitForInput = NULL;
|
|
}
|
|
|
|
FBFreePool ((VOID **) &mFBConIn.AbsolutePointerList);
|
|
if (mFBConIn.AbsolutePointer.WaitForInput != NULL) {
|
|
gBS->CloseEvent (mFBConIn.AbsolutePointer.WaitForInput);
|
|
mFBConIn.AbsolutePointer.WaitForInput = NULL;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConInStart (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE ConInHandle;
|
|
EFI_GUID *Guid;
|
|
|
|
ConInHandle = gST->ConsoleInHandle;
|
|
|
|
//
|
|
// Simple text input protocol
|
|
//
|
|
gST->ConIn = &mFBConIn.TextIn;
|
|
|
|
//
|
|
// Simple text input ex protocol
|
|
//
|
|
Guid = &gEfiSimpleTextInputExProtocolGuid;
|
|
Status = gBS->ReinstallProtocolInterface (ConInHandle, Guid, mOriginalTextInEx, &mFBConIn.TextInEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// SetupMosue will process SimplePointer and AbsolutePointer
|
|
//
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConInStop (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE ConInHandle;
|
|
EFI_GUID *Guid;
|
|
|
|
ConInHandle = gST->ConsoleInHandle;
|
|
|
|
//
|
|
// SetupMosue will process SimplePointer and AbsolutePointer
|
|
//
|
|
|
|
if (mOriginalTextInEx != NULL) {
|
|
Guid = &gEfiSimpleTextInputExProtocolGuid;
|
|
Status = gBS->ReinstallProtocolInterface (ConInHandle, Guid, &mFBConIn.TextInEx, mOriginalTextInEx);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mOriginalTextInEx = NULL;
|
|
}
|
|
|
|
|
|
if (mOriginalConIn != NULL) {
|
|
gST->ConIn = mOriginalConIn;
|
|
mOriginalConIn = NULL;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutConstructor (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
mFBConOut.TextOut.Mode = &mFBConOut.TextOutMode;
|
|
|
|
Status = FBGrowBuffer (
|
|
sizeof (TEXT_OUT_AND_GOP_DATA),
|
|
&mFBConOut.TextOutListCount,
|
|
(VOID **) &mFBConOut.TextOutList
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
mFBConOut.GraphicsOutput.Mode = AllocatePool (sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
|
|
if (mFBConOut.GraphicsOutput.Mode == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
mFBConOut.GraphicsOutput.Mode->Info = AllocatePool (sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
|
|
if (mFBConOut.GraphicsOutput.Mode->Info == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
mOriginalConOut = gST->ConOut;
|
|
|
|
mOriginalUgaDraw = NULL;
|
|
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &mOriginalUgaDraw);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
mOriginalGraphicsOutput = NULL;
|
|
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &mOriginalGraphicsOutput);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutDeconstructor (
|
|
VOID
|
|
)
|
|
{
|
|
mFBConOut.TextOutListCount = 0;
|
|
FBFreePool ((VOID **) &mFBConOut.TextOutList);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutStartForTextOut (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
FBUpdateModeDataForTextOut ();
|
|
|
|
Status = gBS->ReinstallProtocolInterface (
|
|
gST->ConsoleOutHandle,
|
|
&gEfiSimpleTextOutProtocolGuid,
|
|
mOriginalConOut,
|
|
&mFBConOut.TextOut
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
if (mOriginalConOut != NULL) {
|
|
Status = gBS->InstallProtocolInterface (
|
|
&gST->ConsoleOutHandle,
|
|
&gEfiSimpleTextOutProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mFBConOut.TextOut
|
|
);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
gST->ConOut = &mFBConOut.TextOut;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutStartForUga (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
FBUpdateModeDataForUga ();
|
|
|
|
Status = gBS->ReinstallProtocolInterface (
|
|
gST->ConsoleOutHandle,
|
|
&gEfiUgaDrawProtocolGuid,
|
|
mOriginalUgaDraw,
|
|
&mFBConOut.UgaDraw
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
if (mOriginalUgaDraw != NULL) {
|
|
Status = gBS->InstallProtocolInterface (
|
|
&gST->ConsoleOutHandle,
|
|
&gEfiUgaDrawProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mFBConOut.UgaDraw
|
|
);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutStartForGop (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
FBUpdateModeDataForGop ();
|
|
|
|
Status = gBS->ReinstallProtocolInterface (
|
|
gST->ConsoleOutHandle,
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
mOriginalGraphicsOutput,
|
|
&mFBConOut.GraphicsOutput
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
if (mOriginalGraphicsOutput != NULL) {
|
|
Status = gBS->InstallProtocolInterface (
|
|
&gST->ConsoleOutHandle,
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mFBConOut.GraphicsOutput
|
|
);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutStart (
|
|
VOID
|
|
)
|
|
{
|
|
if (FeaturePcdGet (PcdConOutUgaSupport)) {
|
|
FBConOutStartForUga ();
|
|
}
|
|
if (FeaturePcdGet (PcdConOutGopSupport)) {
|
|
FBConOutStartForGop ();
|
|
}
|
|
|
|
FBConOutStartForTextOut ();
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConOutStop (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE ConsoleOutHandle;
|
|
EFI_GUID *Guid;
|
|
|
|
ConsoleOutHandle = gST->ConsoleOutHandle;
|
|
|
|
if (mOriginalConOut != NULL) {
|
|
Status = gBS->ReinstallProtocolInterface (ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, &mFBConOut.TextOut, mOriginalConOut);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
gST->ConOut = mOriginalConOut;
|
|
gST->ConOut->SetAttribute (gST->ConOut, (EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK));
|
|
gST->ConOut->ClearScreen (gST->ConOut);
|
|
mOriginalConOut = NULL;
|
|
}
|
|
|
|
if (mOriginalUgaDraw != NULL) {
|
|
Guid = &gEfiUgaDrawProtocolGuid;
|
|
Status = gBS->ReinstallProtocolInterface (ConsoleOutHandle, Guid, &mFBConOut.UgaDraw, mOriginalUgaDraw);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mOriginalUgaDraw = NULL;
|
|
}
|
|
|
|
if (mOriginalGraphicsOutput != NULL) {
|
|
FBFreePool ((VOID **) &mFBConOut.GraphicsOutput.Mode->Info);
|
|
FBFreePool ((VOID **) &mFBConOut.GraphicsOutput.Mode);
|
|
|
|
Guid = &gEfiGraphicsOutputProtocolGuid;
|
|
Status = gBS->ReinstallProtocolInterface (ConsoleOutHandle, Guid, &mFBConOut.GraphicsOutput, mOriginalGraphicsOutput);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
mOriginalGraphicsOutput = NULL;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterUpdateModeData (
|
|
VOID
|
|
)
|
|
{
|
|
FBUpdateModeDataForTextOut ();
|
|
FBUpdateModeDataForUga ();
|
|
FBUpdateModeDataForGop ();
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterAddDevice (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
FBAddDeviceForConIn (ControllerHandle);
|
|
FBAddDeviceForConOut (ControllerHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterDeleteDevice (
|
|
IN EFI_HANDLE ControllerHandle
|
|
)
|
|
{
|
|
FBDeleteDeviceForConIn (ControllerHandle);
|
|
FBDeleteDeviceForConOut (ControllerHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterInit (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = FBConInConstructor ();
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = FBConOutConstructor ();
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterStart (
|
|
VOID
|
|
)
|
|
{
|
|
FBConInStart ();
|
|
FBConOutStart ();
|
|
|
|
gST->Hdr.CRC32 = 0;
|
|
gBS->CalculateCrc32 (
|
|
(UINT8 *) &gST->Hdr,
|
|
gST->Hdr.HeaderSize,
|
|
&gST->Hdr.CRC32
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
FBConsplitterShutdown (
|
|
VOID
|
|
)
|
|
{
|
|
FBConInStop ();
|
|
FBConOutStop ();
|
|
FBConInDeconstructor ();
|
|
FBConOutDeconstructor ();
|
|
|
|
gST->Hdr.CRC32 = 0;
|
|
gBS->CalculateCrc32 (
|
|
(UINT8 *) &gST->Hdr,
|
|
gST->Hdr.HeaderSize,
|
|
&gST->Hdr.CRC32
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|