consplitter.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,473 行 · 第 1/5 页
C
2,473 行
}
Index --;
TextOutList ++;
}
//
// The specified TextOut is not managed by the ConSplitter driver
//
if ( Index < 0 ) {
return EFI_NOT_FOUND;
}
if ( CurrentNumOfConsoles == 0 ) {
//
// If the number of consoles is zero clear the Dev NULL device
//
Private->CurrentNumberOfConsoles = 0;
Private->TextOutMode.MaxMode = 1;
Private->TextOutQueryData[0].Columns = 80;
Private->TextOutQueryData[0].Rows = 25;
DevNullTextOutSetMode (Private, 0);
return EFI_SUCCESS;
}
//
// Max Mode is realy an intersection of the QueryMode command to all
// devices. So we must copy the QueryMode of the first device to
// QueryData.
//
EfiZeroMem (
Private->TextOutQueryData,
Private->TextOutQueryDataCount * sizeof(TEXT_OUT_SPLITTER_QUERY_DATA)
);
gBS->FreePool (Private->TextOutModeMap);
Private->TextOutModeMap = NULL;
TextOutList = Private->TextOutList;
//
// Add the first TextOut to the QueryData array and ModeMap table
//
Status = ConSplitterAddOutputMode (Private, TextOutList->TextOut);
//
// Now add one by one
//
Index = 1;
Private->CurrentNumberOfConsoles = 1;
TextOutList ++;
while ( (UINTN)Index < CurrentNumOfConsoles ) {
ConSplitterSyncOutputMode (Private, TextOutList->TextOut);
Index ++;
Private->CurrentNumberOfConsoles ++;
TextOutList ++;
}
ConSplitterGetIntersectionBetweenConOutAndStrErr();
return Status;
}
//
// ConSplitter TextIn member functions
//
EFI_STATUS
EFIAPI
ConSplitterTextInReset (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCES - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
{
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
//
// return the worst status met
//
for ( Index = 0, ReturnStatus = EFI_SUCCESS;
Index < Private->CurrentNumberOfConsoles; Index ++ ) {
Status = Private->TextInList[Index]->Reset (
Private->TextInList[Index],
ExtendedVerification
);
if (EFI_ERROR (Status)) {
ReturnStatus = Status;
}
}
return ReturnStatus;
}
EFI_STATUS
EFIAPI
ConSplitterTextInPrivateReadKeyStroke (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
OUT EFI_INPUT_KEY *Key
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
Key - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCES - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keydtroke information was not returned due to
hardware errors.
--*/
{
EFI_STATUS Status;
UINTN Index;
EFI_INPUT_KEY CurrentKey;
Key->UnicodeChar = 0;
Key->ScanCode = SCAN_NULL;
//
// if no physical console input device exists, return EFI_NOT_READY;
// if any physical console input device has key input,
// return the key and EFI_SUCCESS.
//
for ( Index = 0; Index < Private->CurrentNumberOfConsoles; Index ++ ) {
Status = Private->TextInList[Index]->ReadKeyStroke (
Private->TextInList[Index],
&CurrentKey
);
if (!EFI_ERROR (Status)) {
*Key = CurrentKey;
return Status;
}
}
return EFI_NOT_READY;
}
BOOLEAN
ConSpliterConssoleControlStdInLocked (
VOID
)
/*++
Routine Description:
Return TRUE if StdIn is locked. The ConIn device on the virtual handle is
the only device locked.
Arguments:
NONE
Returns:
TRUE - StdIn locked
FALSE - StdIn working normally
--*/
{
return mConIn.PasswordEnabled;
}
VOID
EFIAPI
ConSpliterConsoleControlLockStdInEvent (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
This timer event will fire when StdIn is locked. It will check the key
sequence on StdIn to see if it matches the password. Any error in the
password will cause the check to reset. As long a mConIn.PasswordEnabled is
TRUE the StdIn splitter will not report any input.
Arguments:
(Standard EFI_EVENT_NOTIFY)
Returns:
None
--*/
{
EFI_STATUS Status;
EFI_INPUT_KEY Key;
do {
Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);
if (!EFI_ERROR (Status)) {
//
// if it's an ENTER, match password
//
if ( (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)
&& (Key.ScanCode == SCAN_NULL) ) {
mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;
if ( EfiStrCmp(mConIn.Password, mConIn.PwdAttempt) ) {
//
// Password not match
//
ConSplitterTextOutOutputString (&mConOut.TextOut, L"\n\rPassword not correct\n\r");
mConIn.PwdIndex = 0;
} else {
//
// Key matches password sequence
//
gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);
mConIn.PasswordEnabled = FALSE;
Status = EFI_NOT_READY;
}
} else {
//
// If it's not an ENTER, record the input
//
if ( mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1) ) {
if ( mConIn.PwdIndex == 0 ) {
ConSplitterTextOutOutputString (&mConOut.TextOut, L"\n\r");
}
ConSplitterTextOutOutputString (&mConOut.TextOut, L"*");
mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;
mConIn.PwdIndex++;
}
}
}
} while (!EFI_ERROR (Status));
}
EFI_STATUS
EFIAPI
ConSpliterConsoleControlLockStdIn (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
IN CHAR16 *Password
)
/*++
Routine Description:
If Password is NULL unlock the password state variable and set the event
timer. If the Password is too big return an error. If the Password is valid
Copy the Password and enable state variable and then arm the periodic timer
Arguments:
Returns:
EFI_SUCCESS - Lock the StdIn device
EFI_INVALID_PARAMETER - Password is NULL
EFI_OUT_OF_RESOURCES - Buffer allocation to store the password fails
--*/
{
if (Password == NULL) {
return EFI_INVALID_PARAMETER;
}
if (EfiStrLen (Password) >= MAX_STD_IN_PASSWORD) {
//
// Currently have a max password size
//
return EFI_OUT_OF_RESOURCES;
}
//
// Save the password, initialize state variables and arm event timer
//
EfiStrCpy (mConIn.Password, Password);
mConIn.PasswordEnabled = TRUE;
mConIn.PwdIndex = 0;
gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ConSplitterTextInReadKeyStroke (
IN EFI_SIMPLE_TEXT_IN_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
If the ConIn is password locked make it look like no keystroke is availible
Arguments:
This - Protocol instance pointer.
Key - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCES - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keydtroke information was not returned due to
hardware errors.
--*/
{
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
if (Private->PasswordEnabled) {
//
// If StdIn Locked return not ready
//
return EFI_NOT_READY;
}
return ConSplitterTextInPrivateReadKeyStroke (Private, Key);
}
VOID
EFIAPI
ConSplitterTextInWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
This event agregates all the events of the ConIn devices in the spliter.
If the ConIn is password locked then return.
If any events of physical ConIn devices are signaled, signal the ConIn
spliter event. This will cause the calling code to call
ConSplitterTextInReadKeyStroke ().
Arguments:
Event - The Event assoicated with callback.
Context - Context registered when Event was created.
Returns:
None
--*/
{
EFI_STATUS Status;
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *)Context;
if (Private->PasswordEnabled) {
//
// If StdIn Locked return not ready
//
return;
}
//
// if any physical console input device has key input, signal the event.
//
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);
if (!EFI_ERROR (Status)) {
gBS->SignalEvent (Event);
}
}
}
EFI_STATUS
EFIAPI
ConSplitterSimplePointerReset (
IN EFI_SIMPLE_POINTER_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCES - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
{
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);
if (Private->CurrentNumberOfPointers == 0) {
return EFI_SUCCESS;
}
//
// return the worst status met
//
for (Index = 0, ReturnStatus = EFI_SUCCESS;
Index < Private->CurrentNumberOfPointers; Index++ ) {
Status = Private->PointerList[Index]->Reset (
Private->PointerList[Index],
ExtendedVerification
);
if (EFI_ERROR (Status)) {
ReturnStatus = Status;
}
}
return ReturnStatus;
}
EFI_STATUS
EFIAPI
ConSplitterSimplePointerPrivateGetState (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN OUT EFI_SIMPLE_POINTER_STATE *State
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
State -
Returns:
EFI_SUCCES - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keydtroke information was not returned due to
hardware errors.
--*/
{
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
UINTN Index;
EFI_SIMPLE_POINTER_STATE CurrentState;
State->RelativeMovementX = 0;
State->RelativeMovementY = 0;
State->RelativeMovementZ = 0;
State->LeftButton = FALSE;
State->RightButton = FALSE;
//
// if no physical console input device exists, return EFI_NOT_READY;
// if any physical console input device has key input,
// return the key and EFI_SUCCESS.
//
ReturnStatus = EFI_NOT_READY;
for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++ ) {
Status = Private->PointerList[Index]->GetState (
Private->PointerList[Index],
&CurrentState
);
if (!EFI_ERROR (Status)) {
ReturnStatus = EFI_SUCCESS;
if (CurrentState.LeftButton) {
State->LeftButton = TRUE;
}
if (CurrentState.RightButton) {
State->RightButton = TRUE;
}
if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {
State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32)Private->SimplePointerMode.ResolutionX) / (INT32)Private->PointerList[Index]->Mode->ResolutionX;
}
if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {
State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32)Private->SimplePointerMode.ResolutionY) / (INT32)Private->PointerList[Index]->Mode->ResolutionY;
}
if (CurrentState.Rela
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?