+/**\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
+ //\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
+\r
+ mConIn.PhysicalKeyToggleState = KeyData->KeyState.KeyToggleState;\r
+ DEBUG ((DEBUG_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
+ Re-initialization 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