mirror of https://github.com/acidanthera/audk.git
MdeModulePkg ConSplitterDxe: Support toggle state sync
Register key notify for toggle state (CapsLock, NumLock and ScrollLock) sync between multiple keyboards. The implementation for this feature requires keyboard driver supports EFI_KEY_STATE_EXPOSED, and turns on physical TextInEx partial key report for toggle state sync. The virtual TextInEx will report the partial key after it is required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly. Cc: Ruiyu Ni <Ruiyu.ni@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ruiyu Ni <Ruiyu.ni@intel.com>
This commit is contained in:
parent
12b96a93f3
commit
cf88579c10
|
@ -67,6 +67,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {
|
||||||
(LIST_ENTRY *) NULL,
|
(LIST_ENTRY *) NULL,
|
||||||
(LIST_ENTRY *) NULL
|
(LIST_ENTRY *) NULL
|
||||||
},
|
},
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
|
||||||
{
|
{
|
||||||
ConSplitterSimplePointerReset,
|
ConSplitterSimplePointerReset,
|
||||||
|
@ -300,6 +302,122 @@ EFI_DRIVER_BINDING_PROTOCOL gConSplitterAbsolutePointerDriverBinding =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Key notify for toggle state sync.
|
||||||
|
|
||||||
|
@param KeyData A pointer to a buffer that is filled in with
|
||||||
|
the keystroke information for the key that was
|
||||||
|
pressed.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Toggle state sync successfully.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ToggleStateSyncKeyNotify (
|
||||||
|
IN EFI_KEY_DATA *KeyData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if (((KeyData->KeyState.KeyToggleState & KEY_STATE_VALID_EXPOSED) == KEY_STATE_VALID_EXPOSED) &&
|
||||||
|
(KeyData->KeyState.KeyToggleState != mConIn.PhysicalKeyToggleState)) {
|
||||||
|
//
|
||||||
|
// There is toggle state change, sync to other console input devices.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < mConIn.CurrentNumberOfExConsoles; Index++) {
|
||||||
|
mConIn.TextInExList[Index]->SetState (
|
||||||
|
mConIn.TextInExList[Index],
|
||||||
|
&KeyData->KeyState.KeyToggleState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
mConIn.PhysicalKeyToggleState = KeyData->KeyState.KeyToggleState;
|
||||||
|
DEBUG ((EFI_D_INFO, "Current toggle state is 0x%02x\n", mConIn.PhysicalKeyToggleState));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialization for toggle state sync.
|
||||||
|
|
||||||
|
@param Private Text In Splitter pointer.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
ToggleStateSyncInitialization (
|
||||||
|
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_KEY_DATA KeyData;
|
||||||
|
VOID *NotifyHandle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize PhysicalKeyToggleState that will be synced to new console
|
||||||
|
// input device to turn on physical TextInEx partial key report for
|
||||||
|
// toggle state sync.
|
||||||
|
//
|
||||||
|
Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize VirtualKeyStateExported to let the virtual TextInEx not report
|
||||||
|
// the partial key even though the physical TextInEx turns on the partial
|
||||||
|
// key report. The virtual TextInEx will report the partial key after it is
|
||||||
|
// required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.
|
||||||
|
//
|
||||||
|
Private->VirtualKeyStateExported = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register key notify for toggle state sync.
|
||||||
|
//
|
||||||
|
KeyData.Key.ScanCode = SCAN_NULL;
|
||||||
|
KeyData.Key.UnicodeChar = CHAR_NULL;
|
||||||
|
KeyData.KeyState.KeyShiftState = 0;
|
||||||
|
KeyData.KeyState.KeyToggleState = 0;
|
||||||
|
Private->TextInEx.RegisterKeyNotify (
|
||||||
|
&Private->TextInEx,
|
||||||
|
&KeyData,
|
||||||
|
ToggleStateSyncKeyNotify,
|
||||||
|
&NotifyHandle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reinitialization for toggle state sync.
|
||||||
|
|
||||||
|
@param Private Text In Splitter pointer.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
ToggleStateSyncReInitialization (
|
||||||
|
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reinitialize PhysicalKeyToggleState that will be synced to new console
|
||||||
|
// input device to turn on physical TextInEx partial key report for
|
||||||
|
// toggle state sync.
|
||||||
|
//
|
||||||
|
Private->PhysicalKeyToggleState = KEY_STATE_VALID_EXPOSED;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reinitialize VirtualKeyStateExported to let the virtual TextInEx not report
|
||||||
|
// the partial key even though the physical TextInEx turns on the partial
|
||||||
|
// key report. The virtual TextInEx will report the partial key after it is
|
||||||
|
// required by calling SetState(X | KEY_STATE_VALID_EXPOSED) explicitly.
|
||||||
|
//
|
||||||
|
Private->VirtualKeyStateExported = FALSE;
|
||||||
|
|
||||||
|
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
|
||||||
|
Private->TextInExList[Index]->SetState (
|
||||||
|
Private->TextInExList[Index],
|
||||||
|
&Private->PhysicalKeyToggleState
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The Entry Point for module ConSplitter. The user code starts with this function.
|
The Entry Point for module ConSplitter. The user code starts with this function.
|
||||||
|
|
||||||
|
@ -538,6 +656,8 @@ ConSplitterTextInConstructor (
|
||||||
|
|
||||||
InitializeListHead (&ConInPrivate->NotifyList);
|
InitializeListHead (&ConInPrivate->NotifyList);
|
||||||
|
|
||||||
|
ToggleStateSyncInitialization (ConInPrivate);
|
||||||
|
|
||||||
ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;
|
ConInPrivate->AbsolutePointer.Mode = &ConInPrivate->AbsolutePointerMode;
|
||||||
//
|
//
|
||||||
// Allocate buffer for Absolute Pointer device
|
// Allocate buffer for Absolute Pointer device
|
||||||
|
@ -1890,6 +2010,11 @@ ConSplitterTextInExAddDevice (
|
||||||
Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;
|
Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;
|
||||||
Private->CurrentNumberOfExConsoles++;
|
Private->CurrentNumberOfExConsoles++;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Sync current toggle state to this new console input device.
|
||||||
|
//
|
||||||
|
TextInEx->SetState (TextInEx, &Private->PhysicalKeyToggleState);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Extra CheckEvent added to reduce the double CheckEvent().
|
// Extra CheckEvent added to reduce the double CheckEvent().
|
||||||
//
|
//
|
||||||
|
@ -3321,6 +3446,10 @@ ConSplitterTextInReset (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (ReturnStatus)) {
|
||||||
|
ToggleStateSyncReInitialization (Private);
|
||||||
|
}
|
||||||
|
|
||||||
return ReturnStatus;
|
return ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3357,14 +3486,25 @@ ConSplitterTextInPrivateReadKeyStroke (
|
||||||
// if any physical console input device has key input,
|
// if any physical console input device has key input,
|
||||||
// return the key and EFI_SUCCESS.
|
// return the key and EFI_SUCCESS.
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
|
for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
|
||||||
Status = Private->TextInList[Index]->ReadKeyStroke (
|
Status = Private->TextInList[Index]->ReadKeyStroke (
|
||||||
Private->TextInList[Index],
|
Private->TextInList[Index],
|
||||||
&CurrentKey
|
&CurrentKey
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
*Key = CurrentKey;
|
//
|
||||||
return Status;
|
// If it is not partial keystorke, return the key. Otherwise, continue
|
||||||
|
// to read key from THIS physical console input device.
|
||||||
|
//
|
||||||
|
if ((CurrentKey.ScanCode != CHAR_NULL) || (CurrentKey.UnicodeChar != SCAN_NULL)) {
|
||||||
|
*Key = CurrentKey;
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Continue to read key from NEXT physical console input device.
|
||||||
|
//
|
||||||
|
Index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3542,6 +3682,10 @@ ConSplitterTextInResetEx (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR (ReturnStatus)) {
|
||||||
|
ToggleStateSyncReInitialization (Private);
|
||||||
|
}
|
||||||
|
|
||||||
return ReturnStatus;
|
return ReturnStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3601,14 +3745,28 @@ ConSplitterTextInReadKeyStrokeEx (
|
||||||
// if any physical console input device has key input,
|
// if any physical console input device has key input,
|
||||||
// return the key and EFI_SUCCESS.
|
// return the key and EFI_SUCCESS.
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
|
for (Index = 0; Index < Private->CurrentNumberOfExConsoles;) {
|
||||||
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
|
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
|
||||||
Private->TextInExList[Index],
|
Private->TextInExList[Index],
|
||||||
&CurrentKeyData
|
&CurrentKeyData
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
|
//
|
||||||
return Status;
|
// If virtual KeyState has been required to be exposed, or it is not
|
||||||
|
// partial keystorke, return the key. Otherwise, continue to read key
|
||||||
|
// from THIS physical console input device.
|
||||||
|
//
|
||||||
|
if ((Private->VirtualKeyStateExported) ||
|
||||||
|
(CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
|
||||||
|
(CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {
|
||||||
|
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Continue to read key from NEXT physical console input device.
|
||||||
|
//
|
||||||
|
Index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3641,6 +3799,7 @@ ConSplitterTextInSetState (
|
||||||
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
|
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
EFI_KEY_TOGGLE_STATE PhysicalKeyToggleState;
|
||||||
|
|
||||||
if (KeyToggleState == NULL) {
|
if (KeyToggleState == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
@ -3648,6 +3807,12 @@ ConSplitterTextInSetState (
|
||||||
|
|
||||||
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
|
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Always turn on physical TextInEx partial key report for
|
||||||
|
// toggle state sync.
|
||||||
|
//
|
||||||
|
PhysicalKeyToggleState = *KeyToggleState | EFI_KEY_STATE_EXPOSED;
|
||||||
|
|
||||||
//
|
//
|
||||||
// if no physical console input device exists, return EFI_SUCCESS;
|
// if no physical console input device exists, return EFI_SUCCESS;
|
||||||
// otherwise return the status of setting state of physical console input device
|
// otherwise return the status of setting state of physical console input device
|
||||||
|
@ -3655,13 +3820,22 @@ ConSplitterTextInSetState (
|
||||||
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
|
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
|
||||||
Status = Private->TextInExList[Index]->SetState (
|
Status = Private->TextInExList[Index]->SetState (
|
||||||
Private->TextInExList[Index],
|
Private->TextInExList[Index],
|
||||||
KeyToggleState
|
&PhysicalKeyToggleState
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Record the physical KeyToggleState.
|
||||||
|
//
|
||||||
|
Private->PhysicalKeyToggleState = PhysicalKeyToggleState;
|
||||||
|
//
|
||||||
|
// Get if virtual KeyState has been required to be exposed.
|
||||||
|
//
|
||||||
|
Private->VirtualKeyStateExported = (((*KeyToggleState) & EFI_KEY_STATE_EXPOSED) != 0);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3765,7 +3939,7 @@ ConSplitterTextInRegisterKeyNotify (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertTailList (&mConIn.NotifyList, &NewNotify->NotifyEntry);
|
InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
|
||||||
|
|
||||||
*NotifyHandle = NewNotify;
|
*NotifyHandle = NewNotify;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Private data structures for the Console Splitter driver
|
Private data structures for the Console Splitter driver
|
||||||
|
|
||||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -88,6 +88,7 @@ typedef struct {
|
||||||
UINTN Rows;
|
UINTN Rows;
|
||||||
} TEXT_OUT_SPLITTER_QUERY_DATA;
|
} TEXT_OUT_SPLITTER_QUERY_DATA;
|
||||||
|
|
||||||
|
#define KEY_STATE_VALID_EXPOSED (EFI_TOGGLE_STATE_VALID | EFI_KEY_STATE_EXPOSED)
|
||||||
|
|
||||||
#define TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE SIGNATURE_32 ('T', 'i', 'S', 'n')
|
#define TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE SIGNATURE_32 ('T', 'i', 'S', 'n')
|
||||||
|
|
||||||
|
@ -128,6 +129,16 @@ typedef struct {
|
||||||
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **TextInExList;
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **TextInExList;
|
||||||
UINTN TextInExListCount;
|
UINTN TextInExListCount;
|
||||||
LIST_ENTRY NotifyList;
|
LIST_ENTRY NotifyList;
|
||||||
|
//
|
||||||
|
// It will be initialized and synced between console input devices
|
||||||
|
// for toggle state sync.
|
||||||
|
//
|
||||||
|
EFI_KEY_TOGGLE_STATE PhysicalKeyToggleState;
|
||||||
|
//
|
||||||
|
// It will be initialized and used to record if virtual KeyState
|
||||||
|
// has been required to be exposed.
|
||||||
|
//
|
||||||
|
BOOLEAN VirtualKeyStateExported;
|
||||||
|
|
||||||
|
|
||||||
EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;
|
EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;
|
||||||
|
|
Loading…
Reference in New Issue