using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Cosmos.Debug.Kernel; using Cosmos.HAL; using Cosmos.System.ScanMaps; namespace Cosmos.System { public static class KeyboardManager { public static bool NumLock { get; set; } public static bool CapsLock { get; set; } public static bool ScrollLock { get; set; } public static bool ControlPressed { get; set; } public static bool ShiftPressed { get; set; } public static bool AltPressed { get; set; } public static List Keyboards = new List(); private static ScanMapBase _scanMap = new US_Standard(); private static Queue mQueuedKeys = new Queue(); private static void Enqueue(KeyEvent keyEvent) { mQueuedKeys.Enqueue(keyEvent); } /// /// Allow faking scancodes. Used for test kernels /// internal static void HandleFakeScanCode(byte aScancode, bool aReleased) { HandleScanCode(aScancode, aReleased); } private static void HandleScanCode(byte aScanCode, bool aReleased) { byte key = aScanCode; if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.CapsLock) && !aReleased) { // caps lock CapsLock = !CapsLock; UpdateLeds(); } else if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.NumLock) && !aReleased) { // num lock NumLock = !NumLock; UpdateLeds(); } else if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.ScrollLock) && !aReleased) { // scroll lock ScrollLock = !ScrollLock; UpdateLeds(); } else if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.LCtrl) || _scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.RCtrl)) { ControlPressed = !aReleased; } else if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.LShift) || _scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.RShift)) { ShiftPressed = !aReleased; } else if (_scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.LAlt) || _scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.RAlt)) { AltPressed = !aReleased; } else { if (ControlPressed && AltPressed && _scanMap.ScanCodeMatchesKey(key, ConsoleKeyEx.Delete)) { Global.Console.WriteLine("Detected Ctrl-Alt-Delete! Rebooting System..."); Power.Reboot(); } if (!aReleased) { KeyEvent keyInfo; if (GetKey(key, out keyInfo)) { Enqueue(keyInfo); } } } } private static void UpdateLeds() { foreach(KeyboardBase keyboard in Keyboards) { keyboard.UpdateLeds(); } } public static bool GetKey(byte aScancode, out KeyEvent keyInfo) { if (_scanMap == null) { Debugger.DoSend("No KeyLayout"); } keyInfo = _scanMap.ConvertScanCode(aScancode, ControlPressed, ShiftPressed, AltPressed, NumLock, CapsLock, ScrollLock); return keyInfo != null; } public static bool TryReadKey(out KeyEvent oKey) { if (mQueuedKeys.Count > 0) { oKey = mQueuedKeys.Dequeue(); return true; } oKey = default(KeyEvent); return false; } public static KeyEvent ReadKey() { while (mQueuedKeys.Count == 0) { KeyboardBase.WaitForKey(); } return mQueuedKeys.Dequeue(); } public static ScanMapBase GetKeyLayout() { return _scanMap; } public static void SetKeyLayout(ScanMapBase ScanMap) { if (ScanMap != null) { _scanMap = ScanMap; } } public static void AddKeyboard(KeyboardBase Keyboard) { if (!KeyboardExists(Keyboard.GetType())) { Keyboard.OnKeyPressed = new KeyboardBase.KeyPressedEventHandler(HandleScanCode); Keyboards.Add(Keyboard); } } public static bool KeyboardExists(Type KeyboardType) { foreach (KeyboardBase Keyboard in Keyboards) { if (Keyboard.GetType() == KeyboardType) { return true; } } return false; } } }