alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/H2OFormBrowserDxe/FBConSplitter.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;
}