-/**@file\r
- Console Splitter Driver. Any Handle that attatched\r
- EFI_CONSOLE_IDENTIFIER_PROTOCOL can be bound by this driver.\r
+/** @file\r
+ Console Splitter Driver. Any Handle that attatched console I/O protocols\r
+ (Console In device, Console Out device, Console Error device, Simple Pointer\r
+ protocol, Absolute Pointer protocol) can be bound by this driver.\r
\r
So far it works like any other driver by opening a SimpleTextIn and/or\r
SimpleTextOut protocol with EFI_OPEN_PROTOCOL_BY_DRIVER attributes. The big\r
handle, or construct a child handle like a standard device or bus driver.\r
This driver produces three virtual handles as children, one for console input\r
splitter, one for console output splitter and one for error output splitter.\r
- EFI_CONSOLE_SPLIT_PROTOCOL will be attatched onto each virtual handle to\r
- identify the splitter type.\r
+ These 3 virtual handles would be installed on gST.\r
\r
- Each virtual handle, that supports both the EFI_CONSOLE_SPLIT_PROTOCOL\r
- and Console I/O protocol, will be produced in the driver entry point.\r
- The virtual handle are added on driver entry and never removed.\r
- Such design ensures sytem function well during none console device situation.\r
+ Each virtual handle, that supports the Console I/O protocol, will be produced\r
+ in the driver entry point. The virtual handle are added on driver entry and\r
+ never removed. Such design ensures sytem function well during none console\r
+ device situation.\r
\r
-Copyright (c) 2006 - 2007 Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "ConSplitter.h"\r
\r
//\r
-// Global Variables\r
+// Identify if ConIn is connected in PcdConInConnectOnDemand enabled mode.\r
+// default not connect\r
+//\r
+BOOLEAN mConInIsConnect = FALSE;\r
+\r
+//\r
+// Text In Splitter Private Data template\r
//\r
-STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {\r
+GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {\r
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
(EFI_HANDLE) NULL,\r
+\r
{\r
ConSplitterTextInReset,\r
ConSplitterTextInReadKeyStroke,\r
(EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,\r
0,\r
\r
+ {\r
+ ConSplitterTextInResetEx,\r
+ ConSplitterTextInReadKeyStrokeEx,\r
+ (EFI_EVENT) NULL,\r
+ ConSplitterTextInSetState,\r
+ ConSplitterTextInRegisterKeyNotify,\r
+ ConSplitterTextInUnregisterKeyNotify\r
+ },\r
+ 0,\r
+ (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **) NULL,\r
+ 0,\r
+ {\r
+ (LIST_ENTRY *) NULL,\r
+ (LIST_ENTRY *) NULL\r
+ },\r
+ (EFI_KEY_DATA *) NULL,\r
+ 0,\r
+ 0,\r
+ FALSE,\r
+\r
{\r
ConSplitterSimplePointerReset,\r
ConSplitterSimplePointerGetState,\r
(EFI_SIMPLE_POINTER_PROTOCOL **) NULL,\r
0,\r
\r
- FALSE,\r
{\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+ ConSplitterAbsolutePointerReset,\r
+ ConSplitterAbsolutePointerGetState,\r
+ (EFI_EVENT) NULL,\r
+ (EFI_ABSOLUTE_POINTER_MODE *) NULL\r
},\r
- 0,\r
{\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
+ 0, // AbsoluteMinX\r
+ 0, // AbsoluteMinY\r
+ 0, // AbsoluteMinZ\r
+ 0x10000, // AbsoluteMaxX\r
+ 0x10000, // AbsoluteMaxY\r
+ 0x10000, // AbsoluteMaxZ\r
+ 0 // Attributes\r
},\r
- (EFI_EVENT) NULL,\r
+ 0,\r
+ (EFI_ABSOLUTE_POINTER_PROTOCOL **) NULL,\r
+ 0,\r
+ FALSE,\r
\r
FALSE,\r
FALSE\r
};\r
\r
-STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
+\r
+//\r
+// Uga Draw Protocol Private Data template\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UGA_DRAW_PROTOCOL mUgaDrawProtocolTemplate = {\r
+ ConSplitterUgaDrawGetMode,\r
+ ConSplitterUgaDrawSetMode,\r
+ ConSplitterUgaDrawBlt\r
+};\r
+\r
+//\r
+// Graphics Output Protocol Private Data template\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GRAPHICS_OUTPUT_PROTOCOL mGraphicsOutputProtocolTemplate = {\r
+ ConSplitterGraphicsOutputQueryMode,\r
+ ConSplitterGraphicsOutputSetMode,\r
+ ConSplitterGraphicsOutputBlt,\r
+ NULL\r
+};\r
+\r
+\r
+//\r
+// Text Out Splitter Private Data template\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mConOut = {\r
TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
(EFI_HANDLE) NULL,\r
{\r
0,\r
FALSE,\r
},\r
+\r
{\r
- ConSpliterGraphicsOutputQueryMode,\r
- ConSpliterGraphicsOutputSetMode,\r
- ConSpliterGraphicsOutputBlt,\r
+ NULL,\r
+ NULL,\r
NULL\r
},\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
- (TEXT_OUT_GOP_MODE *) NULL,\r
0,\r
- TRUE,\r
+ 0,\r
+ 0,\r
+ 0,\r
+\r
{\r
- ConSpliterConsoleControlGetMode,\r
- ConSpliterConsoleControlSetMode,\r
- ConSpliterConsoleControlLockStdIn\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
},\r
+ (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+ 0,\r
+ 0,\r
\r
0,\r
(TEXT_OUT_AND_GOP_DATA *) NULL,\r
(TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
0,\r
(INT32 *) NULL,\r
-\r
- EfiConsoleControlScreenText,\r
- 0,\r
- 0,\r
- (CHAR16 *) NULL,\r
- (INT32 *) NULL\r
+ FALSE\r
};\r
\r
-STATIC TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
+//\r
+// Standard Error Text Out Splitter Data Template\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED TEXT_OUT_SPLITTER_PRIVATE_DATA mStdErr = {\r
TEXT_OUT_SPLITTER_PRIVATE_DATA_SIGNATURE,\r
(EFI_HANDLE) NULL,\r
{\r
0,\r
FALSE,\r
},\r
+\r
{\r
- ConSpliterGraphicsOutputQueryMode,\r
- ConSpliterGraphicsOutputSetMode,\r
- ConSpliterGraphicsOutputBlt,\r
+ NULL,\r
+ NULL,\r
NULL\r
},\r
- (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NULL,\r
- (TEXT_OUT_GOP_MODE *) NULL,\r
0,\r
- TRUE,\r
+ 0,\r
+ 0,\r
+ 0,\r
+\r
{\r
- ConSpliterConsoleControlGetMode,\r
- ConSpliterConsoleControlSetMode,\r
- ConSpliterConsoleControlLockStdIn\r
+ NULL,\r
+ NULL,\r
+ NULL,\r
+ NULL\r
},\r
+ (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *) NULL,\r
+ 0,\r
+ 0,\r
\r
0,\r
(TEXT_OUT_AND_GOP_DATA *) NULL,\r
(TEXT_OUT_SPLITTER_QUERY_DATA *) NULL,\r
0,\r
(INT32 *) NULL,\r
-\r
- EfiConsoleControlScreenText,\r
- 0,\r
- 0,\r
- (CHAR16 *) NULL,\r
- (INT32 *) NULL\r
+ FALSE\r
};\r
\r
+//\r
+// Driver binding instance for Console Input Device\r
+//\r
EFI_DRIVER_BINDING_PROTOCOL gConSplitterConInDriverBinding = {\r
ConSplitterConInDriverBindingSupported,\r
ConSplitterConInDriverBindingStart,\r
NULL\r
};\r
\r
-EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = {\r
- ConSplitterSimplePointerDriverBindingSupported,\r
- ConSplitterSimplePointerDriverBindingStart,\r
- ConSplitterSimplePointerDriverBindingStop,\r
- 0xa,\r
- NULL,\r
- NULL\r
-};\r
-\r
+//\r
+// Driver binding instance for Console Out device\r
+//\r
EFI_DRIVER_BINDING_PROTOCOL gConSplitterConOutDriverBinding = {\r
ConSplitterConOutDriverBindingSupported,\r
ConSplitterConOutDriverBindingStart,\r
NULL\r
};\r
\r
+//\r
+// Driver binding instance for Standard Error device\r
+//\r
EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding = {\r
ConSplitterStdErrDriverBindingSupported,\r
ConSplitterStdErrDriverBindingStart,\r
NULL\r
};\r
\r
+//\r
+// Driver binding instance for Simple Pointer protocol\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gConSplitterSimplePointerDriverBinding = {\r
+ ConSplitterSimplePointerDriverBindingSupported,\r
+ ConSplitterSimplePointerDriverBindingStart,\r
+ ConSplitterSimplePointerDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+//\r
+// Driver binding instance for Absolute Pointer protocol\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding = {\r
+ ConSplitterAbsolutePointerDriverBindingSupported,\r
+ ConSplitterAbsolutePointerDriverBindingStart,\r
+ ConSplitterAbsolutePointerDriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+/**\r
+ Key notify for toggle state sync.\r
+\r
+ @param KeyData A pointer to a buffer that is filled in with\r
+ the keystroke information for the key that was\r
+ pressed.\r
+\r
+ @retval EFI_SUCCESS Toggle state sync successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ToggleStateSyncKeyNotify (\r
+ IN EFI_KEY_DATA *KeyData\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ if (((KeyData->KeyState.KeyToggleState & KEY_STATE_VALID_EXPOSED) == KEY_STATE_VALID_EXPOSED) &&\r
+ (KeyData->KeyState.KeyToggleState != mConIn.PhysicalKeyToggleState)) {\r
+ //\r
+ // There is toggle state change, sync to other console input devices.\r
+ //\r
+ for (Index = 0; Index < mConIn.CurrentNumberOfExConsoles; Index++) {\r
+ mConIn.TextInExList[Index]->SetState (\r
+ mConIn.TextInExList[Index],\r
+ &KeyData->KeyState.KeyToggleState\r
+ );\r
+ }\r
+ mConIn.PhysicalKeyToggleState = KeyData->KeyState.KeyToggleState;\r
+ DEBUG ((EFI_D_INFO, "Current toggle state is 0x%02x\n", mConIn.PhysicalKeyToggleState));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Initialization for toggle state sync.\r
+\r
+ @param Private Text In Splitter pointer.\r
+\r
+**/\r
+VOID\r
+ToggleStateSyncInitialization (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private\r
+ )\r
+{\r
+ EFI_KEY_DATA KeyData;\r
+ VOID *NotifyHandle;\r
+\r
+ //\r
+ // Initialize PhysicalKeyToggleState that will be synced to new console\r
+ // input device to turn on physical TextInEx partial key report for\r
+ // toggle state sync.\r
+ //\r
+ Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;\r
+\r
+ //\r
+ // Initialize VirtualKeyStateExported to let the virtual TextInEx not report\r
+ // the partial key even though the physical TextInEx turns on the partial\r
+ // key report. The virtual TextInEx will report the partial key after it is\r
+ // required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.\r
+ //\r
+ Private->VirtualKeyStateExported = FALSE;\r
+\r
+ //\r
+ // Register key notify for toggle state sync.\r
+ //\r
+ KeyData.Key.ScanCode = SCAN_NULL;\r
+ KeyData.Key.UnicodeChar = CHAR_NULL;\r
+ KeyData.KeyState.KeyShiftState = 0;\r
+ KeyData.KeyState.KeyToggleState = 0;\r
+ Private->TextInEx.RegisterKeyNotify (\r
+ &Private->TextInEx,\r
+ &KeyData,\r
+ ToggleStateSyncKeyNotify,\r
+ &NotifyHandle\r
+ );\r
+}\r
+\r
+/**\r
+ Reinitialization for toggle state sync.\r
+\r
+ @param Private Text In Splitter pointer.\r
+\r
+**/\r
+VOID\r
+ToggleStateSyncReInitialization (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ //\r
+ // Reinitialize PhysicalKeyToggleState that will be synced to new console\r
+ // input device to turn on physical TextInEx partial key report for\r
+ // toggle state sync.\r
+ //\r
+ Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;\r
+\r
+ //\r
+ // Reinitialize VirtualKeyStateExported to let the virtual TextInEx not report\r
+ // the partial key even though the physical TextInEx turns on the partial\r
+ // key report. The virtual TextInEx will report the partial key after it is\r
+ // required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.\r
+ //\r
+ Private->VirtualKeyStateExported = FALSE;\r
+\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ Private->TextInExList[Index]->SetState (\r
+ Private->TextInExList[Index],\r
+ &Private->PhysicalKeyToggleState\r
+ );\r
+ }\r
+}\r
+\r
/**\r
- The user Entry Point for module ConSplitter. The user code starts with this function.\r
+ The Entry Point for module ConSplitter. The user code starts with this function.\r
+\r
+ Installs driver module protocols and. Creates virtual device handles for ConIn,\r
+ ConOut, and StdErr. Installs Simple Text In protocol, Simple Text In Ex protocol,\r
+ Simple Pointer protocol, Absolute Pointer protocol on those virtual handlers.\r
+ Installs Graphics Output protocol and/or UGA Draw protocol if needed.\r
\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
@param[in] SystemTable A pointer to the EFI System Table.\r
- \r
+\r
@retval EFI_SUCCESS The entry point is executed successfully.\r
@retval other Some error occurs when executing this entry point.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-InitializeConSplitter(\r
+ConSplitterDriverEntry(\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gConSplitterAbsolutePointerDriverBinding,\r
+ NULL,\r
+ &gConSplitterAbsolutePointerComponentName,\r
+ &gConSplitterAbsolutePointerComponentName2\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
Status = EfiLibInstallDriverBindingComponentName2 (\r
ImageHandle,\r
SystemTable,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
-\r
//\r
- // Call the original Entry Point\r
+ // Either Graphics Output protocol or UGA Draw protocol must be supported.\r
//\r
- Status = ConSplitterDriverEntry (ImageHandle, SystemTable);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterDriverEntry (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Intialize a virtual console device to act as an agrigator of physical console\r
- devices.\r
-\r
-Arguments:\r
- ImageHandle - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
- SystemTable - (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
-Returns:\r
- EFI_SUCCESS\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
+ ASSERT (FeaturePcdGet (PcdConOutGopSupport) ||\r
+ FeaturePcdGet (PcdConOutUgaSupport));\r
\r
//\r
- // The driver creates virtual handles for ConIn, ConOut, and StdErr.\r
+ // The driver creates virtual handles for ConIn, ConOut, StdErr.\r
// The virtual handles will always exist even if no console exist in the\r
// system. This is need to support hotplug devices like USB.\r
//\r
//\r
- // Create virtual device handle for StdErr Splitter\r
- //\r
- Status = ConSplitterTextOutConstructor (&mStdErr);\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mStdErr.VirtualHandle,\r
- &gEfiSimpleTextOutProtocolGuid,\r
- &mStdErr.TextOut,\r
- &gEfiPrimaryStandardErrorDeviceGuid,\r
- NULL,\r
- NULL\r
- );\r
- }\r
- //\r
// Create virtual device handle for ConIn Splitter\r
//\r
Status = ConSplitterTextInConstructor (&mConIn);\r
&mConIn.VirtualHandle,\r
&gEfiSimpleTextInProtocolGuid,\r
&mConIn.TextIn,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ &mConIn.TextInEx,\r
&gEfiSimplePointerProtocolGuid,\r
&mConIn.SimplePointer,\r
- &gEfiPrimaryConsoleInDeviceGuid,\r
- NULL,\r
+ &gEfiAbsolutePointerProtocolGuid,\r
+ &mConIn.AbsolutePointer,\r
NULL\r
);\r
if (!EFI_ERROR (Status)) {\r
//\r
// Update the EFI System Table with new virtual console\r
+ // and update the pointer to Simple Text Input protocol.\r
//\r
gST->ConsoleInHandle = mConIn.VirtualHandle;\r
gST->ConIn = &mConIn.TextIn;\r
//\r
Status = ConSplitterTextOutConstructor (&mConOut);\r
if (!EFI_ERROR (Status)) {\r
- //\r
- // In UEFI mode, Graphics Output Protocol is installed on virtual handle.\r
- //\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&mConOut.VirtualHandle,\r
&gEfiSimpleTextOutProtocolGuid,\r
&mConOut.TextOut,\r
- &gEfiGraphicsOutputProtocolGuid,\r
- &mConOut.GraphicsOutput,\r
- &gEfiConsoleControlProtocolGuid,\r
- &mConOut.ConsoleControl,\r
- &gEfiPrimaryConsoleOutDeviceGuid,\r
- NULL,\r
NULL\r
);\r
-\r
if (!EFI_ERROR (Status)) {\r
//\r
// Update the EFI System Table with new virtual console\r
+ // and Update the pointer to Text Output protocol.\r
//\r
gST->ConsoleOutHandle = mConOut.VirtualHandle;\r
gST->ConOut = &mConOut.TextOut;\r
}\r
\r
}\r
+\r
+ //\r
+ // Create virtual device handle for StdErr Splitter\r
+ //\r
+ Status = ConSplitterTextOutConstructor (&mStdErr);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mStdErr.VirtualHandle,\r
+ &gEfiSimpleTextOutProtocolGuid,\r
+ &mStdErr.TextOut,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Update the EFI System Table with new virtual console\r
+ // and update the pointer to Text Output protocol.\r
+ //\r
+ gST->StandardErrorHandle = mStdErr.VirtualHandle;\r
+ gST->StdErr = &mStdErr.TextOut;\r
+ }\r
+ }\r
+\r
//\r
// Update the CRC32 in the EFI System Table header\r
//\r
);\r
\r
return EFI_SUCCESS;\r
+\r
}\r
\r
+/**\r
+ Construct console input devices' private data.\r
+\r
+ @param ConInPrivate A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA\r
+ structure.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.\r
+ @retval other Failed to construct private data.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterTextInConstructor (\r
TEXT_IN_SPLITTER_PRIVATE_DATA *ConInPrivate\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Construct the ConSplitter.\r
-\r
-Arguments:\r
-\r
- ConInPrivate - A pointer to the TEXT_IN_SPLITTER_PRIVATE_DATA structure.\r
-\r
-Returns:\r
- EFI_OUT_OF_RESOURCES - Out of resources.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
+ UINTN TextInExListCount;\r
\r
//\r
- // Initilize console input splitter's private data.\r
+ // Allocate buffer for Simple Text Input device\r
//\r
Status = ConSplitterGrowBuffer (\r
sizeof (EFI_SIMPLE_TEXT_INPUT_PROTOCOL *),\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+\r
//\r
- // Create Event to support locking StdIn Device\r
+ // Create Event to wait for a key\r
//\r
- Status = gBS->CreateEvent (\r
- EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- ConSpliterConsoleControlLockStdInEvent,\r
- NULL,\r
- &ConInPrivate->LockEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_WAIT,\r
TPL_NOTIFY,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
-\r
+ //\r
+ // Allocate buffer for KeyQueue\r
+ //\r
+ TextInExListCount = ConInPrivate->TextInExListCount;\r
Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
- &ConInPrivate->PointerListCount,\r
- (VOID **) &ConInPrivate->PointerList\r
- );\r
+ sizeof (EFI_KEY_DATA),\r
+ &TextInExListCount,\r
+ (VOID **) &ConInPrivate->KeyQueue\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
+ //\r
+ // Allocate buffer for Simple Text Input Ex device\r
+ //\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
+ &ConInPrivate->TextInExListCount,\r
+ (VOID **) &ConInPrivate->TextInExList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Create Event to wait for a key Ex\r
+ //\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_WAIT,\r
TPL_NOTIFY,\r
- ConSplitterSimplePointerWaitForInput,\r
+ ConSplitterTextInWaitForKey,\r
ConInPrivate,\r
- &ConInPrivate->SimplePointer.WaitForInput\r
+ &ConInPrivate->TextInEx.WaitForKeyEx\r
);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- return Status;\r
-}\r
+ InitializeListHead (&ConInPrivate->NotifyList);\r
\r
-EFI_STATUS\r
-ConSplitterTextOutConstructor (\r
- TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate\r
- )\r
-{\r
- EFI_STATUS Status;\r
+ ToggleStateSyncInitialization (ConInPrivate);\r
\r
+ ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;\r
//\r
- // Initilize console output splitter's private data.\r
+ // Allocate buffer for Absolute Pointer device\r
//\r
- ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
-\r
Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_AND_GOP_DATA),\r
- &ConOutPrivate->TextOutListCount,\r
- (VOID **) &ConOutPrivate->TextOutList\r
+ sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
+ &ConInPrivate->AbsolutePointerListCount,\r
+ (VOID **) &ConInPrivate->AbsolutePointerList\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+ //\r
+ // Create Event to wait for device input for Absolute pointer device\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ ConSplitterAbsolutePointerWaitForInput,\r
+ ConInPrivate,\r
+ &ConInPrivate->AbsolutePointer.WaitForInput\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
\r
+ ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;\r
+ //\r
+ // Allocate buffer for Simple Pointer device\r
+ //\r
Status = ConSplitterGrowBuffer (\r
- sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
- &ConOutPrivate->TextOutQueryDataCount,\r
- (VOID **) &ConOutPrivate->TextOutQueryData\r
+ sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
+ &ConInPrivate->PointerListCount,\r
+ (VOID **) &ConInPrivate->PointerList\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
- // Setup the DevNullTextOut console to 80 x 25\r
+ // Create Event to wait for device input for Simple pointer device\r
//\r
- ConOutPrivate->TextOutQueryData[0].Columns = 80;\r
- ConOutPrivate->TextOutQueryData[0].Rows = 25;\r
- DevNullTextOutSetMode (ConOutPrivate, 0);\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_NOTIFY,\r
+ ConSplitterSimplePointerWaitForInput,\r
+ ConInPrivate,\r
+ &ConInPrivate->SimplePointer.WaitForInput\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Create Event to signal ConIn connection request\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ EfiEventEmptyFunction,\r
+ NULL,\r
+ &gConnectConInEventGuid,\r
+ &ConInPrivate->ConnectConInEvent\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Construct console output devices' private data.\r
+\r
+ @param ConOutPrivate A pointer to the TEXT_OUT_SPLITTER_PRIVATE_DATA\r
+ structure.\r
+\r
+ @retval EFI_OUT_OF_RESOURCES Out of resources.\r
+ @retval EFI_SUCCESS Text Input Devcie's private data has been constructed.\r
+\r
+**/\r
+EFI_STATUS\r
+ConSplitterTextOutConstructor (\r
+ TEXT_OUT_SPLITTER_PRIVATE_DATA *ConOutPrivate\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
\r
//\r
- // Setup resource for mode information in Graphics Output Protocol interface\r
+ // Copy protocols template\r
//\r
- if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+ CopyMem (&ConOutPrivate->UgaDraw, &mUgaDrawProtocolTemplate, sizeof (EFI_UGA_DRAW_PROTOCOL));\r
}\r
- if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
+ if (FeaturePcdGet (PcdConOutGopSupport)) {\r
+ CopyMem (&ConOutPrivate->GraphicsOutput, &mGraphicsOutputProtocolTemplate, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL));\r
}\r
+\r
+ //\r
+ // Initilize console output splitter's private data.\r
+ //\r
+ ConOutPrivate->TextOut.Mode = &ConOutPrivate->TextOutMode;\r
+\r
+ //\r
+ // When new console device is added, the new mode will be set later,\r
+ // so put current mode back to init state.\r
//\r
- // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
+ ConOutPrivate->TextOutMode.Mode = 0xFF;\r
//\r
- if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (TEXT_OUT_GOP_MODE))) == NULL) {\r
+ // Allocate buffer for Console Out device\r
+ //\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (TEXT_OUT_AND_GOP_DATA),\r
+ &ConOutPrivate->TextOutListCount,\r
+ (VOID **) &ConOutPrivate->TextOutList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- ConOutPrivate->GraphicsOutputModeBuffer[0].HorizontalResolution = 800;\r
- ConOutPrivate->GraphicsOutputModeBuffer[0].VerticalResolution = 600;\r
-\r
//\r
- // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
- // GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat\r
- // GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
+ // Allocate buffer for Text Out query data\r
//\r
- ConOutPrivate->GraphicsOutput.Mode->Info->Version = 0;\r
- ConOutPrivate->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;\r
- ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
- ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (TEXT_OUT_SPLITTER_QUERY_DATA),\r
+ &ConOutPrivate->TextOutQueryDataCount,\r
+ (VOID **) &ConOutPrivate->TextOutQueryData\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
\r
- ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
//\r
- // Initial current mode to unknow state, and then set to mode 0\r
+ // Setup the default console to 80 x 25 and mode to 0\r
//\r
- ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;\r
- ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);\r
+ ConOutPrivate->TextOutQueryData[0].Columns = 80;\r
+ ConOutPrivate->TextOutQueryData[0].Rows = 25;\r
+ TextOutSetMode (ConOutPrivate, 0);\r
\r
- return Status;\r
+\r
+ if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+ //\r
+ // Setup the UgaDraw to 800 x 600 x 32 bits per pixel, 60Hz.\r
+ //\r
+ ConSplitterUgaDrawSetMode (&ConOutPrivate->UgaDraw, 800, 600, 32, 60);\r
+ }\r
+ if (FeaturePcdGet (PcdConOutGopSupport)) {\r
+ //\r
+ // Setup resource for mode information in Graphics Output Protocol interface\r
+ //\r
+ if ((ConOutPrivate->GraphicsOutput.Mode = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE))) == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ if ((ConOutPrivate->GraphicsOutput.Mode->Info = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Setup the DevNullGraphicsOutput to 800 x 600 x 32 bits per pixel\r
+ // DevNull will be updated to user-defined mode after driver has started.\r
+ //\r
+ if ((ConOutPrivate->GraphicsOutputModeBuffer = AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ Info = &ConOutPrivate->GraphicsOutputModeBuffer[0];\r
+ Info->Version = 0;\r
+ Info->HorizontalResolution = 800;\r
+ Info->VerticalResolution = 600;\r
+ Info->PixelFormat = PixelBltOnly;\r
+ Info->PixelsPerScanLine = 800;\r
+ CopyMem (ConOutPrivate->GraphicsOutput.Mode->Info, Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+ ConOutPrivate->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+ //\r
+ // Initialize the following items, theset items remain unchanged in GraphicsOutput->SetMode()\r
+ // GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize\r
+ //\r
+ ConOutPrivate->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
+ ConOutPrivate->GraphicsOutput.Mode->FrameBufferSize = 0;\r
+\r
+ ConOutPrivate->GraphicsOutput.Mode->MaxMode = 1;\r
+ //\r
+ // Initial current mode to unknown state, and then set to mode 0\r
+ //\r
+ ConOutPrivate->GraphicsOutput.Mode->Mode = 0xffff;\r
+ ConOutPrivate->GraphicsOutput.SetMode (&ConOutPrivate->GraphicsOutput, 0);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Test to see if the specified protocol could be supported on the specified device.\r
+\r
+ @param This Driver Binding protocol pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param Guid The specified protocol.\r
+\r
+ @retval EFI_SUCCESS The specified protocol is supported on this device.\r
+ @retval EFI_UNSUPPORTED The specified protocol attempts to be installed on virtul handle.\r
+ @retval other Failed to open specified protocol on this device.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterSupported (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_GUID *Guid\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Generic Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller Handle.\r
- Guid - Guid.\r
-\r
-Returns:\r
-\r
- EFI_UNSUPPORTED - unsupported.\r
- EFI_SUCCESS - operation is OK.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
VOID *Instance;\r
//\r
// Make sure the Console Splitter does not attempt to attach to itself\r
//\r
- if (ControllerHandle == mConIn.VirtualHandle) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (ControllerHandle == mConOut.VirtualHandle) {\r
+ if (ControllerHandle == mConIn.VirtualHandle ||\r
+ ControllerHandle == mConOut.VirtualHandle ||\r
+ ControllerHandle == mStdErr.VirtualHandle\r
+ ) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- if (ControllerHandle == mStdErr.VirtualHandle) {\r
- return EFI_UNSUPPORTED;\r
- }\r
//\r
- // Check to see whether the handle has the ConsoleInDevice GUID on it\r
+ // Check to see whether the specific protocol could be opened BY_DRIVER\r
//\r
Status = gBS->OpenProtocol (\r
ControllerHandle,\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Test to see if Console In Device could be supported on the Controller.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterConInDriverBindingSupported (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Console In Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
{\r
return ConSplitterSupported (\r
This,\r
);\r
}\r
\r
+/**\r
+ Test to see if Simple Pointer protocol could be supported on the Controller.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterSimplePointerDriverBindingSupported (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Standard Error Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
{\r
return ConSplitterSupported (\r
This,\r
);\r
}\r
\r
+/**\r
+ Test to see if Absolute Pointer protocol could be supported on the Controller.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
-ConSplitterConOutDriverBindingSupported (\r
+ConSplitterAbsolutePointerDriverBindingSupported (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
+{\r
+ return ConSplitterSupported (\r
+ This,\r
+ ControllerHandle,\r
+ &gEfiAbsolutePointerProtocolGuid\r
+ );\r
+}\r
\r
-Routine Description:\r
- Console Out Supported Check\r
\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
+/**\r
+ Test to see if Console Out Device could be supported on the Controller.\r
\r
-Returns:\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
\r
- EFI_STATUS\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other This driver does not support this device.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterConOutDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
{\r
return ConSplitterSupported (\r
This,\r
);\r
}\r
\r
+/**\r
+ Test to see if Standard Error Device could be supported on the Controller.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to test.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterStdErrDriverBindingSupported (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Standard Error Supported Check\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
-\r
---*/\r
{\r
return ConSplitterSupported (\r
This,\r
);\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Start ConSplitter on devcie handle by opening Console Device Guid on device handle\r
+ and the console virtual handle. And Get the console interface on controller handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device.\r
+ @param ConSplitterVirtualHandle Console virtual Handle.\r
+ @param DeviceGuid The specified Console Device, such as ConInDev,\r
+ ConOutDev.\r
+ @param InterfaceGuid The specified protocol to be opened.\r
+ @param Interface Protocol interface returned.\r
+\r
+ @retval EFI_SUCCESS This driver supports this device.\r
+ @retval other Failed to open the specified Console Device Guid\r
+ or specified protocol.\r
+\r
+**/\r
EFI_STATUS\r
-EFIAPI\r
ConSplitterStart (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_HANDLE ConSplitterVirtualHandle,\r
IN EFI_GUID *DeviceGuid,\r
IN EFI_GUID *InterfaceGuid,\r
- IN VOID **Interface\r
+ OUT VOID **Interface\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Start() function)\r
-\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
VOID *Instance;\r
\r
//\r
- // Check to see whether the handle has the ConsoleInDevice GUID on it\r
+ // Check to see whether the ControllerHandle has the DeviceGuid on it.\r
//\r
Status = gBS->OpenProtocol (\r
ControllerHandle,\r
return Status;\r
}\r
\r
+ //\r
+ // Open the Parent Handle for the child.\r
+ //\r
Status = gBS->OpenProtocol (\r
ControllerHandle,\r
DeviceGuid,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Err;\r
}\r
\r
- return gBS->OpenProtocol (\r
+ //\r
+ // Open InterfaceGuid on the virtul handle.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
ControllerHandle,\r
InterfaceGuid,\r
Interface,\r
ConSplitterVirtualHandle,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // close the DeviceGuid on ConSplitter VirtualHandle.\r
+ //\r
+ gBS->CloseProtocol (\r
+ ControllerHandle,\r
+ DeviceGuid,\r
+ This->DriverBindingHandle,\r
+ ConSplitterVirtualHandle\r
+ );\r
+\r
+Err:\r
+ //\r
+ // close the DeviceGuid on ControllerHandle.\r
+ //\r
+ gBS->CloseProtocol (\r
+ ControllerHandle,\r
+ DeviceGuid,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle\r
+ );\r
+\r
+ return Status;\r
}\r
\r
+\r
+/**\r
+ Start Console In Consplitter on device handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS Console In Consplitter is added to ControllerHandle.\r
+ @retval other Console In Consplitter does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterConInDriverBindingStart (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_STATUS\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
\r
//\r
// Start ConSplitter on ControllerHandle, and create the virtual\r
return Status;\r
}\r
\r
- return ConSplitterTextInAddDevice (&mConIn, TextIn);\r
+ //\r
+ // Add this device into Text In devices list.\r
+ //\r
+ Status = ConSplitterTextInAddDevice (&mConIn, TextIn);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID **) &TextInEx,\r
+ This->DriverBindingHandle,\r
+ mConIn.VirtualHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If Simple Text Input Ex protocol exists,\r
+ // add this device into Text In Ex devices list.\r
+ //\r
+ Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);\r
+ }\r
+\r
+ return Status;\r
}\r
\r
+\r
+/**\r
+ Start Simple Pointer Consplitter on device handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS Simple Pointer Consplitter is added to ControllerHandle.\r
+ @retval other Simple Pointer Consplitter does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterSimplePointerDriverBindingStart (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
-\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
\r
+ //\r
+ // Start ConSplitter on ControllerHandle, and create the virtual\r
+ // agrogated console device on first call Start for a SimplePointer handle.\r
+ //\r
Status = ConSplitterStart (\r
This,\r
ControllerHandle,\r
return Status;\r
}\r
\r
+ //\r
+ // Add this devcie into Simple Pointer devices list.\r
+ //\r
return ConSplitterSimplePointerAddDevice (&mConIn, SimplePointer);\r
}\r
\r
+\r
+/**\r
+ Start Absolute Pointer Consplitter on device handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS Absolute Pointer Consplitter is added to ControllerHandle.\r
+ @retval other Absolute Pointer Consplitter does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
-ConSplitterConOutDriverBindingStart (\r
+ConSplitterAbsolutePointerDriverBindingStart (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;\r
+\r
+ //\r
+ // Start ConSplitter on ControllerHandle, and create the virtual\r
+ // agrogated console device on first call Start for a AbsolutePointer handle.\r
+ //\r
+ Status = ConSplitterStart (\r
+ This,\r
+ ControllerHandle,\r
+ mConIn.VirtualHandle,\r
+ &gEfiAbsolutePointerProtocolGuid,\r
+ &gEfiAbsolutePointerProtocolGuid,\r
+ (VOID **) &AbsolutePointer\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Add this devcie into Absolute Pointer devices list.\r
+ //\r
+ return ConSplitterAbsolutePointerAddDevice (&mConIn, AbsolutePointer);\r
+}\r
\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
+/**\r
+ Start Console Out Consplitter on device handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
+ @retval EFI_SUCCESS Console Out Consplitter is added to ControllerHandle.\r
+ @retval other Console Out Consplitter does not support this device.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterConOutDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
- EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
- EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+ EFI_UGA_DRAW_PROTOCOL *UgaDraw;\r
+ UINTN SizeOfInfo;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
\r
+ //\r
+ // Start ConSplitter on ControllerHandle, and create the virtual\r
+ // agrogated console device on first call Start for a ConsoleOut handle.\r
+ //\r
Status = ConSplitterStart (\r
This,\r
ControllerHandle,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
+ GraphicsOutput = NULL;\r
+ UgaDraw = NULL;\r
//\r
// Try to Open Graphics Output protocol\r
//\r
mConOut.VirtualHandle,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
);\r
- if (EFI_ERROR (Status)) {\r
- GraphicsOutput = NULL;\r
+\r
+ if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {\r
+ //\r
+ // Open UGA DRAW protocol\r
+ //\r
+ gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ (VOID **) &UgaDraw,\r
+ This->DriverBindingHandle,\r
+ mConOut.VirtualHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
}\r
+\r
//\r
- // Open UGA_DRAW protocol\r
+ // When new console device is added, the new mode will be set later,\r
+ // so put current mode back to init state.\r
//\r
- Status = gBS->OpenProtocol (\r
- ControllerHandle,\r
- &gEfiUgaDrawProtocolGuid,\r
- (VOID **) &UgaDraw,\r
- This->DriverBindingHandle,\r
- mConOut.VirtualHandle,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- UgaDraw = NULL;\r
- }\r
+ mConOut.TextOutMode.Mode = 0xFF;\r
+\r
//\r
// If both ConOut and StdErr incorporate the same Text Out device,\r
// their MaxMode and QueryData should be the intersection of both.\r
Status = ConSplitterTextOutAddDevice (&mConOut, TextOut, GraphicsOutput, UgaDraw);\r
ConSplitterTextOutSetAttribute (&mConOut.TextOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));\r
\r
+ if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
+ //\r
+ // Get the UGA mode data of ConOut from the current mode\r
+ //\r
+ if (GraphicsOutput != NULL) {\r
+ Status = GraphicsOutput->QueryMode (GraphicsOutput, GraphicsOutput->Mode->Mode, &SizeOfInfo, &Info);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ASSERT ( SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+\r
+ mConOut.UgaHorizontalResolution = Info->HorizontalResolution;\r
+ mConOut.UgaVerticalResolution = Info->VerticalResolution;\r
+ mConOut.UgaColorDepth = 32;\r
+ mConOut.UgaRefreshRate = 60;\r
+\r
+ FreePool (Info);\r
+\r
+ } else if (UgaDraw != NULL) {\r
+ Status = UgaDraw->GetMode (\r
+ UgaDraw,\r
+ &mConOut.UgaHorizontalResolution,\r
+ &mConOut.UgaVerticalResolution,\r
+ &mConOut.UgaColorDepth,\r
+ &mConOut.UgaRefreshRate\r
+ );\r
+ }\r
+ }\r
+\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Start Standard Error Consplitter on device handle.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to bind driver to.\r
+ @param RemainingDevicePath Optional parameter use to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCESS Standard Error Consplitter is added to ControllerHandle.\r
+ @retval other Standard Error Consplitter does not support this device.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterStdErrDriverBindingStart (\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Start ConSplitter on ControllerHandle, and create the virtual\r
- agrogated console device on first call Start for a SimpleTextIn handle.\r
-\r
-Arguments:\r
- This - Pointer to protocol.\r
- ControllerHandle - Controller handle.\r
- RemainingDevicePath - Remaining device path.\r
-\r
-Returns:\r
- EFI_ERROR if a SimpleTextIn protocol is not started.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
\r
+ //\r
+ // Start ConSplitter on ControllerHandle, and create the virtual\r
+ // agrogated console device on first call Start for a StandardError handle.\r
+ //\r
Status = ConSplitterStart (\r
This,\r
ControllerHandle,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
+ //\r
+ // When new console device is added, the new mode will be set later,\r
+ // so put current mode back to init state.\r
+ //\r
+ mStdErr.TextOutMode.Mode = 0xFF;\r
+\r
//\r
// If both ConOut and StdErr incorporate the same Text Out device,\r
// their MaxMode and QueryData should be the intersection of both.\r
//\r
Status = ConSplitterTextOutAddDevice (&mStdErr, TextOut, NULL, NULL);\r
ConSplitterTextOutSetAttribute (&mStdErr.TextOut, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- if (mStdErr.CurrentNumberOfConsoles == 1) {\r
- gST->StandardErrorHandle = mStdErr.VirtualHandle;\r
- gST->StdErr = &mStdErr.TextOut;\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
\r
return Status;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Stop ConSplitter on device handle by closing Console Device Guid on device handle\r
+ and the console virtual handle.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ControllerHandle Handle of device.\r
+ @param ConSplitterVirtualHandle Console virtual Handle.\r
+ @param DeviceGuid The specified Console Device, such as ConInDev,\r
+ ConOutDev.\r
+ @param InterfaceGuid The specified protocol to be opened.\r
+ @param Interface Protocol interface returned.\r
+\r
+ @retval EFI_SUCCESS Stop ConSplitter on ControllerHandle successfully.\r
+ @retval other Failed to Stop ConSplitter on ControllerHandle.\r
+\r
+**/\r
EFI_STATUS\r
-EFIAPI\r
ConSplitterStop (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_GUID *InterfaceGuid,\r
IN VOID **Interface\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
\r
This->DriverBindingHandle,\r
ConSplitterVirtualHandle\r
);\r
+\r
gBS->CloseProtocol (\r
ControllerHandle,\r
DeviceGuid,\r
return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Stop Console In ConSplitter on ControllerHandle by closing Console In Devcice GUID.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterConInDriverBindingStop (\r
IN UINTN NumberOfChildren,\r
IN EFI_HANDLE *ChildHandleBuffer\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
- EFI_STATUS Status;\r
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;\r
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;\r
\r
if (NumberOfChildren == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiSimpleTextInputExProtocolGuid,\r
+ (VOID **) &TextInEx,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If Simple Text Input Ex protocol exists,\r
+ // remove device from Text Input Ex devices list.\r
+ //\r
+ Status = ConSplitterTextInExDeleteDevice (&mConIn, TextInEx);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Close Simple Text In protocol on controller handle and virtual handle.\r
+ //\r
Status = ConSplitterStop (\r
This,\r
ControllerHandle,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
- // Delete this console input device's data structures.\r
+ // Remove device from Text Input devices list.\r
//\r
return ConSplitterTextInDeleteDevice (&mConIn, TextIn);\r
}\r
\r
+\r
+/**\r
+ Stop Simple Pointer protocol ConSplitter on ControllerHandle by closing\r
+ Simple Pointer protocol.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterSimplePointerDriverBindingStop (\r
IN UINTN NumberOfChildren,\r
IN EFI_HANDLE *ChildHandleBuffer\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Close Simple Pointer protocol on controller handle and virtual handle.\r
+ //\r
Status = ConSplitterStop (\r
This,\r
ControllerHandle,\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
- // Delete this console input device's data structures.\r
+ // Remove this device from Simple Pointer device list.\r
//\r
return ConSplitterSimplePointerDeleteDevice (&mConIn, SimplePointer);\r
}\r
\r
+\r
+/**\r
+ Stop Absolute Pointer protocol ConSplitter on ControllerHandle by closing\r
+ Absolute Pointer protocol.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
-ConSplitterConOutDriverBindingStop (\r
+ConSplitterAbsolutePointerDriverBindingStop (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN UINTN NumberOfChildren,\r
IN EFI_HANDLE *ChildHandleBuffer\r
)\r
-/*++\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer;\r
+\r
+ if (NumberOfChildren == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Close Absolute Pointer protocol on controller handle and virtual handle.\r
+ //\r
+ Status = ConSplitterStop (\r
+ This,\r
+ ControllerHandle,\r
+ mConIn.VirtualHandle,\r
+ &gEfiAbsolutePointerProtocolGuid,\r
+ &gEfiAbsolutePointerProtocolGuid,\r
+ (VOID **) &AbsolutePointer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Remove this device from Absolute Pointer device list.\r
+ //\r
+ return ConSplitterAbsolutePointerDeleteDevice (&mConIn, AbsolutePointer);\r
+}\r
\r
-Routine Description:\r
\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
+/**\r
+ Stop Console Out ConSplitter on device handle by closing Console Out Devcice GUID.\r
\r
-Returns:\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
\r
- None\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterConOutDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Close Absolute Pointer protocol on controller handle and virtual handle.\r
+ //\r
Status = ConSplitterStop (\r
This,\r
ControllerHandle,\r
}\r
\r
//\r
- // Delete this console output device's data structures.\r
+ // Remove this device from Text Out device list.\r
//\r
return ConSplitterTextOutDeleteDevice (&mConOut, TextOut);\r
}\r
\r
+\r
+/**\r
+ Stop Standard Error ConSplitter on ControllerHandle by closing Standard Error GUID.\r
+\r
+ @param This Driver Binding protocol instance pointer.\r
+ @param ControllerHandle Handle of device to stop driver on\r
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of\r
+ children is zero stop the entire bus driver.\r
+ @param ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCESS This driver is removed ControllerHandle\r
+ @retval other This driver was not removed from this device\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterStdErrDriverBindingStop (\r
IN UINTN NumberOfChildren,\r
IN EFI_HANDLE *ChildHandleBuffer\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- (Standard DriverBinding Protocol Stop() function)\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Complete successfully.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Close Standard Error Device on controller handle and virtual handle.\r
+ //\r
Status = ConSplitterStop (\r
This,\r
ControllerHandle,\r
//\r
// Delete this console error out device's data structures.\r
//\r
- Status = ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ return ConSplitterTextOutDeleteDevice (&mStdErr, TextOut);\r
+}\r
\r
- if (mStdErr.CurrentNumberOfConsoles == 0) {\r
- gST->StandardErrorHandle = NULL;\r
- gST->StdErr = NULL;\r
- //\r
- // Update the CRC32 in the EFI System Table header\r
- //\r
- gST->Hdr.CRC32 = 0;\r
- gBS->CalculateCrc32 (\r
- (UINT8 *) &gST->Hdr,\r
- gST->Hdr.HeaderSize,\r
- &gST->Hdr.CRC32\r
- );\r
- }\r
\r
- return Status;\r
-}\r
+/**\r
+ Take the passed in Buffer of size ElementSize and grow the buffer\r
+ by CONSOLE_SPLITTER_ALLOC_UNIT * ElementSize bytes.\r
+ Copy the current data in Buffer to the new version of Buffer and\r
+ free the old version of buffer.\r
\r
+ @param ElementSize Size of element in array.\r
+ @param Count Current number of elements in array.\r
+ @param Buffer Bigger version of passed in Buffer with all the\r
+ data.\r
+\r
+ @retval EFI_SUCCESS Buffer size has grown.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterGrowBuffer (\r
- IN UINTN SizeOfCount,\r
- IN UINTN *Count,\r
+ IN UINTN ElementSize,\r
+ IN OUT UINTN *Count,\r
IN OUT VOID **Buffer\r
)\r
-/*++\r
-\r
-Routine Description:\r
- Take the passed in Buffer of size SizeOfCount and grow the buffer\r
- by MAX (CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT, MaxGrow) * SizeOfCount\r
- bytes. Copy the current data in Buffer to the new version of Buffer\r
- and free the old version of buffer.\r
-\r
-\r
-Arguments:\r
- SizeOfCount - Size of element in array\r
- Count - Current number of elements in array\r
- Buffer - Bigger version of passed in Buffer with all the data\r
-\r
-Returns:\r
- EFI_SUCCESS - Buffer size has grown\r
- EFI_OUT_OF_RESOURCES - Could not grow the buffer size\r
-\r
- None\r
-\r
---*/\r
{\r
- UINTN NewSize;\r
- UINTN OldSize;\r
VOID *Ptr;\r
\r
//\r
// copy the old buffer's content to the new-size buffer,\r
// then free the old buffer.\r
//\r
- OldSize = *Count * SizeOfCount;\r
- *Count += CONSOLE_SPLITTER_CONSOLES_ALLOC_UNIT;\r
- NewSize = *Count * SizeOfCount;\r
-\r
- Ptr = AllocateZeroPool (NewSize);\r
+ Ptr = ReallocatePool (\r
+ ElementSize * (*Count),\r
+ ElementSize * ((*Count) + CONSOLE_SPLITTER_ALLOC_UNIT),\r
+ *Buffer\r
+ );\r
if (Ptr == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+ *Count += CONSOLE_SPLITTER_ALLOC_UNIT;\r
+ *Buffer = Ptr;\r
+ return EFI_SUCCESS;\r
+}\r
\r
- CopyMem (Ptr, *Buffer, OldSize);\r
\r
- if (*Buffer != NULL) {\r
- FreePool (*Buffer);\r
- }\r
+/**\r
+ Add Text Input Device in Consplitter Text Input list.\r
\r
- *Buffer = Ptr;\r
+ @param Private Text In Splitter pointer.\r
+ @param TextIn Simple Text Input protocol pointer.\r
\r
- return EFI_SUCCESS;\r
-}\r
+ @retval EFI_SUCCESS Text Input Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
\r
+**/\r
EFI_STATUS\r
ConSplitterTextInAddDevice (\r
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- EFI_OUT_OF_RESOURCES\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
\r
//\r
- // If the Text In List is full, enlarge it by calling growbuffer().\r
+ // If the Text In List is full, enlarge it by calling ConSplitterGrowBuffer().\r
//\r
if (Private->CurrentNumberOfConsoles >= Private->TextInListCount) {\r
Status = ConSplitterGrowBuffer (\r
Private->CurrentNumberOfConsoles++;\r
\r
//\r
- // Extra CheckEvent added to reduce the double CheckEvent() in UI.c\r
+ // Extra CheckEvent added to reduce the double CheckEvent().\r
//\r
gBS->CheckEvent (TextIn->WaitForKey);\r
\r
return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Remove Text Input Device from Consplitter Text Input list.\r
+\r
+ @param Private Text In Splitter pointer.\r
+ @param TextIn Simple Text protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Simple Text Device removed successfully.\r
+ @retval EFI_NOT_FOUND No Simple Text Device found.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterTextInDeleteDevice (\r
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS\r
- EFI_NOT_FOUND\r
-\r
---*/\r
{\r
UINTN Index;\r
//\r
//\r
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
if (Private->TextInList[Index] == TextIn) {\r
- for (Index = Index; Index < Private->CurrentNumberOfConsoles - 1; Index++) {\r
+ for (; Index < Private->CurrentNumberOfConsoles - 1; Index++) {\r
Private->TextInList[Index] = Private->TextInList[Index + 1];\r
}\r
\r
return EFI_NOT_FOUND;\r
}\r
\r
-EFI_STATUS\r
-ConSplitterSimplePointerAddDevice (\r
- IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
+/**\r
+ Add Text Input Ex Device in Consplitter Text Input Ex list.\r
\r
-Returns:\r
+ @param Private Text In Splitter pointer.\r
+ @param TextInEx Simple Text Input Ex Input protocol pointer.\r
\r
- EFI_OUT_OF_RESOURCES\r
- EFI_SUCCESS\r
+ @retval EFI_SUCCESS Text Input Ex Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+ConSplitterTextInExAddDevice (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx\r
+ )\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;\r
+ UINTN TextInExListCount;\r
\r
//\r
- // If the Text In List is full, enlarge it by calling growbuffer().\r
+ // Enlarge the NotifyHandleList and the TextInExList\r
//\r
- if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {\r
+ if (Private->CurrentNumberOfExConsoles >= Private->TextInExListCount) {\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);\r
+ TextInExListCount = Private->TextInExListCount;\r
+\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (EFI_HANDLE),\r
+ &TextInExListCount,\r
+ (VOID **) &CurrentNotify->NotifyHandleList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+ TextInExListCount = Private->TextInExListCount;\r
Status = ConSplitterGrowBuffer (\r
- sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
- &Private->PointerListCount,\r
- (VOID **) &Private->PointerList\r
+ sizeof (EFI_KEY_DATA),\r
+ &TextInExListCount,\r
+ (VOID **) &Private->KeyQueue\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),\r
+ &Private->TextInExListCount,\r
+ (VOID **) &Private->TextInExList\r
);\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
}\r
+\r
//\r
- // Add the new text-in device data structure into the Text In List.\r
+ // Register the key notify in the new text-in device\r
//\r
- Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;\r
- Private->CurrentNumberOfPointers++;\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);\r
+ Status = TextInEx->RegisterKeyNotify (\r
+ TextInEx,\r
+ &CurrentNotify->KeyData,\r
+ CurrentNotify->KeyNotificationFn,\r
+ &CurrentNotify->NotifyHandleList[Private->CurrentNumberOfExConsoles]\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ for (Link = Link->BackLink; Link != &Private->NotifyList; Link = Link->BackLink) {\r
+ CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);\r
+ TextInEx->UnregisterKeyNotify (\r
+ TextInEx,\r
+ CurrentNotify->NotifyHandleList[Private->CurrentNumberOfExConsoles]\r
+ );\r
+ }\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Add the new text-in device data structure into the Text Input Ex List.\r
+ //\r
+ Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;\r
+ Private->CurrentNumberOfExConsoles++;\r
+\r
+ //\r
+ // Sync current toggle state to this new console input device.\r
+ //\r
+ TextInEx->SetState (TextInEx, &Private->PhysicalKeyToggleState);\r
+\r
+ //\r
+ // Extra CheckEvent added to reduce the double CheckEvent().\r
+ //\r
+ gBS->CheckEvent (TextInEx->WaitForKeyEx);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Remove Text Ex Device from Consplitter Text Input Ex list.\r
+\r
+ @param Private Text In Splitter pointer.\r
+ @param TextInEx Simple Text Ex protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Simple Text Input Ex Device removed successfully.\r
+ @retval EFI_NOT_FOUND No Simple Text Input Ex Device found.\r
+\r
+**/\r
EFI_STATUS\r
-ConSplitterSimplePointerDeleteDevice (\r
+ConSplitterTextInExDeleteDevice (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx\r
+ )\r
+{\r
+ UINTN Index;\r
+ //\r
+ // Remove the specified text-in device data structure from the Text Input Ex List,\r
+ // and rearrange the remaining data structures in the Text In List.\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ if (Private->TextInExList[Index] == TextInEx) {\r
+ for (; Index < Private->CurrentNumberOfExConsoles - 1; Index++) {\r
+ Private->TextInExList[Index] = Private->TextInExList[Index + 1];\r
+ }\r
+\r
+ Private->CurrentNumberOfExConsoles--;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+ Add Simple Pointer Device in Consplitter Simple Pointer list.\r
+\r
+ @param Private Text In Splitter pointer.\r
+ @param SimplePointer Simple Pointer protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Simple Pointer Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
+\r
+**/\r
+EFI_STATUS\r
+ConSplitterSimplePointerAddDevice (\r
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
)\r
-/*++\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // If the Simple Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().\r
+ //\r
+ if (Private->CurrentNumberOfPointers >= Private->PointerListCount) {\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (EFI_SIMPLE_POINTER_PROTOCOL *),\r
+ &Private->PointerListCount,\r
+ (VOID **) &Private->PointerList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+ //\r
+ // Add the new text-in device data structure into the Simple Pointer List.\r
+ //\r
+ Private->PointerList[Private->CurrentNumberOfPointers] = SimplePointer;\r
+ Private->CurrentNumberOfPointers++;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
\r
-Routine Description:\r
\r
-Arguments:\r
+/**\r
+ Remove Simple Pointer Device from Consplitter Simple Pointer list.\r
\r
-Returns:\r
+ @param Private Text In Splitter pointer.\r
+ @param SimplePointer Simple Pointer protocol pointer.\r
\r
- None\r
+ @retval EFI_SUCCESS Simple Pointer Device removed successfully.\r
+ @retval EFI_NOT_FOUND No Simple Pointer Device found.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+ConSplitterSimplePointerDeleteDevice (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer\r
+ )\r
{\r
UINTN Index;\r
//\r
- // Remove the specified text-in device data structure from the Text In List,\r
+ // Remove the specified text-in device data structure from the Simple Pointer List,\r
// and rearrange the remaining data structures in the Text In List.\r
//\r
for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
if (Private->PointerList[Index] == SimplePointer) {\r
- for (Index = Index; Index < Private->CurrentNumberOfPointers - 1; Index++) {\r
+ for (; Index < Private->CurrentNumberOfPointers - 1; Index++) {\r
Private->PointerList[Index] = Private->PointerList[Index + 1];\r
}\r
\r
return EFI_NOT_FOUND;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Add Absolute Pointer Device in Consplitter Absolute Pointer list.\r
+\r
+ @param Private Text In Splitter pointer.\r
+ @param AbsolutePointer Absolute Pointer protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Absolute Pointer Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
+\r
+**/\r
EFI_STATUS\r
-ConSplitterGrowMapTable (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
+ConSplitterAbsolutePointerAddDevice (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // If the Absolute Pointer List is full, enlarge it by calling ConSplitterGrowBuffer().\r
+ //\r
+ if (Private->CurrentNumberOfAbsolutePointers >= Private->AbsolutePointerListCount) {\r
+ Status = ConSplitterGrowBuffer (\r
+ sizeof (EFI_ABSOLUTE_POINTER_PROTOCOL *),\r
+ &Private->AbsolutePointerListCount,\r
+ (VOID **) &Private->AbsolutePointerList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+ //\r
+ // Add the new text-in device data structure into the Absolute Pointer List.\r
+ //\r
+ Private->AbsolutePointerList[Private->CurrentNumberOfAbsolutePointers] = AbsolutePointer;\r
+ Private->CurrentNumberOfAbsolutePointers++;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Remove Absolute Pointer Device from Consplitter Absolute Pointer list.\r
+\r
+ @param Private Text In Splitter pointer.\r
+ @param AbsolutePointer Absolute Pointer protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Absolute Pointer Device removed successfully.\r
+ @retval EFI_NOT_FOUND No Absolute Pointer Device found.\r
+\r
+**/\r
+EFI_STATUS\r
+ConSplitterAbsolutePointerDeleteDevice (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *AbsolutePointer\r
)\r
-/*++\r
+{\r
+ UINTN Index;\r
+ //\r
+ // Remove the specified text-in device data structure from the Absolute Pointer List,\r
+ // and rearrange the remaining data structures from the Absolute Pointer List.\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
+ if (Private->AbsolutePointerList[Index] == AbsolutePointer) {\r
+ for (; Index < Private->CurrentNumberOfAbsolutePointers - 1; Index++) {\r
+ Private->AbsolutePointerList[Index] = Private->AbsolutePointerList[Index + 1];\r
+ }\r
+\r
+ Private->CurrentNumberOfAbsolutePointers--;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
\r
-Routine Description:\r
+/**\r
+ Reallocate Text Out mode map.\r
\r
-Arguments:\r
+ Allocate new buffer and copy original buffer into the new buffer.\r
\r
-Returns:\r
+ @param Private Consplitter Text Out pointer.\r
\r
- None\r
+ @retval EFI_SUCCESS Buffer size has grown\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+ConSplitterGrowMapTable (\r
+ IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
+ )\r
{\r
UINTN Size;\r
UINTN NewSize;\r
INT32 *OldTextOutModeMap;\r
INT32 *SrcAddress;\r
INT32 Index;\r
+ UINTN OldStepSize;\r
+ UINTN NewStepSize;\r
\r
NewSize = Private->TextOutListCount * sizeof (INT32);\r
OldTextOutModeMap = Private->TextOutModeMap;\r
- TotalSize = NewSize * Private->TextOutQueryDataCount;\r
+ TotalSize = NewSize * (Private->TextOutQueryDataCount);\r
\r
- TextOutModeMap = AllocateZeroPool (TotalSize);\r
+ //\r
+ // Allocate new buffer for Text Out List.\r
+ //\r
+ TextOutModeMap = AllocatePool (TotalSize);\r
if (TextOutModeMap == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
Size = Private->CurrentNumberOfConsoles * sizeof (INT32);\r
Index = 0;\r
SrcAddress = OldTextOutModeMap;\r
+ NewStepSize = NewSize / sizeof(INT32);\r
+ // If Private->CurrentNumberOfConsoles is not zero and OldTextOutModeMap\r
+ // is not NULL, it indicates that the original TextOutModeMap is not enough\r
+ // for the new console devices and has been enlarged by CONSOLE_SPLITTER_ALLOC_UNIT columns.\r
+ //\r
+ OldStepSize = NewStepSize - CONSOLE_SPLITTER_ALLOC_UNIT;\r
\r
//\r
// Copy the old data to the new one\r
//\r
while (Index < Private->TextOutMode.MaxMode) {\r
CopyMem (TextOutModeMap, SrcAddress, Size);\r
- TextOutModeMap += NewSize;\r
- SrcAddress += Size;\r
+ //\r
+ // Go to next row of new TextOutModeMap.\r
+ //\r
+ TextOutModeMap += NewStepSize;\r
+ //\r
+ // Go to next row of old TextOutModeMap.\r
+ //\r
+ SrcAddress += OldStepSize;\r
Index++;\r
}\r
//\r
return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Add new device's output mode to console splitter's mode list.\r
+\r
+ @param Private Text Out Splitter pointer\r
+ @param TextOut Simple Text Output protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterAddOutputMode (\r
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
INT32 MaxMode;\r
Mode = 0;\r
Index = 0;\r
while (Mode < MaxMode) {\r
- TextOut->QueryMode (\r
- TextOut,\r
- Mode,\r
- &Private->TextOutQueryData[Mode].Columns,\r
- &Private->TextOutQueryData[Mode].Rows\r
- );\r
+ Status = TextOut->QueryMode (\r
+ TextOut,\r
+ Mode,\r
+ &Private->TextOutQueryData[Mode].Columns,\r
+ &Private->TextOutQueryData[Mode].Rows\r
+ );\r
+ //\r
+ // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData\r
+ // is clear to 0x0.\r
+ //\r
+ if ((EFI_ERROR(Status)) && (Mode == 1)) {\r
+ Private->TextOutQueryData[Mode].Columns = 0;\r
+ Private->TextOutQueryData[Mode].Rows = 0;\r
+ }\r
Private->TextOutModeMap[Index] = Mode;\r
Mode++;\r
Index += Private->TextOutListCount;\r
return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
+/**\r
+ Reconstruct TextOutModeMap to get intersection of modes.\r
+\r
+ This routine reconstruct TextOutModeMap to get the intersection\r
+ of modes for all console out devices. Because EFI/UEFI spec require\r
+ mode 0 is 80x25, mode 1 is 80x50, this routine will not check the\r
+ intersection for mode 0 and mode 1.\r
+\r
+ @param TextOutModeMap Current text out mode map, begin with the mode 80x25\r
+ @param NewlyAddedMap New text out mode map, begin with the mode 80x25\r
+ @param MapStepSize Mode step size for one console device\r
+ @param NewMapStepSize New Mode step size for one console device\r
+ @param MaxMode IN: Current max text mode, OUT: Updated max text mode.\r
+ @param CurrentMode IN: Current text mode, OUT: Updated current text mode.\r
+\r
+**/\r
VOID\r
ConSplitterGetIntersection (\r
- IN INT32 *TextOutModeMap,\r
- IN INT32 *NewlyAddedMap,\r
- IN UINTN MapStepSize,\r
- IN UINTN NewMapStepSize,\r
- OUT INT32 *MaxMode,\r
- OUT INT32 *CurrentMode\r
+ IN INT32 *TextOutModeMap,\r
+ IN INT32 *NewlyAddedMap,\r
+ IN UINTN MapStepSize,\r
+ IN UINTN NewMapStepSize,\r
+ IN OUT INT32 *MaxMode,\r
+ IN OUT INT32 *CurrentMode\r
)\r
{\r
INT32 Index;\r
INT32 *CurrentMapEntry;\r
INT32 *NextMapEntry;\r
+ INT32 *NewMapEntry;\r
INT32 CurrentMaxMode;\r
INT32 Mode;\r
\r
- Index = 0;\r
- CurrentMapEntry = TextOutModeMap;\r
- NextMapEntry = TextOutModeMap;\r
+ //\r
+ // According to EFI/UEFI spec, mode 0 and mode 1 have been reserved\r
+ // for 80x25 and 80x50 in Simple Text Out protocol, so don't make intersection\r
+ // for mode 0 and mode 1, mode number starts from 2.\r
+ //\r
+ Index = 2;\r
+ CurrentMapEntry = &TextOutModeMap[MapStepSize * 2];\r
+ NextMapEntry = CurrentMapEntry;\r
+ NewMapEntry = &NewlyAddedMap[NewMapStepSize * 2];\r
+\r
CurrentMaxMode = *MaxMode;\r
Mode = *CurrentMode;\r
\r
while (Index < CurrentMaxMode) {\r
- if (*NewlyAddedMap == -1) {\r
+ if (*NewMapEntry == -1) {\r
//\r
// This mode is not supported any more. Remove it. Special care\r
// must be taken as this remove will also affect current mode;\r
}\r
\r
CurrentMapEntry += MapStepSize;\r
- NewlyAddedMap += NewMapStepSize;\r
+ NewMapEntry += NewMapStepSize;\r
Index++;\r
}\r
\r
return ;\r
}\r
\r
-STATIC\r
+/**\r
+ Sync the device's output mode to console splitter's mode list.\r
+\r
+ @param Private Text Out Splitter pointer.\r
+ @param TextOut Simple Text Output protocol pointer.\r
+\r
+**/\r
VOID\r
ConSplitterSyncOutputMode (\r
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
- Private - Private data structure.\r
- TextOut - Text Out Protocol.\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
INT32 CurrentMaxMode;\r
INT32 Mode;\r
INT32 Index;\r
INT32 *TextOutModeMap;\r
INT32 *MapTable;\r
+ INT32 QueryMode;\r
TEXT_OUT_SPLITTER_QUERY_DATA *TextOutQueryData;\r
UINTN Rows;\r
UINTN Columns;\r
UINTN StepSize;\r
+ EFI_STATUS Status;\r
\r
//\r
// Must make sure that current mode won't change even if mode number changes\r
Mode = 0;\r
MapTable = TextOutModeMap + Private->CurrentNumberOfConsoles;\r
while (Mode < TextOut->Mode->MaxMode) {\r
- TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
+ Status = TextOut->QueryMode (TextOut, Mode, &Columns, &Rows);\r
\r
+ if (EFI_ERROR(Status)) {\r
+ if (Mode == 1) {\r
+ //\r
+ // If mode 1 (80x50) is not supported, make sure mode 1 in TextOutQueryData\r
+ // is clear to 0x0.\r
+ //\r
+ MapTable[StepSize] = Mode;\r
+ TextOutQueryData[Mode].Columns = 0;\r
+ TextOutQueryData[Mode].Rows = 0;\r
+ }\r
+ Mode++;\r
+ continue;\r
+ }\r
//\r
- // Search the QueryData database to see if they intersects\r
+ // Search the intersection map and QueryData database to see if they intersects\r
//\r
Index = 0;\r
while (Index < CurrentMaxMode) {\r
- if ((TextOutQueryData[Index].Rows == Rows) && (TextOutQueryData[Index].Columns == Columns)) {\r
+ QueryMode = *(TextOutModeMap + Index * StepSize);\r
+ if ((TextOutQueryData[QueryMode].Rows == Rows) && (TextOutQueryData[QueryMode].Columns == Columns)) {\r
MapTable[Index * StepSize] = Mode;\r
break;\r
}\r
-\r
Index++;\r
}\r
-\r
Mode++;\r
}\r
//\r
return ;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Sync output device between ConOut and StdErr output.\r
+\r
+ @retval EFI_SUCCESS Sync implemented successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterGetIntersectionBetweenConOutAndStrErr (\r
VOID\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
- EFI_OUT_OF_RESOURCES\r
-\r
---*/\r
{\r
UINTN ConOutNumOfConsoles;\r
UINTN StdErrNumOfConsoles;\r
TEXT_OUT_AND_GOP_DATA *StdErrTextOutList;\r
UINTN Indexi;\r
UINTN Indexj;\r
- UINTN Rows;\r
- UINTN Columns;\r
+ UINTN ConOutRows;\r
+ UINTN ConOutColumns;\r
+ UINTN StdErrRows;\r
+ UINTN StdErrColumns;\r
INT32 ConOutMaxMode;\r
INT32 StdErrMaxMode;\r
+ INT32 ConOutMode;\r
+ INT32 StdErrMode;\r
INT32 Mode;\r
INT32 Index;\r
INT32 *ConOutModeMap;\r
INT32 *StdErrMapTable;\r
TEXT_OUT_SPLITTER_QUERY_DATA *ConOutQueryData;\r
TEXT_OUT_SPLITTER_QUERY_DATA *StdErrQueryData;\r
+ UINTN ConOutStepSize;\r
+ UINTN StdErrStepSize;\r
BOOLEAN FoundTheSameTextOut;\r
UINTN ConOutMapTableSize;\r
UINTN StdErrMapTableSize;\r
//\r
ConOutMaxMode = mConOut.TextOutMode.MaxMode;\r
ConOutModeMap = mConOut.TextOutModeMap;\r
+ ConOutStepSize = mConOut.TextOutListCount;\r
ConOutQueryData = mConOut.TextOutQueryData;\r
\r
StdErrMaxMode = mStdErr.TextOutMode.MaxMode;\r
StdErrModeMap = mStdErr.TextOutModeMap;\r
+ StdErrStepSize = mStdErr.TextOutListCount;\r
StdErrQueryData = mStdErr.TextOutQueryData;\r
\r
//\r
\r
//\r
// Find the intersection of the two set of modes. If they actually intersect, the\r
- // correponding entry in the map table is set to 1.\r
+ // corresponding entry in the map table is set to 1.\r
//\r
Mode = 0;\r
while (Mode < ConOutMaxMode) {\r
//\r
- // Search the other's QueryData database to see if they intersect\r
+ // Search the intersection map and QueryData database to see if they intersect\r
//\r
- Index = 0;\r
- Rows = ConOutQueryData[Mode].Rows;\r
- Columns = ConOutQueryData[Mode].Columns;\r
+ Index = 0;\r
+ ConOutMode = *(ConOutModeMap + Mode * ConOutStepSize);\r
+ ConOutRows = ConOutQueryData[ConOutMode].Rows;\r
+ ConOutColumns = ConOutQueryData[ConOutMode].Columns;\r
while (Index < StdErrMaxMode) {\r
- if ((StdErrQueryData[Index].Rows == Rows) && (StdErrQueryData[Index].Columns == Columns)) {\r
+ StdErrMode = *(StdErrModeMap + Index * StdErrStepSize);\r
+ StdErrRows = StdErrQueryData[StdErrMode].Rows;\r
+ StdErrColumns = StdErrQueryData[StdErrMode].Columns;\r
+ if ((StdErrRows == ConOutRows) && (StdErrColumns == ConOutColumns)) {\r
ConOutMapTable[Mode] = 1;\r
StdErrMapTable[Index] = 1;\r
break;\r
&(mConOut.TextOutMode.MaxMode),\r
&(mConOut.TextOutMode.Mode)\r
);\r
+\r
if (mConOut.TextOutMode.Mode < 0) {\r
mConOut.TextOut.SetMode (&(mConOut.TextOut), 0);\r
}\r
&(mStdErr.TextOutMode.MaxMode),\r
&(mStdErr.TextOutMode.Mode)\r
);\r
+\r
if (mStdErr.TextOutMode.Mode < 0) {\r
mStdErr.TextOut.SetMode (&(mStdErr.TextOut), 0);\r
}\r
return EFI_SUCCESS;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Add Grahpics Output modes into Consplitter Text Out list.\r
+\r
+ @param Private Text Out Splitter pointer.\r
+ @param GraphicsOutput Graphics Output protocol pointer.\r
+ @param UgaDraw UGA Draw protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Output mode added successfully.\r
+ @retval other Failed to add output mode.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterAddGraphicsOutputMode (\r
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
UINTN Index;\r
- TEXT_OUT_GOP_MODE *Mode;\r
+ UINTN CurrentIndex;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode;\r
UINTN SizeOfInfo;\r
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *CurrentGraphicsOutputMode;\r
- TEXT_OUT_GOP_MODE *ModeBuffer;\r
- TEXT_OUT_GOP_MODE *MatchedMode;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeBuffer;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *MatchedMode;\r
UINTN NumberIndex;\r
BOOLEAN Match;\r
+ BOOLEAN AlreadyExist;\r
+ UINT32 UgaHorizontalResolution;\r
+ UINT32 UgaVerticalResolution;\r
+ UINT32 UgaColorDepth;\r
+ UINT32 UgaRefreshRate;\r
\r
- if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
+ ASSERT (GraphicsOutput != NULL || UgaDraw != NULL);\r
\r
CurrentGraphicsOutputMode = Private->GraphicsOutput.Mode;\r
\r
+ Index = 0;\r
+ CurrentIndex = 0;\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (Private->CurrentNumberOfUgaDraw != 0) {\r
+ //\r
+ // If any UGA device has already been added, then there is no need to\r
+ // calculate intersection of display mode of different GOP/UGA device,\r
+ // since only one display mode will be exported (i.e. user-defined mode)\r
+ //\r
+ goto Done;\r
+ }\r
+\r
if (GraphicsOutput != NULL) {\r
if (Private->CurrentNumberOfGraphicsOutput == 0) {\r
//\r
//\r
// Allocate resource for the private mode buffer\r
//\r
- ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * GraphicsOutput->Mode->MaxMode);\r
+ ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * GraphicsOutput->Mode->MaxMode);\r
if (ModeBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r
Mode = ModeBuffer;\r
for (Index = 0; Index < GraphicsOutput->Mode->MaxMode; Index++) {\r
+ //\r
+ // The Info buffer would be allocated by callee\r
+ //\r
Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) Index, &SizeOfInfo, &Info);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- Mode->HorizontalResolution = Info->HorizontalResolution;\r
- Mode->VerticalResolution = Info->VerticalResolution;\r
+ ASSERT ( SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+ CopyMem (Mode, Info, SizeOfInfo);\r
Mode++;\r
FreePool (Info);\r
}\r
//\r
// Check intersection of display mode\r
//\r
- ModeBuffer = AllocatePool (sizeof (TEXT_OUT_GOP_MODE) * CurrentGraphicsOutputMode->MaxMode);\r
+ ModeBuffer = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION) * CurrentGraphicsOutputMode->MaxMode);\r
if (ModeBuffer == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
Match = FALSE;\r
\r
for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex++) {\r
+ //\r
+ // The Info buffer would be allocated by callee\r
+ //\r
Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
- (Info->VerticalResolution == Mode->VerticalResolution)){\r
+ (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+ //\r
+ // If GOP device supports one mode in current mode buffer,\r
+ // it will be added into matched mode buffer\r
+ //\r
Match = TRUE;\r
FreePool (Info);\r
break;\r
}\r
\r
if (Match) {\r
- CopyMem (MatchedMode, Mode, sizeof (TEXT_OUT_GOP_MODE));\r
- MatchedMode++;\r
+ AlreadyExist = FALSE;\r
+\r
+ //\r
+ // Check if GOP mode has been in the mode buffer, ModeBuffer = MatchedMode at begin.\r
+ //\r
+ for (Info = ModeBuffer; Info < MatchedMode; Info++) {\r
+ if ((Info->HorizontalResolution == Mode->HorizontalResolution) &&\r
+ (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+ AlreadyExist = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!AlreadyExist) {\r
+ CopyMem (MatchedMode, Mode, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+\r
+ //\r
+ // Physical frame buffer is no longer available, change PixelFormat to PixelBltOnly\r
+ //\r
+ MatchedMode->Version = 0;\r
+ MatchedMode->PixelFormat = PixelBltOnly;\r
+ ZeroMem (&MatchedMode->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
+\r
+ MatchedMode++;\r
+ }\r
}\r
\r
Mode++;\r
//\r
// Physical frame buffer is no longer available when there are more than one physical GOP devices\r
//\r
- CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (TEXT_OUT_GOP_MODE));\r
+ CurrentGraphicsOutputMode->MaxMode = (UINT32) (((UINTN) MatchedMode - (UINTN) ModeBuffer) / sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
ZeroMem (&CurrentGraphicsOutputMode->Info->PixelInformation, sizeof (EFI_PIXEL_BITMASK));\r
CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+ CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
}\r
\r
//\r
- // Select a prefered Display mode 800x600\r
+ // Graphics console driver can ensure the same mode for all GOP devices\r
//\r
for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
Mode = &Private->GraphicsOutputModeBuffer[Index];\r
- if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
+ if ((Mode->HorizontalResolution == GraphicsOutput->Mode->Info->HorizontalResolution) &&\r
+ (Mode->VerticalResolution == GraphicsOutput->Mode->Info->VerticalResolution)) {\r
+ CurrentIndex = Index;\r
break;\r
}\r
}\r
- //\r
- // Prefered mode is not found, set to mode 0\r
- //\r
if (Index >= CurrentGraphicsOutputMode->MaxMode) {\r
- Index = 0;\r
+ //\r
+ // if user defined mode is not found, set to default mode 800x600\r
+ //\r
+ for (Index = 0; Index < CurrentGraphicsOutputMode->MaxMode; Index++) {\r
+ Mode = &Private->GraphicsOutputModeBuffer[Index];\r
+ if ((Mode->HorizontalResolution == 800) && (Mode->VerticalResolution == 600)) {\r
+ CurrentIndex = Index;\r
+ break;\r
+ }\r
+ }\r
}\r
-\r
- //\r
- // Current mode number may need update now, so set it to an invalide mode number\r
- //\r
- CurrentGraphicsOutputMode->Mode = 0xffff;\r
- } else {\r
+ } else if (UgaDraw != NULL) {\r
//\r
- // For UGA device, it's inconvenient to retrieve all the supported display modes.\r
- // To simplify the implementation, only add one resolution(800x600, 32bit color depth) as defined in UEFI spec\r
+ // Graphics console driver can ensure the same mode for all GOP devices\r
+ // so we can get the current mode from this video device\r
//\r
+ UgaDraw->GetMode (\r
+ UgaDraw,\r
+ &UgaHorizontalResolution,\r
+ &UgaVerticalResolution,\r
+ &UgaColorDepth,\r
+ &UgaRefreshRate\r
+ );\r
+\r
CurrentGraphicsOutputMode->MaxMode = 1;\r
- CurrentGraphicsOutputMode->Info->Version = 0;\r
- CurrentGraphicsOutputMode->Info->HorizontalResolution = 800;\r
- CurrentGraphicsOutputMode->Info->VerticalResolution = 600;\r
- CurrentGraphicsOutputMode->Info->PixelFormat = PixelBltOnly;\r
- CurrentGraphicsOutputMode->Info->PixelsPerScanLine = 800;\r
- CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
- CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) NULL;\r
+ Info = CurrentGraphicsOutputMode->Info;\r
+ Info->Version = 0;\r
+ Info->HorizontalResolution = UgaHorizontalResolution;\r
+ Info->VerticalResolution = UgaVerticalResolution;\r
+ Info->PixelFormat = PixelBltOnly;\r
+ Info->PixelsPerScanLine = UgaHorizontalResolution;\r
+ CurrentGraphicsOutputMode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+ CurrentGraphicsOutputMode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;\r
CurrentGraphicsOutputMode->FrameBufferSize = 0;\r
\r
//\r
// Update the private mode buffer\r
//\r
- ModeBuffer = &Private->GraphicsOutputModeBuffer[0];\r
- ModeBuffer->HorizontalResolution = 800;\r
- ModeBuffer->VerticalResolution = 600;\r
+ CopyMem (&Private->GraphicsOutputModeBuffer[0], Info, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
\r
//\r
- // Current mode is unknow now, set it to an invalid mode number 0xffff\r
+ // Only mode 0 is available to be set\r
//\r
- CurrentGraphicsOutputMode->Mode = 0xffff;\r
- Index = 0;\r
+ CurrentIndex = 0;\r
+ }\r
+\r
+Done:\r
+\r
+ if (GraphicsOutput != NULL) {\r
+ Private->CurrentNumberOfGraphicsOutput++;\r
+ }\r
+ if (UgaDraw != NULL) {\r
+ Private->CurrentNumberOfUgaDraw++;\r
}\r
\r
//\r
// Force GraphicsOutput mode to be set,\r
- // regardless whether the console is in EfiConsoleControlScreenGraphics or EfiConsoleControlScreenText mode\r
//\r
- Private->HardwareNeedsStarting = TRUE;\r
- Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) Index);\r
-\r
- Private->CurrentNumberOfGraphicsOutput++;\r
-\r
- return Status;\r
-}\r
\r
-EFI_STATUS\r
-ConSplitterTextOutAddDevice (\r
- IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut,\r
- IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
- IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
+ Mode = &Private->GraphicsOutputModeBuffer[CurrentIndex];\r
+ if ((GraphicsOutput != NULL) &&\r
+ (Mode->HorizontalResolution == CurrentGraphicsOutputMode->Info->HorizontalResolution) &&\r
+ (Mode->VerticalResolution == CurrentGraphicsOutputMode->Info->VerticalResolution)) {\r
+ CurrentGraphicsOutputMode->Mode = (UINT32) CurrentIndex;\r
+ if ((Mode->HorizontalResolution != GraphicsOutput->Mode->Info->HorizontalResolution) ||\r
+ (Mode->VerticalResolution != GraphicsOutput->Mode->Info->VerticalResolution)) {\r
+ //\r
+ // If all existing video device has been set to common mode, only set new GOP device to\r
+ // the common mode\r
+ //\r
+ for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {\r
+ Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {\r
+ FreePool (Info);\r
+ break;\r
+ }\r
+ FreePool (Info);\r
+ }\r
+ Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);\r
+ }\r
+ } else {\r
+ //\r
+ // Current mode number may need update now, so set it to an invalid mode number\r
+ //\r
+ CurrentGraphicsOutputMode->Mode = 0xffff;\r
+ //\r
+ // Graphics console can ensure all GOP devices have the same mode which can be taken as current mode.\r
+ //\r
+ Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, (UINT32) CurrentIndex);\r
+ if (EFI_ERROR(Status)) {\r
+ //\r
+ // If user defined mode is not valid for display device, set to the default mode 800x600.\r
+ //\r
+ (Private->GraphicsOutputModeBuffer[0]).HorizontalResolution = 800;\r
+ (Private->GraphicsOutputModeBuffer[0]).VerticalResolution = 600;\r
+ Status = Private->GraphicsOutput.SetMode (&Private->GraphicsOutput, 0);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set the current console out mode.\r
+\r
+ This routine will get the current console mode information (column, row)\r
+ from ConsoleOutMode variable and set it; if the variable does not exist,\r
+ set to user defined console mode.\r
+\r
+ @param Private Consplitter Text Out pointer.\r
+\r
+**/\r
+VOID\r
+ConsplitterSetConsoleOutMode (\r
+ IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private\r
)\r
-/*++\r
+{\r
+ UINTN Col;\r
+ UINTN Row;\r
+ UINTN Mode;\r
+ UINTN PreferMode;\r
+ UINTN BaseMode;\r
+ UINTN MaxMode;\r
+ EFI_STATUS Status;\r
+ CONSOLE_OUT_MODE ModeInfo;\r
+ CONSOLE_OUT_MODE MaxModeInfo;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;\r
+\r
+ PreferMode = 0xFF;\r
+ BaseMode = 0xFF;\r
+ TextOut = &Private->TextOut;\r
+ MaxMode = (UINTN) (TextOut->Mode->MaxMode);\r
\r
-Routine Description:\r
+ MaxModeInfo.Column = 0;\r
+ MaxModeInfo.Row = 0;\r
+ ModeInfo.Column = PcdGet32 (PcdConOutColumn);\r
+ ModeInfo.Row = PcdGet32 (PcdConOutRow);\r
\r
-Arguments:\r
+ //\r
+ // To find the prefer mode and basic mode from Text Out mode list\r
+ //\r
+ for (Mode = 0; Mode < MaxMode; Mode++) {\r
+ Status = TextOut->QueryMode (TextOut, Mode, &Col, &Row);\r
+ if (!EFI_ERROR(Status)) {\r
+ if ((ModeInfo.Column != 0) && (ModeInfo.Row != 0)) {\r
+ //\r
+ // Use user defined column and row\r
+ //\r
+ if (Col == ModeInfo.Column && Row == ModeInfo.Row) {\r
+ PreferMode = Mode;\r
+ }\r
+ } else {\r
+ //\r
+ // If user sets PcdConOutColumn or PcdConOutRow to 0,\r
+ // find and set the highest text mode.\r
+ //\r
+ if ((Col >= MaxModeInfo.Column) && (Row >= MaxModeInfo.Row)) {\r
+ MaxModeInfo.Column = Col;\r
+ MaxModeInfo.Row = Row;\r
+ PreferMode = Mode;\r
+ }\r
+ }\r
+ if (Col == 80 && Row == 25) {\r
+ BaseMode = Mode;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set prefer mode to Text Out devices.\r
+ //\r
+ Status = TextOut->SetMode (TextOut, PreferMode);\r
+ if (EFI_ERROR(Status)) {\r
+ //\r
+ // if current mode setting is failed, default 80x25 mode will be set.\r
+ //\r
+ Status = TextOut->SetMode (TextOut, BaseMode);\r
+ ASSERT(!EFI_ERROR(Status));\r
+\r
+ Status = PcdSet32S (PcdConOutColumn, 80);\r
+ ASSERT(!EFI_ERROR(Status));\r
+ Status = PcdSet32S (PcdConOutRow, 25);\r
+ ASSERT(!EFI_ERROR(Status));\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+\r
+/**\r
+ Add Text Output Device in Consplitter Text Output list.\r
\r
-Returns:\r
+ @param Private Text Out Splitter pointer.\r
+ @param TextOut Simple Text Output protocol pointer.\r
+ @param GraphicsOutput Graphics Output protocol pointer.\r
+ @param UgaDraw UGA Draw protocol pointer.\r
\r
- None\r
+ @retval EFI_SUCCESS Text Output Device added successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Could not grow the buffer size.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+ConSplitterTextOutAddDevice (\r
+ IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut,\r
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,\r
+ IN EFI_UGA_DRAW_PROTOCOL *UgaDraw\r
+ )\r
{\r
- EFI_STATUS Status;\r
- UINTN CurrentNumOfConsoles;\r
- INT32 CurrentMode;\r
- INT32 MaxMode;\r
- TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
+ EFI_STATUS Status;\r
+ UINTN CurrentNumOfConsoles;\r
+ INT32 MaxMode;\r
+ UINT32 UgaHorizontalResolution;\r
+ UINT32 UgaVerticalResolution;\r
+ UINT32 UgaColorDepth;\r
+ UINT32 UgaRefreshRate;\r
+ TEXT_OUT_AND_GOP_DATA *TextAndGop;\r
+ UINTN SizeOfInfo;\r
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;\r
+ EFI_STATUS DeviceStatus;\r
\r
- Status = EFI_SUCCESS;\r
- CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
+ Status = EFI_SUCCESS;\r
+ CurrentNumOfConsoles = Private->CurrentNumberOfConsoles;\r
+ Private->AddingConOutDevice = TRUE;\r
\r
//\r
- // If the Text Out List is full, enlarge it by calling growbuffer().\r
+ // If the Text Out List is full, enlarge it by calling ConSplitterGrowBuffer().\r
//\r
while (CurrentNumOfConsoles >= Private->TextOutListCount) {\r
Status = ConSplitterGrowBuffer (\r
\r
TextAndGop = &Private->TextOutList[CurrentNumOfConsoles];\r
\r
- TextAndGop->TextOut = TextOut;\r
+ TextAndGop->TextOut = TextOut;\r
TextAndGop->GraphicsOutput = GraphicsOutput;\r
- TextAndGop->UgaDraw = UgaDraw;\r
-\r
- if ((GraphicsOutput == NULL) && (UgaDraw == NULL)) {\r
- //\r
- // If No UGA device then use the ConOut device\r
- //\r
- TextAndGop->TextOutEnabled = TRUE;\r
- } else {\r
- //\r
- // If UGA device use ConOut device only used if UGA screen is in Text mode\r
- //\r
- TextAndGop->TextOutEnabled = (BOOLEAN) (Private->ConsoleOutputMode == EfiConsoleControlScreenText);\r
- }\r
+ TextAndGop->UgaDraw = UgaDraw;\r
\r
if (CurrentNumOfConsoles == 0) {\r
//\r
//\r
ConSplitterGetIntersectionBetweenConOutAndStrErr ();\r
\r
- CurrentMode = Private->TextOutMode.Mode;\r
MaxMode = Private->TextOutMode.MaxMode;\r
ASSERT (MaxMode >= 1);\r
\r
+ DeviceStatus = EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
+\r
+ //\r
+ // This device display mode will be added into Graphics Ouput modes.\r
+ //\r
if ((GraphicsOutput != NULL) || (UgaDraw != NULL)) {\r
- ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
+ DeviceStatus = ConSplitterAddGraphicsOutputMode (Private, GraphicsOutput, UgaDraw);\r
}\r
\r
- if (Private->ConsoleOutputMode == EfiConsoleControlScreenGraphics && GraphicsOutput != NULL) {\r
- //\r
- // We just added a new UGA device in graphics mode\r
- //\r
- DevNullGopSync (Private, GraphicsOutput, UgaDraw);\r
- } else if ((CurrentMode >= 0) && ((GraphicsOutput != NULL) || (UgaDraw != NULL)) && (CurrentMode < Private->TextOutMode.MaxMode)) {\r
- //\r
- // The new console supports the same mode of the current console so sync up\r
+ if (FeaturePcdGet (PcdConOutUgaSupport)) {\r
//\r
- DevNullSyncGopStdOut (Private);\r
- } else {\r
- //\r
- // If ConOut, then set the mode to Mode #0 which us 80 x 25\r
+ // If UGA is produced by Consplitter\r
//\r
- Private->TextOut.SetMode (&Private->TextOut, 0);\r
+ if (GraphicsOutput != NULL) {\r
+ Status = GraphicsOutput->QueryMode (GraphicsOutput, GraphicsOutput->Mode->Mode, &SizeOfInfo, &Info);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ASSERT ( SizeOfInfo <= sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+\r
+ UgaHorizontalResolution = Info->HorizontalResolution;\r
+ UgaVerticalResolution = Info->VerticalResolution;\r
+\r
+ FreePool (Info);\r
+\r
+ } else if (UgaDraw != NULL) {\r
+ Status = UgaDraw->GetMode (\r
+ UgaDraw,\r
+ &UgaHorizontalResolution,\r
+ &UgaVerticalResolution,\r
+ &UgaColorDepth,\r
+ &UgaRefreshRate\r
+ );\r
+ if (!EFI_ERROR (Status) && EFI_ERROR (DeviceStatus)) {\r
+ //\r
+ // if GetMode is successfully and UGA device hasn't been set, set it\r
+ //\r
+ Status = ConSplitterUgaDrawSetMode (\r
+ &Private->UgaDraw,\r
+ UgaHorizontalResolution,\r
+ UgaVerticalResolution,\r
+ UgaColorDepth,\r
+ UgaRefreshRate\r
+ );\r
+ }\r
+ //\r
+ // If GetMode/SetMode is failed, set to 800x600 mode\r
+ //\r
+ if(EFI_ERROR (Status)) {\r
+ Status = ConSplitterUgaDrawSetMode (\r
+ &Private->UgaDraw,\r
+ 800,\r
+ 600,\r
+ 32,\r
+ 60\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ if (((!EFI_ERROR (DeviceStatus)) || (!EFI_ERROR (Status))) &&\r
+ ((Private->CurrentNumberOfGraphicsOutput + Private->CurrentNumberOfUgaDraw) == 1)) {\r
+ if (!FeaturePcdGet (PcdConOutGopSupport)) {\r
+ //\r
+ // If Graphics Outpurt protocol not supported, UGA Draw protocol is installed\r
+ // on the virtual handle.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mConOut.VirtualHandle,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &mConOut.UgaDraw,\r
+ NULL\r
+ );\r
+ } else if (!FeaturePcdGet (PcdConOutUgaSupport)) {\r
+ //\r
+ // If UGA Draw protocol not supported, Graphics Output Protocol is installed\r
+ // on virtual handle.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mConOut.VirtualHandle,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &mConOut.GraphicsOutput,\r
+ NULL\r
+ );\r
+ } else {\r
+ //\r
+ // Boot Graphics Output protocol and UGA Draw protocol are supported,\r
+ // both they will be installed on virtual handle.\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mConOut.VirtualHandle,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &mConOut.GraphicsOutput,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &mConOut.UgaDraw,\r
+ NULL\r
+ );\r
+ }\r
}\r
\r
+ //\r
+ // After adding new console device, all existing console devices should be\r
+ // synced to the current shared mode.\r
+ //\r
+ ConsplitterSetConsoleOutMode (Private);\r
+\r
+ Private->AddingConOutDevice = FALSE;\r
+\r
return Status;\r
}\r
\r
+\r
+/**\r
+ Remove Text Out Device in Consplitter Text Out list.\r
+\r
+ @param Private Text Out Splitter pointer.\r
+ @param TextOut Simple Text Output Pointer protocol pointer.\r
+\r
+ @retval EFI_SUCCESS Text Out Device removed successfully.\r
+ @retval EFI_NOT_FOUND No Text Out Device found.\r
+\r
+**/\r
EFI_STATUS\r
ConSplitterTextOutDeleteDevice (\r
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
INT32 Index;\r
UINTN CurrentNumOfConsoles;\r
TextOutList = Private->TextOutList;\r
while (Index >= 0) {\r
if (TextOutList->TextOut == TextOut) {\r
+ if (TextOutList->UgaDraw != NULL) {\r
+ Private->CurrentNumberOfUgaDraw--;\r
+ }\r
+ if (TextOutList->GraphicsOutput != NULL) {\r
+ Private->CurrentNumberOfGraphicsOutput--;\r
+ }\r
CopyMem (TextOutList, TextOutList + 1, sizeof (TEXT_OUT_AND_GOP_DATA) * Index);\r
CurrentNumOfConsoles--;\r
break;\r
return EFI_NOT_FOUND;\r
}\r
\r
+ if ((Private->CurrentNumberOfGraphicsOutput == 0) && (Private->CurrentNumberOfUgaDraw == 0)) {\r
+ //\r
+ // If there is not any physical GOP and UGA device in system,\r
+ // Consplitter GOP or UGA protocol will be uninstalled\r
+ //\r
+ if (!FeaturePcdGet (PcdConOutGopSupport)) {\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Private->VirtualHandle,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &Private->UgaDraw\r
+ );\r
+ } else if (!FeaturePcdGet (PcdConOutUgaSupport)) {\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Private->VirtualHandle,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &Private->GraphicsOutput\r
+ );\r
+ } else {\r
+ Status = gBS->UninstallMultipleProtocolInterfaces (\r
+ Private->VirtualHandle,\r
+ &gEfiUgaDrawProtocolGuid,\r
+ &Private->UgaDraw,\r
+ &gEfiGraphicsOutputProtocolGuid,\r
+ &Private->GraphicsOutput,\r
+ NULL\r
+ );\r
+ }\r
+ }\r
+\r
if (CurrentNumOfConsoles == 0) {\r
//\r
- // If the number of consoles is zero clear the Dev NULL device\r
+ // If the number of consoles is zero, reset all parameters\r
//\r
Private->CurrentNumberOfConsoles = 0;\r
Private->TextOutMode.MaxMode = 1;\r
Private->TextOutQueryData[0].Columns = 80;\r
Private->TextOutQueryData[0].Rows = 25;\r
- DevNullTextOutSetMode (Private, 0);\r
+ TextOutSetMode (Private, 0);\r
\r
return EFI_SUCCESS;\r
}\r
\r
return Status;\r
}\r
-//\r
-// ConSplitter TextIn member functions\r
-//\r
+\r
+\r
+/**\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextInReset (\r
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
IN BOOLEAN ExtendedVerification\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Reset the input device and optionaly run diagnostics\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform diagnostics on reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The device was reset.\r
- EFI_DEVICE_ERROR - The device is not functioning properly and could\r
- not be reset.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_STATUS ReturnStatus;\r
}\r
}\r
\r
+ if (!EFI_ERROR (ReturnStatus)) {\r
+ ToggleStateSyncReInitialization (Private);\r
+ //\r
+ // Empty the key queue.\r
+ //\r
+ Private->CurrentNumberOfKeys = 0;\r
+ }\r
+\r
return ReturnStatus;\r
}\r
\r
+/**\r
+ Dequeue the saved key from internal key queue.\r
+\r
+ @param Private Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
+ @retval EFI_NOT_FOUND Queue is empty.\r
+ @retval EFI_SUCCESS First key is dequeued and returned.\r
+**/\r
EFI_STATUS\r
-EFIAPI\r
-ConSplitterTextInPrivateReadKeyStroke (\r
+ConSplitterTextInExDequeueKey (\r
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
- OUT EFI_INPUT_KEY *Key\r
+ OUT EFI_KEY_DATA *KeyData\r
)\r
-/*++\r
+{\r
+ if (Private->CurrentNumberOfKeys == 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Return the first saved key.\r
+ //\r
+ CopyMem (KeyData, &Private->KeyQueue[0], sizeof (EFI_KEY_DATA));\r
+ Private->CurrentNumberOfKeys--;\r
+ CopyMem (\r
+ &Private->KeyQueue[0],\r
+ &Private->KeyQueue[1],\r
+ Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA)\r
+ );\r
+ return EFI_SUCCESS;\r
+}\r
\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Key - Driver may perform diagnostics on reset.\r
+ @param Private Protocol instance pointer.\r
+ @param Key Driver may perform diagnostics on reset.\r
\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keydtroke information was not returned due\r
+ to hardware errors.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInPrivateReadKeyStroke (\r
+ IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
+ OUT EFI_INPUT_KEY *Key\r
+ )\r
{\r
EFI_STATUS Status;\r
UINTN Index;\r
- EFI_INPUT_KEY CurrentKey;\r
+ EFI_KEY_DATA KeyData;\r
+\r
+ //\r
+ // Return the first saved non-NULL key.\r
+ //\r
+ while (TRUE) {\r
+ Status = ConSplitterTextInExDequeueKey (Private, &KeyData);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+ return Status;\r
+ }\r
+ }\r
\r
Key->UnicodeChar = 0;\r
Key->ScanCode = SCAN_NULL;\r
// if any physical console input device has key input,\r
// return the key and EFI_SUCCESS.\r
//\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+ for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {\r
Status = Private->TextInList[Index]->ReadKeyStroke (\r
Private->TextInList[Index],\r
- &CurrentKey\r
+ &KeyData.Key\r
);\r
if (!EFI_ERROR (Status)) {\r
- *Key = CurrentKey;\r
- return Status;\r
+ //\r
+ // If it is not partial keystorke, return the key. Otherwise, continue\r
+ // to read key from THIS physical console input device.\r
+ //\r
+ if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {\r
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
+ return Status;\r
+ }\r
+ } else {\r
+ //\r
+ // Continue to read key from NEXT physical console input device.\r
+ //\r
+ Index++;\r
}\r
}\r
\r
return EFI_NOT_READY;\r
}\r
\r
-BOOLEAN\r
-ConSpliterConssoleControlStdInLocked (\r
- VOID\r
- )\r
-/*++\r
\r
-Routine Description:\r
- Return TRUE if StdIn is locked. The ConIn device on the virtual handle is\r
- the only device locked.\r
\r
-Arguments:\r
- NONE\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
\r
-Returns:\r
- TRUE - StdIn locked\r
- FALSE - StdIn working normally\r
+ @param This Protocol instance pointer.\r
+ @param Key Driver may perform diagnostics on reset.\r
\r
---*/\r
-{\r
- return mConIn.PasswordEnabled;\r
-}\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keydtroke information was not returned due\r
+ to hardware errors.\r
\r
-VOID\r
+**/\r
+EFI_STATUS\r
EFIAPI\r
-ConSpliterConsoleControlLockStdInEvent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ConSplitterTextInReadKeyStroke (\r
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
+ OUT EFI_INPUT_KEY *Key\r
)\r
-/*++\r
-\r
-Routine Description:\r
- This timer event will fire when StdIn is locked. It will check the key\r
- sequence on StdIn to see if it matches the password. Any error in the\r
- password will cause the check to reset. As long a mConIn.PasswordEnabled is\r
- TRUE the StdIn splitter will not report any input.\r
-\r
-Arguments:\r
- (Standard EFI_EVENT_NOTIFY)\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
{\r
- EFI_STATUS Status;\r
- EFI_INPUT_KEY Key;\r
- CHAR16 BackSpaceString[2];\r
- CHAR16 SpaceString[2];\r
-\r
- do {\r
- Status = ConSplitterTextInPrivateReadKeyStroke (&mConIn, &Key);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // if it's an ENTER, match password\r
- //\r
- if ((Key.UnicodeChar == CHAR_CARRIAGE_RETURN) && (Key.ScanCode == SCAN_NULL)) {\r
- mConIn.PwdAttempt[mConIn.PwdIndex] = CHAR_NULL;\r
- if (StrCmp (mConIn.Password, mConIn.PwdAttempt)) {\r
- //\r
- // Password not match\r
- //\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\rPassword not correct\n\r");\r
- mConIn.PwdIndex = 0;\r
- } else {\r
- //\r
- // Key matches password sequence\r
- //\r
- gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, 0);\r
- mConIn.PasswordEnabled = FALSE;\r
- Status = EFI_NOT_READY;\r
- }\r
- } else if ((Key.UnicodeChar == CHAR_BACKSPACE) && (Key.ScanCode == SCAN_NULL)) {\r
- //\r
- // BackSpace met\r
- //\r
- if (mConIn.PwdIndex > 0) {\r
- BackSpaceString[0] = CHAR_BACKSPACE;\r
- BackSpaceString[1] = 0;\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
\r
- SpaceString[0] = ' ';\r
- SpaceString[1] = 0;\r
+ Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, SpaceString);\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, BackSpaceString);\r
+ Private->KeyEventSignalState = FALSE;\r
\r
- mConIn.PwdIndex--;\r
- }\r
- } else if ((Key.ScanCode == SCAN_NULL) && (Key.UnicodeChar >= 32)) {\r
- //\r
- // If it's not an ENTER, neigher a function key, nor a CTRL-X or ALT-X, record the input\r
- //\r
- if (mConIn.PwdIndex < (MAX_STD_IN_PASSWORD - 1)) {\r
- if (mConIn.PwdIndex == 0) {\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"\n\r");\r
- }\r
+ //\r
+ // Signal ConnectConIn event on first call in Lazy ConIn mode\r
+ //\r
+ if (!mConInIsConnect && PcdGetBool (PcdConInConnectOnDemand)) {\r
+ DEBUG ((EFI_D_INFO, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));\r
+ gBS->SignalEvent (Private->ConnectConInEvent);\r
+ mConInIsConnect = TRUE;\r
+ }\r
\r
- ConSplitterTextOutOutputString (&mConOut.TextOut, (CHAR16 *) L"*");\r
- mConIn.PwdAttempt[mConIn.PwdIndex] = Key.UnicodeChar;\r
- mConIn.PwdIndex++;\r
- }\r
- }\r
- }\r
- } while (!EFI_ERROR (Status));\r
+ return ConSplitterTextInPrivateReadKeyStroke (Private, Key);\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-ConSpliterConsoleControlLockStdIn (\r
- IN EFI_CONSOLE_CONTROL_PROTOCOL *This,\r
- IN CHAR16 *Password\r
- )\r
-/*++\r
\r
-Routine Description:\r
- If Password is NULL unlock the password state variable and set the event\r
- timer. If the Password is too big return an error. If the Password is valid\r
- Copy the Password and enable state variable and then arm the periodic timer\r
+/**\r
+ This event aggregates all the events of the ConIn devices in the spliter.\r
\r
-Arguments:\r
+ If any events of physical ConIn devices are signaled, signal the ConIn\r
+ spliter event. This will cause the calling code to call\r
+ ConSplitterTextInReadKeyStroke ().\r
\r
-Returns:\r
- EFI_SUCCESS - Lock the StdIn device\r
- EFI_INVALID_PARAMETER - Password is NULL\r
- EFI_OUT_OF_RESOURCES - Buffer allocation to store the password fails\r
+ @param Event The Event assoicated with callback.\r
+ @param Context Context registered when Event was created.\r
\r
---*/\r
+**/\r
+VOID\r
+EFIAPI\r
+ConSplitterTextInWaitForKey (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
{\r
- if (Password == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
+ EFI_STATUS Status;\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN Index;\r
\r
- if (StrLen (Password) >= MAX_STD_IN_PASSWORD) {\r
- //\r
- // Currently have a max password size\r
+ Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
+\r
+ if (Private->KeyEventSignalState) {\r
//\r
- return EFI_OUT_OF_RESOURCES;\r
+ // If KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
+ //\r
+ gBS->SignalEvent (Event);\r
+ return ;\r
}\r
+\r
//\r
- // Save the password, initialize state variables and arm event timer\r
+ // If any physical console input device has key input, signal the event.\r
//\r
- StrCpy (mConIn.Password, Password);\r
- mConIn.PasswordEnabled = TRUE;\r
- mConIn.PwdIndex = 0;\r
- gBS->SetTimer (mConIn.LockEvent, TimerPeriodic, (10000 * 25));\r
+ for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+ Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->SignalEvent (Event);\r
+ Private->KeyEventSignalState = TRUE;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+/**\r
+ Test if the key has been registered on input device.\r
+\r
+ @param RegsiteredData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ registered.\r
+ @param InputData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
+\r
+ @retval TRUE Key be pressed matches a registered key.\r
+ @retval FLASE Match failed.\r
+\r
+**/\r
+BOOLEAN\r
+IsKeyRegistered (\r
+ IN EFI_KEY_DATA *RegsiteredData,\r
+ IN EFI_KEY_DATA *InputData\r
+ )\r
+{\r
+ ASSERT (RegsiteredData != NULL && InputData != NULL);\r
+\r
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
+ //\r
+ if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
+ RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
+ return FALSE;\r
+ }\r
+ if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
+ RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
\r
- return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Reset the input device and optionaly run diagnostics\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
-ConSplitterTextInReadKeyStroke (\r
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
- OUT EFI_INPUT_KEY *Key\r
+ConSplitterTextInResetEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
)\r
-/*++\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS ReturnStatus;\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN Index;\r
+\r
+ Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ Private->KeyEventSignalState = FALSE;\r
+\r
+ //\r
+ // return the worst status met\r
+ //\r
+ for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ Status = Private->TextInExList[Index]->Reset (\r
+ Private->TextInExList[Index],\r
+ ExtendedVerification\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
+ }\r
+ }\r
\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
- If the ConIn is password locked make it look like no keystroke is availible\r
+ if (!EFI_ERROR (ReturnStatus)) {\r
+ ToggleStateSyncReInitialization (Private);\r
+ //\r
+ // Empty the key queue.\r
+ //\r
+ Private->CurrentNumberOfKeys = 0;\r
+ }\r
+\r
+ return ReturnStatus;\r
+\r
+}\r
+\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Key - Driver may perform diagnostics on reset.\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with the\r
+ keystroke state data for the key that was\r
+ pressed.\r
\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due\r
+ to hardware errors.\r
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInReadKeyStrokeEx (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ OUT EFI_KEY_DATA *KeyData\r
+ )\r
{\r
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_KEY_STATE KeyState;\r
+ EFI_KEY_DATA CurrentKeyData;\r
+\r
+\r
+ if (KeyData == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ Private->KeyEventSignalState = FALSE;\r
+\r
+ //\r
+ // Signal ConnectConIn event on first call in Lazy ConIn mode\r
+ //\r
+ if (!mConInIsConnect && PcdGetBool (PcdConInConnectOnDemand)) {\r
+ DEBUG ((EFI_D_INFO, "Connect ConIn in first ReadKeyStoke in Lazy ConIn mode.\n"));\r
+ gBS->SignalEvent (Private->ConnectConInEvent);\r
+ mConInIsConnect = TRUE;\r
+ }\r
+\r
+ //\r
+ // Return the first saved key.\r
+ //\r
+ Status = ConSplitterTextInExDequeueKey (Private, KeyData);\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ASSERT (Private->CurrentNumberOfKeys == 0);\r
+\r
+ ZeroMem (&KeyState, sizeof (KeyState));\r
+\r
+ //\r
+ // Iterate through all physical consoles to get key state.\r
+ // Some physical consoles may return valid key.\r
+ // Queue the valid keys.\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ ZeroMem (&CurrentKeyData, sizeof (EFI_KEY_DATA));\r
+ Status = Private->TextInExList[Index]->ReadKeyStrokeEx (\r
+ Private->TextInExList[Index],\r
+ &CurrentKeyData\r
+ );\r
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {\r
+ continue;\r
+ }\r
\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
- if (Private->PasswordEnabled) {\r
//\r
- // If StdIn Locked return not ready\r
+ // Consolidate the key state from all physical consoles.\r
//\r
- return EFI_NOT_READY;\r
+ if ((CurrentKeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) {\r
+ KeyState.KeyShiftState |= CurrentKeyData.KeyState.KeyShiftState;\r
+ }\r
+ if ((CurrentKeyData.KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != 0) {\r
+ KeyState.KeyToggleState |= CurrentKeyData.KeyState.KeyToggleState;\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If virtual KeyState has been required to be exposed, or it is not\r
+ // partial keystorke, queue the key.\r
+ // It's possible that user presses at multiple keyboards at the same moment,\r
+ // Private->KeyQueue[] are the storage to save all the keys.\r
+ //\r
+ if ((Private->VirtualKeyStateExported) ||\r
+ (CurrentKeyData.Key.ScanCode != CHAR_NULL) ||\r
+ (CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {\r
+ CopyMem (\r
+ &Private->KeyQueue[Private->CurrentNumberOfKeys],\r
+ &CurrentKeyData,\r
+ sizeof (EFI_KEY_DATA)\r
+ );\r
+ Private->CurrentNumberOfKeys++;\r
+ }\r
+ }\r
}\r
\r
- Private->KeyEventSignalState = FALSE;\r
+ //\r
+ // Consolidate the key state for all keys in Private->KeyQueue[]\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfKeys; Index++) {\r
+ CopyMem (&Private->KeyQueue[Index].KeyState, &KeyState, sizeof (EFI_KEY_STATE));\r
+ }\r
\r
- return ConSplitterTextInPrivateReadKeyStroke (Private, Key);\r
+ //\r
+ // Return the first saved key.\r
+ //\r
+ Status = ConSplitterTextInExDequeueKey (Private, KeyData);\r
+ if (!EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Always return the key state even there is no key pressed.\r
+ //\r
+ ZeroMem (&KeyData->Key, sizeof (KeyData->Key));\r
+ CopyMem (&KeyData->KeyState, &KeyState, sizeof (KeyData->KeyState));\r
+ return EFI_NOT_READY;\r
}\r
\r
-VOID\r
+\r
+/**\r
+ Set certain state for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
+ state for the input device.\r
+\r
+ @retval EFI_SUCCESS The device state was set successfully.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and\r
+ could not have the setting adjusted.\r
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its\r
+ state.\r
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
EFIAPI\r
-ConSplitterTextInWaitForKey (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ConSplitterTextInSetState (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
)\r
-/*++\r
+{\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ EFI_KEY_TOGGLE_STATE PhysicalKeyToggleState;\r
\r
-Routine Description:\r
- This event agregates all the events of the ConIn devices in the spliter.\r
- If the ConIn is password locked then return.\r
- If any events of physical ConIn devices are signaled, signal the ConIn\r
- spliter event. This will cause the calling code to call\r
- ConSplitterTextInReadKeyStroke ().\r
+ if (KeyToggleState == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
-Arguments:\r
- Event - The Event assoicated with callback.\r
- Context - Context registered when Event was created.\r
+ Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
-Returns:\r
- None\r
+ //\r
+ // Always turn on physical TextInEx partial key report for\r
+ // toggle state sync.\r
+ //\r
+ PhysicalKeyToggleState = *KeyToggleState | EFI_KEY_STATE_EXPOSED;\r
\r
---*/\r
+ //\r
+ // if no physical console input device exists, return EFI_SUCCESS;\r
+ // otherwise return the status of setting state of physical console input device\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ Status = Private->TextInExList[Index]->SetState (\r
+ Private->TextInExList[Index],\r
+ &PhysicalKeyToggleState\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Record the physical KeyToggleState.\r
+ //\r
+ Private->PhysicalKeyToggleState = PhysicalKeyToggleState;\r
+ //\r
+ // Get if virtual KeyState has been required to be exposed.\r
+ //\r
+ Private->VirtualKeyStateExported = (((*KeyToggleState) & EFI_KEY_STATE_EXPOSED) != 0);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+}\r
+\r
+\r
+/**\r
+ Register a notification function for a particular keystroke for the input device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param KeyData A pointer to a buffer that is filled in with\r
+ the keystroke information for the key that was\r
+ pressed. If KeyData.Key, KeyData.KeyState.KeyToggleState\r
+ and KeyData.KeyState.KeyShiftState are 0, then any incomplete\r
+ keystroke will trigger a notification of the KeyNotificationFunction.\r
+ @param KeyNotificationFunction Points to the function to be called when the key\r
+ sequence is typed specified by KeyData. This notification function\r
+ should be called at <=TPL_CALLBACK.\r
+ @param NotifyHandle Points to the unique handle assigned to the\r
+ registered notification.\r
+\r
+ @retval EFI_SUCCESS The notification function was registered\r
+ successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data\r
+ structures.\r
+ @retval EFI_INVALID_PARAMETER KeyData or KeyNotificationFunction or NotifyHandle is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterTextInRegisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN EFI_KEY_DATA *KeyData,\r
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
+ OUT VOID **NotifyHandle\r
+ )\r
{\r
- EFI_STATUS Status;\r
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
UINTN Index;\r
+ TEXT_IN_EX_SPLITTER_NOTIFY *NewNotify;\r
+ LIST_ENTRY *Link;\r
+ TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;\r
\r
- Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return ;\r
+\r
+ if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
}\r
\r
+ Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
//\r
- // if KeyEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
//\r
- if (Private->KeyEventSignalState) {\r
- gBS->SignalEvent (Event);\r
- return ;\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);\r
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
+ *NotifyHandle = CurrentNotify;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
}\r
+\r
//\r
- // if any physical console input device has key input, signal the event.\r
+ // Allocate resource to save the notification function\r
//\r
- for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- Status = gBS->CheckEvent (Private->TextInList[Index]->WaitForKey);\r
- if (!EFI_ERROR (Status)) {\r
- gBS->SignalEvent (Event);\r
- Private->KeyEventSignalState = TRUE;\r
+ NewNotify = (TEXT_IN_EX_SPLITTER_NOTIFY *) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY));\r
+ if (NewNotify == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ NewNotify->NotifyHandleList = (EFI_HANDLE *) AllocateZeroPool (sizeof (EFI_HANDLE) * Private->TextInExListCount);\r
+ if (NewNotify->NotifyHandleList == NULL) {\r
+ gBS->FreePool (NewNotify);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ NewNotify->Signature = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;\r
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
+\r
+ //\r
+ // Return the wrong status of registering key notify of\r
+ // physical console input device if meet problems\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ Status = Private->TextInExList[Index]->RegisterKeyNotify (\r
+ Private->TextInExList[Index],\r
+ KeyData,\r
+ KeyNotificationFunction,\r
+ &NewNotify->NotifyHandleList[Index]\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Un-register the key notify on all physical console input devices\r
+ //\r
+ while (Index-- != 0) {\r
+ Private->TextInExList[Index]->UnregisterKeyNotify (\r
+ Private->TextInExList[Index],\r
+ NewNotify->NotifyHandleList[Index]\r
+ );\r
+ }\r
+ gBS->FreePool (NewNotify->NotifyHandleList);\r
+ gBS->FreePool (NewNotify);\r
+ return Status;\r
}\r
}\r
+\r
+ InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);\r
+\r
+ *NotifyHandle = NewNotify;\r
+\r
+ return EFI_SUCCESS;\r
+\r
}\r
\r
+\r
+/**\r
+ Remove a registered notification function from a particular keystroke.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param NotificationHandle The handle of the notification function being\r
+ unregistered.\r
+\r
+ @retval EFI_SUCCESS The notification function was unregistered\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
-ConSplitterSimplePointerReset (\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
- IN BOOLEAN ExtendedVerification\r
+ConSplitterTextInUnregisterKeyNotify (\r
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
+ IN VOID *NotificationHandle\r
)\r
-/*++\r
+{\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN Index;\r
+ TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;\r
+ LIST_ENTRY *Link;\r
\r
- Routine Description:\r
- Reset the input device and optionaly run diagnostics\r
+ if (NotificationHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {\r
+ CurrentNotify = TEXT_IN_EX_SPLITTER_NOTIFY_FROM_THIS (Link);\r
+ if (CurrentNotify == NotificationHandle) {\r
+ for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {\r
+ Private->TextInExList[Index]->UnregisterKeyNotify (\r
+ Private->TextInExList[Index],\r
+ CurrentNotify->NotifyHandleList[Index]\r
+ );\r
+ }\r
+ RemoveEntryList (&CurrentNotify->NotifyEntry);\r
+\r
+ gBS->FreePool (CurrentNotify->NotifyHandleList);\r
+ gBS->FreePool (CurrentNotify);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // NotificationHandle is not found in database\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+\r
+/**\r
+ Reset the input device and optionaly run diagnostics\r
\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform diagnostics on reset.\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
\r
- Returns:\r
- EFI_SUCCESS - The device was reset.\r
- EFI_DEVICE_ERROR - The device is not functioning properly and could\r
- not be reset.\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterSimplePointerReset (\r
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
{\r
EFI_STATUS Status;\r
EFI_STATUS ReturnStatus;\r
return ReturnStatus;\r
}\r
\r
-STATIC\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ @param Private Protocol instance pointer.\r
+ @param State The state information of simple pointer device.\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keydtroke information was not returned due\r
+ to hardware errors.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterSimplePointerPrivateGetState (\r
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,\r
IN OUT EFI_SIMPLE_POINTER_STATE *State\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- State -\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_STATUS ReturnStatus;\r
State->LeftButton = TRUE;\r
}\r
\r
- if (CurrentState.RightButton) {\r
- State->RightButton = TRUE;\r
- }\r
+ if (CurrentState.RightButton) {\r
+ State->RightButton = TRUE;\r
+ }\r
+\r
+ if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {\r
+ State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->PointerList[Index]->Mode->ResolutionX;\r
+ }\r
+\r
+ if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {\r
+ State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->PointerList[Index]->Mode->ResolutionY;\r
+ }\r
+\r
+ if (CurrentState.RelativeMovementZ != 0 && Private->PointerList[Index]->Mode->ResolutionZ != 0) {\r
+ State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->PointerList[Index]->Mode->ResolutionZ;\r
+ }\r
+ } else if (Status == EFI_DEVICE_ERROR) {\r
+ ReturnStatus = EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ return ReturnStatus;\r
+}\r
+\r
+\r
+/**\r
+ Reads the next keystroke from the input device. The WaitForKey Event can\r
+ be used to test for existance of a keystroke via WaitForEvent () call.\r
+\r
+ @param This A pointer to protocol instance.\r
+ @param State A pointer to state information on the pointer device\r
+\r
+ @retval EFI_SUCCESS The keystroke information was returned in State.\r
+ @retval EFI_NOT_READY There was no keystroke data availiable.\r
+ @retval EFI_DEVICE_ERROR The keydtroke information was not returned due\r
+ to hardware errors.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterSimplePointerGetState (\r
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
+ IN OUT EFI_SIMPLE_POINTER_STATE *State\r
+ )\r
+{\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+\r
+ Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
+\r
+ Private->InputEventSignalState = FALSE;\r
+\r
+ return ConSplitterSimplePointerPrivateGetState (Private, State);\r
+}\r
+\r
+\r
+/**\r
+ This event agregates all the events of the ConIn devices in the spliter.\r
+ If any events of physical ConIn devices are signaled, signal the ConIn\r
+ spliter event. This will cause the calling code to call\r
+ ConSplitterTextInReadKeyStroke ().\r
+\r
+ @param Event The Event assoicated with callback.\r
+ @param Context Context registered when Event was created.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ConSplitterSimplePointerWaitForInput (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN Index;\r
+\r
+ Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
+\r
+ //\r
+ // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
+ //\r
+ if (Private->InputEventSignalState) {\r
+ gBS->SignalEvent (Event);\r
+ return ;\r
+ }\r
+ //\r
+ // if any physical console input device has key input, signal the event.\r
+ //\r
+ for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
+ Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);\r
+ if (!EFI_ERROR (Status)) {\r
+ gBS->SignalEvent (Event);\r
+ Private->InputEventSignalState = TRUE;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Resets the pointer device hardware.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and\r
+ could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterAbsolutePointerReset (\r
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STATUS ReturnStatus;\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN Index;\r
+\r
+ Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);\r
+\r
+ Private->AbsoluteInputEventSignalState = FALSE;\r
+\r
+ if (Private->CurrentNumberOfAbsolutePointers == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // return the worst status met\r
+ //\r
+ for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
+ Status = Private->AbsolutePointerList[Index]->Reset (\r
+ Private->AbsolutePointerList[Index],\r
+ ExtendedVerification\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
+ }\r
+ }\r
+\r
+ return ReturnStatus;\r
+}\r
+\r
+\r
+/**\r
+ Retrieves the current state of a pointer device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param State A pointer to the state information on the\r
+ pointer device.\r
+\r
+ @retval EFI_SUCCESS The state of the pointer device was returned in\r
+ State..\r
+ @retval EFI_NOT_READY The state of the pointer device has not changed\r
+ since the last call to GetState().\r
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to\r
+ retrieve the pointer device's current state.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConSplitterAbsolutePointerGetState (\r
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,\r
+ IN OUT EFI_ABSOLUTE_POINTER_STATE *State\r
+ )\r
+{\r
+ TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
+ EFI_STATUS Status;\r
+ EFI_STATUS ReturnStatus;\r
+ UINTN Index;\r
+ EFI_ABSOLUTE_POINTER_STATE CurrentState;\r
+ UINT64 MinX;\r
+ UINT64 MinY;\r
+ UINT64 MinZ;\r
+ UINT64 MaxX;\r
+ UINT64 MaxY;\r
+ UINT64 MaxZ;\r
+ UINT64 VirtualMinX;\r
+ UINT64 VirtualMinY;\r
+ UINT64 VirtualMinZ;\r
+ UINT64 VirtualMaxX;\r
+ UINT64 VirtualMaxY;\r
+ UINT64 VirtualMaxZ;\r
+\r
+ Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS (This);\r
+\r
+ Private->AbsoluteInputEventSignalState = FALSE;\r
+\r
+ State->CurrentX = 0;\r
+ State->CurrentY = 0;\r
+ State->CurrentZ = 0;\r
+ State->ActiveButtons = 0;\r
+\r
+ VirtualMinX = Private->AbsolutePointerMode.AbsoluteMinX;\r
+ VirtualMinY = Private->AbsolutePointerMode.AbsoluteMinY;\r
+ VirtualMinZ = Private->AbsolutePointerMode.AbsoluteMinZ;\r
+ VirtualMaxX = Private->AbsolutePointerMode.AbsoluteMaxX;\r
+ VirtualMaxY = Private->AbsolutePointerMode.AbsoluteMaxY;\r
+ VirtualMaxZ = Private->AbsolutePointerMode.AbsoluteMaxZ;\r
+\r
+ //\r
+ // if no physical pointer device exists, return EFI_NOT_READY;\r
+ // if any physical pointer device has changed state,\r
+ // return the state and EFI_SUCCESS.\r
+ //\r
+ ReturnStatus = EFI_NOT_READY;\r
+ for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
+\r
+ Status = Private->AbsolutePointerList[Index]->GetState (\r
+ Private->AbsolutePointerList[Index],\r
+ &CurrentState\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if (ReturnStatus == EFI_NOT_READY) {\r
+ ReturnStatus = EFI_SUCCESS;\r
+ }\r
+\r
+ MinX = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinX;\r
+ MinY = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinY;\r
+ MinZ = Private->AbsolutePointerList[Index]->Mode->AbsoluteMinZ;\r
+ MaxX = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxX;\r
+ MaxY = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxY;\r
+ MaxZ = Private->AbsolutePointerList[Index]->Mode->AbsoluteMaxZ;\r
\r
- if (CurrentState.RelativeMovementX != 0 && Private->PointerList[Index]->Mode->ResolutionX != 0) {\r
- State->RelativeMovementX += (CurrentState.RelativeMovementX * (INT32) Private->SimplePointerMode.ResolutionX) / (INT32) Private->PointerList[Index]->Mode->ResolutionX;\r
- }\r
+ State->ActiveButtons = CurrentState.ActiveButtons;\r
\r
- if (CurrentState.RelativeMovementY != 0 && Private->PointerList[Index]->Mode->ResolutionY != 0) {\r
- State->RelativeMovementY += (CurrentState.RelativeMovementY * (INT32) Private->SimplePointerMode.ResolutionY) / (INT32) Private->PointerList[Index]->Mode->ResolutionY;\r
+ //\r
+ // Rescale to Con Splitter virtual Absolute Pointer's resolution.\r
+ //\r
+ if (!(MinX == 0 && MaxX == 0)) {\r
+ State->CurrentX = VirtualMinX + DivU64x64Remainder (\r
+ MultU64x64 (\r
+ CurrentState.CurrentX,\r
+ VirtualMaxX - VirtualMinX\r
+ ),\r
+ MaxX - MinX,\r
+ NULL\r
+ );\r
}\r
-\r
- if (CurrentState.RelativeMovementZ != 0 && Private->PointerList[Index]->Mode->ResolutionZ != 0) {\r
- State->RelativeMovementZ += (CurrentState.RelativeMovementZ * (INT32) Private->SimplePointerMode.ResolutionZ) / (INT32) Private->PointerList[Index]->Mode->ResolutionZ;\r
+ if (!(MinY == 0 && MaxY == 0)) {\r
+ State->CurrentY = VirtualMinY + DivU64x64Remainder (\r
+ MultU64x64 (\r
+ CurrentState.CurrentY,\r
+ VirtualMaxY - VirtualMinY\r
+ ),\r
+ MaxY - MinY,\r
+ NULL\r
+ );\r
}\r
+ if (!(MinZ == 0 && MaxZ == 0)) {\r
+ State->CurrentZ = VirtualMinZ + DivU64x64Remainder (\r
+ MultU64x64 (\r
+ CurrentState.CurrentZ,\r
+ VirtualMaxZ - VirtualMinZ\r
+ ),\r
+ MaxZ - MinZ,\r
+ NULL\r
+ );\r
+ }\r
+\r
} else if (Status == EFI_DEVICE_ERROR) {\r
ReturnStatus = EFI_DEVICE_ERROR;\r
}\r
return ReturnStatus;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-ConSplitterSimplePointerGetState (\r
- IN EFI_SIMPLE_POINTER_PROTOCOL *This,\r
- IN OUT EFI_SIMPLE_POINTER_STATE *State\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Reads the next keystroke from the input device. The WaitForKey Event can\r
- be used to test for existance of a keystroke via WaitForEvent () call.\r
- If the ConIn is password locked make it look like no keystroke is availible\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- State -\r
-\r
- Returns:\r
- EFI_SUCCESS - The keystroke information was returned.\r
- EFI_NOT_READY - There was no keystroke data availiable.\r
- EFI_DEVICE_ERROR - The keydtroke information was not returned due to\r
- hardware errors.\r
-\r
---*/\r
-{\r
- TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
-\r
- Private = TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_SIMPLE_POINTER_THIS (This);\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return EFI_NOT_READY;\r
- }\r
\r
- Private->InputEventSignalState = FALSE;\r
+/**\r
+ This event agregates all the events of the pointer devices in the splitter.\r
+ If any events of physical pointer devices are signaled, signal the pointer\r
+ splitter event. This will cause the calling code to call\r
+ ConSplitterAbsolutePointerGetState ().\r
\r
- return ConSplitterSimplePointerPrivateGetState (Private, State);\r
-}\r
+ @param Event The Event assoicated with callback.\r
+ @param Context Context registered when Event was created.\r
\r
+**/\r
VOID\r
EFIAPI\r
-ConSplitterSimplePointerWaitForInput (\r
+ConSplitterAbsolutePointerWaitForInput (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
- This event agregates all the events of the ConIn devices in the spliter.\r
- If the ConIn is password locked then return.\r
- If any events of physical ConIn devices are signaled, signal the ConIn\r
- spliter event. This will cause the calling code to call\r
- ConSplitterTextInReadKeyStroke ().\r
-\r
-Arguments:\r
- Event - The Event assoicated with callback.\r
- Context - Context registered when Event was created.\r
-\r
-Returns:\r
- None\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;\r
UINTN Index;\r
\r
Private = (TEXT_IN_SPLITTER_PRIVATE_DATA *) Context;\r
- if (Private->PasswordEnabled) {\r
- //\r
- // If StdIn Locked return not ready\r
- //\r
- return ;\r
- }\r
\r
//\r
- // if InputEventSignalState is flagged before, and not cleared by Reset() or ReadKeyStroke()\r
+ // if AbsoluteInputEventSignalState is flagged before,\r
+ // and not cleared by Reset() or GetState(), signal it\r
//\r
- if (Private->InputEventSignalState) {\r
+ if (Private->AbsoluteInputEventSignalState) {\r
gBS->SignalEvent (Event);\r
return ;\r
}\r
//\r
// if any physical console input device has key input, signal the event.\r
//\r
- for (Index = 0; Index < Private->CurrentNumberOfPointers; Index++) {\r
- Status = gBS->CheckEvent (Private->PointerList[Index]->WaitForInput);\r
+ for (Index = 0; Index < Private->CurrentNumberOfAbsolutePointers; Index++) {\r
+ Status = gBS->CheckEvent (Private->AbsolutePointerList[Index]->WaitForInput);\r
if (!EFI_ERROR (Status)) {\r
gBS->SignalEvent (Event);\r
- Private->InputEventSignalState = TRUE;\r
+ Private->AbsoluteInputEventSignalState = TRUE;\r
}\r
}\r
}\r
\r
+\r
+/**\r
+ Reset the text output device hardware and optionaly run diagnostics\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ExtendedVerification Driver may perform more exhaustive verfication\r
+ operation of the device during reset.\r
+\r
+ @retval EFI_SUCCESS The text output device was reset.\r
+ @retval EFI_DEVICE_ERROR The text output device is not functioning\r
+ correctly and could not be reset.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutReset (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN BOOLEAN ExtendedVerification\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Reset the text output device hardware and optionaly run diagnostics\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ExtendedVerification - Driver may perform more exhaustive verfication\r
- operation of the device during reset.\r
-\r
- Returns:\r
- EFI_SUCCESS - The text output device was reset.\r
- EFI_DEVICE_ERROR - The text output device is not functioning correctly and\r
- could not be reset.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
-\r
- Status = Private->TextOutList[Index].TextOut->Reset (\r
- Private->TextOutList[Index].TextOut,\r
- ExtendedVerification\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->Reset (\r
+ Private->TextOutList[Index].TextOut,\r
+ ExtendedVerification\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
\r
- This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));\r
+ This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));\r
\r
- Status = DevNullTextOutSetMode (Private, 0);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ //\r
+ // reset all mode parameters\r
+ //\r
+ TextOutSetMode (Private, 0);\r
\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Write a Unicode string to the output device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param WString The NULL-terminated Unicode string to be\r
+ displayed on the output device(s). All output\r
+ devices must also support the Unicode drawing\r
+ defined in this file.\r
+\r
+ @retval EFI_SUCCESS The string was output to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while attempting to\r
+ output the text.\r
+ @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
+ defined text mode.\r
+ @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
+ characters in the Unicode string could not be\r
+ rendered and were skipped.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutOutputString (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN CHAR16 *WString\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Write a Unicode string to the output device.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- String - The NULL-terminated Unicode string to be displayed on the output\r
- device(s). All output devices must also support the Unicode\r
- drawing defined in this file.\r
-\r
- Returns:\r
- EFI_SUCCESS - The string was output to the device.\r
- EFI_DEVICE_ERROR - The device reported an error while attempting to output\r
- the text.\r
- EFI_UNSUPPORTED - The output device's mode is not currently in a\r
- defined text mode.\r
- EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the\r
- characters in the Unicode string could not be\r
- rendered and were skipped.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
UINTN Index;\r
- UINTN BackSpaceCount;\r
EFI_STATUS ReturnStatus;\r
- CHAR16 *TargetString;\r
+ UINTN MaxColumn;\r
+ UINTN MaxRow;\r
\r
This->SetAttribute (This, This->Mode->Attribute);\r
\r
Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
- BackSpaceCount = 0;\r
- for (TargetString = WString; *TargetString; TargetString++) {\r
- if (*TargetString == CHAR_BACKSPACE) {\r
- BackSpaceCount++;\r
- }\r
-\r
- }\r
-\r
- if (BackSpaceCount == 0) {\r
- TargetString = WString;\r
- } else {\r
- TargetString = AllocatePool (sizeof (CHAR16) * (StrLen (WString) + BackSpaceCount + 1));\r
- StrCpy (TargetString, WString);\r
- }\r
//\r
// return the worst status met\r
//\r
- Status = DevNullTextOutOutputString (Private, TargetString);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
+ for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+ Status = Private->TextOutList[Index].TextOut->OutputString (\r
+ Private->TextOutList[Index].TextOut,\r
+ WString\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
+ }\r
}\r
\r
- for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
+ if (Private->CurrentNumberOfConsoles > 0) {\r
+ Private->TextOutMode.CursorColumn = Private->TextOutList[0].TextOut->Mode->CursorColumn;\r
+ Private->TextOutMode.CursorRow = Private->TextOutList[0].TextOut->Mode->CursorRow;\r
+ } else {\r
+ //\r
+ // When there is no real console devices in system,\r
+ // update cursor position for the virtual device in consplitter.\r
+ //\r
+ Private->TextOut.QueryMode (\r
+ &Private->TextOut,\r
+ Private->TextOutMode.Mode,\r
+ &MaxColumn,\r
+ &MaxRow\r
+ );\r
+ for (; *WString != CHAR_NULL; WString++) {\r
+ switch (*WString) {\r
+ case CHAR_BACKSPACE:\r
+ if (Private->TextOutMode.CursorColumn == 0 && Private->TextOutMode.CursorRow > 0) {\r
+ Private->TextOutMode.CursorRow--;\r
+ Private->TextOutMode.CursorColumn = (INT32) (MaxColumn - 1);\r
+ } else if (Private->TextOutMode.CursorColumn > 0) {\r
+ Private->TextOutMode.CursorColumn--;\r
+ }\r
+ break;\r
\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->OutputString (\r
- Private->TextOutList[Index].TextOut,\r
- TargetString\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
+ case CHAR_LINEFEED:\r
+ if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {\r
+ Private->TextOutMode.CursorRow++;\r
+ }\r
+ break;\r
+\r
+ case CHAR_CARRIAGE_RETURN:\r
+ Private->TextOutMode.CursorColumn = 0;\r
+ break;\r
+\r
+ default:\r
+ if (Private->TextOutMode.CursorColumn < (INT32) (MaxColumn - 1)) {\r
+ Private->TextOutMode.CursorColumn++;\r
+ } else {\r
+ Private->TextOutMode.CursorColumn = 0;\r
+ if (Private->TextOutMode.CursorRow < (INT32) (MaxRow - 1)) {\r
+ Private->TextOutMode.CursorRow++;\r
+ }\r
+ }\r
+ break;\r
}\r
}\r
}\r
\r
- if (BackSpaceCount) {\r
- FreePool (TargetString);\r
- }\r
-\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Verifies that all characters in a Unicode string can be output to the\r
+ target device.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param WString The NULL-terminated Unicode string to be\r
+ examined for the output device(s).\r
+\r
+ @retval EFI_SUCCESS The device(s) are capable of rendering the\r
+ output string.\r
+ @retval EFI_UNSUPPORTED Some of the characters in the Unicode string\r
+ cannot be rendered by one or more of the output\r
+ devices mapped by the EFI handle.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutTestString (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN CHAR16 *WString\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Verifies that all characters in a Unicode string can be output to the\r
- target device.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- String - The NULL-terminated Unicode string to be examined for the output\r
- device(s).\r
-\r
- Returns:\r
- EFI_SUCCESS - The device(s) are capable of rendering the output string.\r
- EFI_UNSUPPORTED - Some of the characters in the Unicode string cannot be\r
- rendered by one or more of the output devices mapped\r
- by the EFI handle.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->TestString (\r
- Private->TextOutList[Index].TextOut,\r
- WString\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->TestString (\r
+ Private->TextOutList[Index].TextOut,\r
+ WString\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
//\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Returns information for an available text mode that the output device(s)\r
+ supports.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ModeNumber The mode number to return information on.\r
+ @param Columns Returns the columns of the text output device\r
+ for the requested ModeNumber.\r
+ @param Rows Returns the rows of the text output device\r
+ for the requested ModeNumber.\r
+\r
+ @retval EFI_SUCCESS The requested mode information was returned.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request.\r
+ @retval EFI_UNSUPPORTED The mode number was not valid.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutQueryMode (\r
OUT UINTN *Columns,\r
OUT UINTN *Rows\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Returns information for an available text mode that the output device(s)\r
- supports.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ModeNumber - The mode number to return information on.\r
- Columns, Rows - Returns the geometry of the text output device for the\r
- requested ModeNumber.\r
-\r
- Returns:\r
- EFI_SUCCESS - The requested mode information was returned.\r
- EFI_DEVICE_ERROR - The device had an error and could not\r
- complete the request.\r
- EFI_UNSUPPORTED - The mode number was not valid.\r
-\r
---*/\r
{\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
+ UINTN CurrentMode;\r
+ INT32 *TextOutModeMap;\r
\r
Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
- *Columns = Private->TextOutQueryData[ModeNumber].Columns;\r
- *Rows = Private->TextOutQueryData[ModeNumber].Rows;\r
+ //\r
+ // We get the available mode from mode intersection map if it's available\r
+ //\r
+ if (Private->TextOutModeMap != NULL) {\r
+ TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
+ CurrentMode = (UINTN)(*TextOutModeMap);\r
+ *Columns = Private->TextOutQueryData[CurrentMode].Columns;\r
+ *Rows = Private->TextOutQueryData[CurrentMode].Rows;\r
+ } else {\r
+ *Columns = Private->TextOutQueryData[ModeNumber].Columns;\r
+ *Rows = Private->TextOutQueryData[ModeNumber].Rows;\r
+ }\r
\r
if (*Columns <= 0 && *Rows <= 0) {\r
return EFI_UNSUPPORTED;\r
return EFI_SUCCESS;\r
}\r
\r
+\r
+/**\r
+ Sets the output device(s) to a specified mode.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param ModeNumber The mode number to set.\r
+\r
+ @retval EFI_SUCCESS The requested text mode was set.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request.\r
+ @retval EFI_UNSUPPORTED The mode number was not valid.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutSetMode (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN UINTN ModeNumber\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Sets the output device(s) to a specified mode.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- ModeNumber - The mode number to set.\r
-\r
- Returns:\r
- EFI_SUCCESS - The requested text mode was set.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The mode number was not valid.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
//\r
TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
+ //\r
+ // While adding a console out device do not set same mode again for the same device.\r
+ //\r
+ if ((!Private->AddingConOutDevice) ||\r
+ (TextOutModeMap[Index] != Private->TextOutList[Index].TextOut->Mode->Mode)) {\r
Status = Private->TextOutList[Index].TextOut->SetMode (\r
Private->TextOutList[Index].TextOut,\r
TextOutModeMap[Index]\r
);\r
- //\r
- // If this console device is based on a UGA device, then sync up the bitmap from\r
- // the UGA splitter and reclear the text portion of the display in the new mode.\r
- //\r
- if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {\r
- Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
- }\r
-\r
if (EFI_ERROR (Status)) {\r
ReturnStatus = Status;\r
}\r
}\r
}\r
+\r
//\r
- // The DevNull Console will support any possible mode as it allocates memory\r
+ // Set mode parameter to specified mode number\r
//\r
- Status = DevNullTextOutSetMode (Private, ModeNumber);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ TextOutSetMode (Private, ModeNumber);\r
\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Sets the background and foreground colors for the OutputString () and\r
+ ClearScreen () functions.\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Attribute The attribute to set. Bits 0..3 are the\r
+ foreground color, and bits 4..6 are the\r
+ background color. All other bits are undefined\r
+ and must be zero. The valid Attributes are\r
+ defined in this file.\r
+\r
+ @retval EFI_SUCCESS The attribute was set.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request.\r
+ @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutSetAttribute (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN UINTN Attribute\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Sets the background and foreground colors for the OutputString () and\r
- ClearScreen () functions.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Attribute - The attribute to set. Bits 0..3 are the foreground color, and\r
- bits 4..6 are the background color. All other bits are undefined\r
- and must be zero. The valid Attributes are defined in this file.\r
-\r
- Returns:\r
- EFI_SUCCESS - The attribute was set.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The attribute requested is not defined.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
//\r
// Check whether param Attribute is valid.\r
//\r
- if ( (Attribute > (UINTN)(((UINT32)-1)>>1)) ) {\r
+ if ((Attribute | 0x7F) != 0x7F) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->SetAttribute (\r
- Private->TextOutList[Index].TextOut,\r
- Attribute\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->SetAttribute (\r
+ Private->TextOutList[Index].TextOut,\r
+ Attribute\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Clears the output device(s) display to the currently selected background\r
+ color.\r
+\r
+ @param This Protocol instance pointer.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request.\r
+ @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutClearScreen (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Clears the output device(s) display to the currently selected background\r
- color.\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->ClearScreen (Private->TextOutList[Index].TextOut);\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
\r
- Status = DevNullTextOutClearScreen (Private);\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ //\r
+ // No need to do extra check here as whether (Column, Row) is valid has\r
+ // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should\r
+ // always be supported.\r
+ //\r
+ Private->TextOutMode.CursorColumn = 0;\r
+ Private->TextOutMode.CursorRow = 0;\r
+ Private->TextOutMode.CursorVisible = TRUE;\r
\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Sets the current coordinates of the cursor position\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Column The column position to set the cursor to. Must be\r
+ greater than or equal to zero and less than the\r
+ number of columns by QueryMode ().\r
+ @param Row The row position to set the cursor to. Must be\r
+ greater than or equal to zero and less than the\r
+ number of rows by QueryMode ().\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request.\r
+ @retval EFI_UNSUPPORTED The output device is not in a valid text mode,\r
+ or the cursor position is invalid for the\r
+ current mode.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutSetCursorPosition (\r
IN UINTN Column,\r
IN UINTN Row\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Sets the current coordinates of the cursor position\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Column, Row - the position to set the cursor to. Must be greater than or\r
- equal to zero and less than the number of columns and rows\r
- by QueryMode ().\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and\r
- could not complete the request.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode, or the\r
- cursor position is invalid for the current mode.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
EFI_STATUS ReturnStatus;\r
UINTN MaxColumn;\r
UINTN MaxRow;\r
+ INT32 *TextOutModeMap;\r
+ INT32 ModeNumber;\r
+ INT32 CurrentMode;\r
\r
Private = TEXT_OUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);\r
+ TextOutModeMap = NULL;\r
+ ModeNumber = Private->TextOutMode.Mode;\r
+\r
+ //\r
+ // Get current MaxColumn and MaxRow from intersection map\r
+ //\r
+ if (Private->TextOutModeMap != NULL) {\r
+ TextOutModeMap = Private->TextOutModeMap + Private->TextOutListCount * ModeNumber;\r
+ CurrentMode = *TextOutModeMap;\r
+ } else {\r
+ CurrentMode = ModeNumber;\r
+ }\r
\r
- MaxColumn = Private->TextOutQueryData[Private->TextOutMode.Mode].Columns;\r
- MaxRow = Private->TextOutQueryData[Private->TextOutMode.Mode].Rows;\r
+ MaxColumn = Private->TextOutQueryData[CurrentMode].Columns;\r
+ MaxRow = Private->TextOutQueryData[CurrentMode].Rows;\r
\r
if (Column >= MaxColumn || Row >= MaxRow) {\r
return EFI_UNSUPPORTED;\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->SetCursorPosition (\r
- Private->TextOutList[Index].TextOut,\r
- Column,\r
- Row\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->SetCursorPosition (\r
+ Private->TextOutList[Index].TextOut,\r
+ Column,\r
+ Row\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
\r
- DevNullTextOutSetCursorPosition (Private, Column, Row);\r
+ //\r
+ // No need to do extra check here as whether (Column, Row) is valid has\r
+ // been checked in ConSplitterTextOutSetCursorPosition. And (0, 0) should\r
+ // always be supported.\r
+ //\r
+ Private->TextOutMode.CursorColumn = (INT32) Column;\r
+ Private->TextOutMode.CursorRow = (INT32) Row;\r
\r
return ReturnStatus;\r
}\r
\r
+\r
+/**\r
+ Makes the cursor visible or invisible\r
+\r
+ @param This Protocol instance pointer.\r
+ @param Visible If TRUE, the cursor is set to be visible. If\r
+ FALSE, the cursor is set to be invisible.\r
+\r
+ @retval EFI_SUCCESS The operation completed successfully.\r
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete\r
+ the request, or the device does not support\r
+ changing the cursor mode.\r
+ @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
ConSplitterTextOutEnableCursor (\r
IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
IN BOOLEAN Visible\r
)\r
-/*++\r
-\r
- Routine Description:\r
- Makes the cursor visible or invisible\r
-\r
- Arguments:\r
- This - Protocol instance pointer.\r
- Visible - If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
- set to be invisible.\r
-\r
- Returns:\r
- EFI_SUCCESS - The operation completed successfully.\r
- EFI_DEVICE_ERROR - The device had an error and could not complete the\r
- request, or the device does not support changing\r
- the cursor mode.\r
- EFI_UNSUPPORTED - The output device is not in a valid text mode.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;\r
// return the worst status met\r
//\r
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfConsoles; Index++) {\r
-\r
- if (Private->TextOutList[Index].TextOutEnabled) {\r
- Status = Private->TextOutList[Index].TextOut->EnableCursor (\r
- Private->TextOutList[Index].TextOut,\r
- Visible\r
- );\r
- if (EFI_ERROR (Status)) {\r
- ReturnStatus = Status;\r
- }\r
+ Status = Private->TextOutList[Index].TextOut->EnableCursor (\r
+ Private->TextOutList[Index].TextOut,\r
+ Visible\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ ReturnStatus = Status;\r
}\r
}\r
\r
- DevNullTextOutEnableCursor (Private, Visible);\r
+ Private->TextOutMode.CursorVisible = Visible;\r
\r
return ReturnStatus;\r
}\r