diff --git a/source/Cosmos.HAL/Cosmos.HAL.csproj b/source/Cosmos.HAL/Cosmos.HAL.csproj index 0446aab77..876c84cef 100644 --- a/source/Cosmos.HAL/Cosmos.HAL.csproj +++ b/source/Cosmos.HAL/Cosmos.HAL.csproj @@ -97,11 +97,7 @@ - - - - @@ -127,7 +123,7 @@ - + @@ -145,7 +141,6 @@ - diff --git a/source/Cosmos.HAL/Global.cs b/source/Cosmos.HAL/Global.cs index db8d06e79..b3107f1a5 100644 --- a/source/Cosmos.HAL/Global.cs +++ b/source/Cosmos.HAL/Global.cs @@ -10,38 +10,11 @@ namespace Cosmos.HAL { public static readonly Debugger mDebugger = new Debugger("HAL", "Global"); - public static Keyboard Keyboard; - - public static bool NumLock - { - get { return _numLock; } - set { _numLock = value; Keyboard?.UpdateLeds(); } - } - - public static bool CapsLock - { - get { return _capsLock; } - set { _capsLock = value; Keyboard?.UpdateLeds(); } - } - - public static bool ScrollLock - { - get { return _scrollLock; } - set - { - _scrollLock = value; - Keyboard?.UpdateLeds(); - } - } - //static public PIT PIT = new PIT(); // Must be static init, other static inits rely on it not being null public static TextScreenBase TextScreen = new TextScreen(); public static PCI Pci; - private static bool _numLock; - private static bool _capsLock; - private static bool _scrollLock; private static void InitAta(Ata.ControllerIdEnum aControllerID, Ata.BusPositionEnum aBusPosition) @@ -118,21 +91,13 @@ namespace Cosmos.HAL //PCI.Setup(); } - static public void Init(TextScreenBase textScreen, Keyboard keyboard) + static public void Init(TextScreenBase textScreen) { if (textScreen != null) { TextScreen = textScreen; } - if (keyboard == null) - { - mDebugger.Send("No keyboard specified!"); - throw new SystemException("No keyboard specified!"); - } - else - { - Keyboard = keyboard; - } + mDebugger.Send("Before Core.Global.Init"); Core.Global.Init(); mDebugger.Send("Static Devices"); diff --git a/source/Cosmos.HAL/Keyboard.cs b/source/Cosmos.HAL/Keyboard.cs deleted file mode 100644 index 4579c5880..000000000 --- a/source/Cosmos.HAL/Keyboard.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Cosmos.Debug.Kernel; - -namespace Cosmos.HAL { - public abstract class Keyboard : Device { - protected Keyboard(ScanMapBase scanMap) - { - if (mQueuedKeys != null) - { - Debugger.DoSend("Skipping creation of key queue!"); - } - mQueuedKeys = new Queue(); - Debugger.DoSend("mQueuedKeys created"); - SetKeyLayout(scanMap); - Debugger.DoSend("Keylayout set"); - Initialize(); - Debugger.DoSend("Initialized"); - UpdateLeds(); - Debugger.DoSend("Leds updated"); - } - - /// - /// Initialize the device. Happens before the interrupt is registered, ie before the class is being used. - /// - protected abstract void Initialize(); - - public ScanMapBase KeyLayout { get; private set; } - - public virtual void SetKeyLayout(ScanMapBase layout) - { - KeyLayout = layout; - } - - /// - /// Allow faking scancodes. Used for test kernels - /// - internal void HandleFakeScanCode(byte aScancode, bool aReleased) - { - HandleScancode(aScancode, aReleased); - } - - public abstract void UpdateLeds(); - - protected abstract void HandleScancode(byte aScancode, bool aReleased); - - private static Queue mQueuedKeys; - - protected void Enqueue(KeyEvent aKey) - { - mQueuedKeys.Enqueue(aKey); - } - - public bool TryReadKey(out KeyEvent oKey) - { - if (mQueuedKeys.Count > 0) - { - oKey = mQueuedKeys.Dequeue(); - return true; - } - oKey = default(KeyEvent); - return false; - } - - public KeyEvent ReadKey() - { - while (mQueuedKeys.Count == 0) - { - Core.Global.CPU.Halt(); - } - return mQueuedKeys.Dequeue(); - } - - public bool ShiftPressed - { - get; - protected set; - } - - public bool ControlPressed - { - get; - protected set; - } - - public bool AltPressed - { - get; - protected set; - } - } -} diff --git a/source/Cosmos.HAL/KeyboardBase.cs b/source/Cosmos.HAL/KeyboardBase.cs new file mode 100644 index 000000000..8e93a11a0 --- /dev/null +++ b/source/Cosmos.HAL/KeyboardBase.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Cosmos.Debug.Kernel; + +namespace Cosmos.HAL +{ + public abstract class KeyboardBase : Device + { + protected KeyboardBase() + { + Initialize(); + Debugger.DoSend("Initialized"); + UpdateLeds(); + Debugger.DoSend("Leds updated"); + } + + /// + /// Initialize the device. Happens before the interrupt is registered, ie before the class is being used. + /// + protected abstract void Initialize(); + + public abstract void UpdateLeds(); + + public delegate void KeyPressedEventHandler(byte ScanCode, bool Released); + public KeyPressedEventHandler OnKeyPressed; + + public static void WaitForKey() + { + Core.Global.CPU.Halt(); + } + } +} diff --git a/source/Cosmos.HAL/PS2Keyboard.cs b/source/Cosmos.HAL/PS2Keyboard.cs index 6c0cd4537..e8006a8da 100644 --- a/source/Cosmos.HAL/PS2Keyboard.cs +++ b/source/Cosmos.HAL/PS2Keyboard.cs @@ -6,12 +6,13 @@ using Cosmos.Debug.Kernel; namespace Cosmos.HAL { - public class PS2Keyboard : Keyboard + public class PS2Keyboard : KeyboardBase { protected Core.IOGroup.Keyboard IO = Core.Global.BaseIOGroups.Keyboard; - public PS2Keyboard(ScanMapBase scanMap): base(scanMap) + public PS2Keyboard() : base() { + } protected override void Initialize() @@ -27,7 +28,7 @@ namespace Cosmos.HAL { xScanCode = (byte)(xScanCode ^ 0x80); } - HandleScancode(xScanCode, xReleased); + OnKeyPressed?.Invoke(xScanCode, xReleased); } public override void UpdateLeds() @@ -43,78 +44,5 @@ namespace Cosmos.HAL //{ //} } - - protected override void HandleScancode(byte aScancode, bool aReleased) - { - byte key = aScancode; - if (key == 0x3A && !aReleased) - { - // caps lock - Global.CapsLock = !Global.CapsLock; - UpdateLeds(); - } - else if (key == 0x45 && !aReleased) - { - // num lock - Global.NumLock = !Global.NumLock; - UpdateLeds(); - } - else if (key == 0x46 && !aReleased) - { - // scroll lock - Global.ScrollLock = !Global.ScrollLock; - UpdateLeds(); - } - else - switch (key) - { - case 0x1D: - { - ControlPressed = !aReleased; - break; - } - case 0x2A: - case 0x36: - { - ShiftPressed = !aReleased; - break; - } - case 0x38: - { - AltPressed = !aReleased; - break; - } - default: - { - if (ControlPressed && AltPressed && (key == 0x53)) - { - Console.WriteLine("Detected Ctrl-Alt-Delete! Rebooting System..."); - Core.Global.CPU.Reboot(); - } - - if (!aReleased) - { - KeyEvent keyInfo; - if (GetKey(key, aReleased, out keyInfo)) - { - Enqueue(keyInfo); - } - } - - - break; - } - } - } - - public bool GetKey(byte aScancode, bool released, out KeyEvent keyInfo) - { - if (KeyLayout == null) - { - Debugger.DoSend("No KeyLayout"); - } - keyInfo = KeyLayout.ConvertScanCode(aScancode, ControlPressed, ShiftPressed, AltPressed, Global.NumLock, Global.CapsLock, Global.ScrollLock); - return keyInfo != null; - } } } diff --git a/source/Cosmos.IL2CPU/AppAssembler.cs b/source/Cosmos.IL2CPU/AppAssembler.cs index 9c173e349..b36c15db9 100644 --- a/source/Cosmos.IL2CPU/AppAssembler.cs +++ b/source/Cosmos.IL2CPU/AppAssembler.cs @@ -1292,7 +1292,7 @@ namespace Cosmos.IL2CPU { if (ILOp.TypeIsReferenceType(aFrom.MethodBase.DeclaringType) && !ILOp.TypeIsReferenceType(xParams[0].ParameterType)) { - throw new Exception("Original method argument $this is a reference type. Plug attribute first argument is not an argument type, nor was it marked with ObjectPointerAccessAttribute!"); + throw new Exception("Original method argument $this is a reference type. Plug attribute first argument is not an argument type, nor was it marked with ObjectPointerAccessAttribute! Method: " + aFrom.MethodBase.GetFullName() + " Parameter: " + xParams[0].Name); } } @@ -1332,7 +1332,7 @@ namespace Cosmos.IL2CPU { if (ILOp.TypeIsReferenceType(xFromParameters[xOriginalParamsIdx].ParameterType) && !ILOp.TypeIsReferenceType(xParams[xCurParamIdx].ParameterType)) { - throw new Exception("Original method argument $this is a reference type. Plug attribute first argument is not an argument type, nor was it marked with ObjectPointerAccessAttribute!"); + throw new Exception("Original method argument $this is a reference type. Plug attribute first argument is not an argument type, nor was it marked with ObjectPointerAccessAttribute! Method: " + aFrom.MethodBase.GetFullName() + " Parameter: " + xParam.Name); } // normal field access XS.Comment("Loading parameter " + (xCurParamIdx + xCurParamOffset)); diff --git a/source/Cosmos.System.Plugs/System/ConsoleImpl.cs b/source/Cosmos.System.Plugs/System/ConsoleImpl.cs index bdc69cf2b..a3b55ffcf 100644 --- a/source/Cosmos.System.Plugs/System/ConsoleImpl.cs +++ b/source/Cosmos.System.Plugs/System/ConsoleImpl.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using Cosmos.HAL; using Encoding = System.Text.Encoding; using Plug = Cosmos.IL2CPU.Plugs.PlugAttribute; @@ -385,7 +384,7 @@ namespace Cosmos.System.Plugs.System // TODO special cases, if needed, that returns -1 KeyEvent xResult; - if (HAL.Global.Keyboard.TryReadKey(out xResult)) + if (KeyboardManager.TryReadKey(out xResult)) { return xResult.KeyChar; } @@ -399,7 +398,7 @@ namespace Cosmos.System.Plugs.System public static ConsoleKeyInfo ReadKey(Boolean intercept) { - var key = Cosmos.HAL.Global.Keyboard.ReadKey(); + var key = KeyboardManager.ReadKey(); if (false == intercept && key.KeyChar != '\0') { Write(key.KeyChar); @@ -420,7 +419,7 @@ namespace Cosmos.System.Plugs.System KeyEvent current; int currentCount = 0; - while ((current = HAL.Global.Keyboard.ReadKey()).Key != ConsoleKeyEx.Enter) + while ((current = KeyboardManager.ReadKey()).Key != ConsoleKeyEx.Enter) { if (current.Key == ConsoleKeyEx.NumEnter) break; //Check for "special" keys diff --git a/source/Cosmos.System.Plugs/System/RuntimeTypeImpl.cs b/source/Cosmos.System.Plugs/System/RuntimeTypeImpl.cs index d16de67a2..704955f36 100644 --- a/source/Cosmos.System.Plugs/System/RuntimeTypeImpl.cs +++ b/source/Cosmos.System.Plugs/System/RuntimeTypeImpl.cs @@ -9,7 +9,7 @@ namespace Cosmos.System.Plugs.System { public static string ToString(object aThis) { - throw new NotImplementedException("RuntimeTypePlug.ToStrin()"); + throw new NotImplementedException("RuntimeTypePlug.ToString()"); } } diff --git a/source/Cosmos.System.Plugs/System/TypeImpl.cs b/source/Cosmos.System.Plugs/System/TypeImpl.cs index e205a8450..dfa1e55a2 100644 --- a/source/Cosmos.System.Plugs/System/TypeImpl.cs +++ b/source/Cosmos.System.Plugs/System/TypeImpl.cs @@ -24,12 +24,19 @@ namespace Cosmos.System.Plugs.System } [PlugMethod(Signature = "System_Boolean__System_Type_op_Equality_System_Type__System_Type_")] - public static bool op_Equality(uint left, uint right) + public static bool op_Equality([ObjectPointerAccess]uint left, [ObjectPointerAccess]uint right) { // for now, type info is the type id. return left == right; } + [PlugMethod(Signature = "System_Boolean__System_Type_op_Inequality_System_Type__System_Type_")] + public static bool op_Inequality([ObjectPointerAccess]uint left, [ObjectPointerAccess]uint right) + { + // for now, type info is the type id. + return left != right; + } + //System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle) } } diff --git a/source/Cosmos.System/Cosmos.System.csproj b/source/Cosmos.System/Cosmos.System.csproj index 8e2be9846..35e3fda0e 100644 --- a/source/Cosmos.System/Cosmos.System.csproj +++ b/source/Cosmos.System/Cosmos.System.csproj @@ -101,6 +101,15 @@ + + + + + + + + + @@ -118,9 +127,6 @@ - - - @@ -148,11 +154,11 @@ - - \ No newline at end of file + diff --git a/source/Cosmos.System/Global.cs b/source/Cosmos.System/Global.cs index 4827ba31c..55b6da02c 100644 --- a/source/Cosmos.System/Global.cs +++ b/source/Cosmos.System/Global.cs @@ -25,23 +25,23 @@ namespace Cosmos.System public static bool NumLock { - get { return HAL.Global.NumLock; } - set { HAL.Global.NumLock = value; } + get { return KeyboardManager.NumLock; } + set { KeyboardManager.NumLock = value; } } public static bool CapsLock { - get { return HAL.Global.CapsLock; } - set { HAL.Global.CapsLock = value; } + get { return KeyboardManager.CapsLock; } + set { KeyboardManager.CapsLock = value; } } public static bool ScrollLock { - get { return HAL.Global.ScrollLock; } - set { HAL.Global.ScrollLock = value; } + get { return KeyboardManager.ScrollLock; } + set { KeyboardManager.ScrollLock = value; } } - public static void Init(TextScreenBase textScreen, Keyboard keyboard) + public static void Init(TextScreenBase textScreen) { // We must init Console before calling Inits. // This is part of the "minimal" boot to allow output. @@ -51,12 +51,19 @@ namespace Cosmos.System Console = new Console(textScreen); } + mDebugger.Send("Creating Keyboard"); + mDebugger.Send("HW Init"); - HAL.Global.Init(textScreen, keyboard); + HAL.Global.Init(textScreen); NumLock = false; CapsLock = false; ScrollLock = false; //Network.NetworkStack.Init(); } + + public static void ChangeKeyLayout(ScanMapBase scanMap) + { + KeyboardManager.SetKeyLayout(scanMap); + } } } diff --git a/source/Cosmos.System/Kernel.cs b/source/Cosmos.System/Kernel.cs index 48db41ec2..2558dabf5 100644 --- a/source/Cosmos.System/Kernel.cs +++ b/source/Cosmos.System/Kernel.cs @@ -26,11 +26,15 @@ namespace Cosmos.System return null; } - protected virtual ScanMapBase GetKeyboardScanMap() + protected ScanMapBase GetKeyboardScanMap() { - return new US_Standard(); + return KeyboardManager.GetKeyLayout(); } + protected void SetKeyboardScanMap(ScanMapBase ScanMap) + { + KeyboardManager.SetKeyLayout(ScanMap); + } /// /// Start the system up using the properties for configuration. @@ -56,7 +60,10 @@ namespace Cosmos.System HAL.Bootstrap.Init(); Global.mDebugger.Send("Global Init"); - Global.Init(GetTextScreen(), new PS2Keyboard(GetKeyboardScanMap())); + Global.Init(GetTextScreen()); + + //Start with a PS2Keyboard + KeyboardManager.AddKeyboard(new PS2Keyboard()); // Provide the user with a clear screen if they requested it if (ClearScreen) diff --git a/source/Cosmos.HAL/ConsoleKeyEx.cs b/source/Cosmos.System/Keyboard/ConsoleKeyEx.cs similarity index 98% rename from source/Cosmos.HAL/ConsoleKeyEx.cs rename to source/Cosmos.System/Keyboard/ConsoleKeyEx.cs index e9588b3f9..16a960180 100644 --- a/source/Cosmos.HAL/ConsoleKeyEx.cs +++ b/source/Cosmos.System/Keyboard/ConsoleKeyEx.cs @@ -1,4 +1,4 @@ -namespace Cosmos.HAL +namespace Cosmos.System { public enum ConsoleKeyEx { @@ -53,7 +53,7 @@ namespace Cosmos.HAL LBracket, RBracket, Enter, - + CapsLock, A, S, @@ -131,4 +131,4 @@ namespace Cosmos.HAL Sleep, Wake } -} \ No newline at end of file +} diff --git a/source/Cosmos.HAL/ConsoleKeyExExtensions.cs b/source/Cosmos.System/Keyboard/ConsoleKeyExExtensions.cs similarity index 99% rename from source/Cosmos.HAL/ConsoleKeyExExtensions.cs rename to source/Cosmos.System/Keyboard/ConsoleKeyExExtensions.cs index 829de9078..359cf96b3 100644 --- a/source/Cosmos.HAL/ConsoleKeyExExtensions.cs +++ b/source/Cosmos.System/Keyboard/ConsoleKeyExExtensions.cs @@ -1,6 +1,6 @@ using System; -namespace Cosmos.HAL +namespace Cosmos.System { public static class ConsoleKeyExExtensions { @@ -178,4 +178,4 @@ namespace Cosmos.HAL } } } -} \ No newline at end of file +} diff --git a/source/Cosmos.HAL/KeyEvent.cs b/source/Cosmos.System/Keyboard/KeyEvent.cs similarity index 98% rename from source/Cosmos.HAL/KeyEvent.cs rename to source/Cosmos.System/Keyboard/KeyEvent.cs index 05aed93e7..b985ccadb 100644 --- a/source/Cosmos.HAL/KeyEvent.cs +++ b/source/Cosmos.System/Keyboard/KeyEvent.cs @@ -1,6 +1,6 @@ using System; -namespace Cosmos.HAL +namespace Cosmos.System { public class KeyEvent { @@ -61,4 +61,4 @@ namespace Cosmos.HAL this.Type = type; } } -} \ No newline at end of file +} diff --git a/source/Cosmos.HAL/KeyMapping.cs b/source/Cosmos.System/Keyboard/KeyMapping.cs similarity index 76% rename from source/Cosmos.HAL/KeyMapping.cs rename to source/Cosmos.System/Keyboard/KeyMapping.cs index d1c9e9bc5..937b326fa 100644 --- a/source/Cosmos.HAL/KeyMapping.cs +++ b/source/Cosmos.System/Keyboard/KeyMapping.cs @@ -1,8 +1,8 @@ -namespace Cosmos.HAL +namespace Cosmos.System { public class KeyMapping { - public uint Scancode; + public byte Scancode; public char Value; public char Shift; public char Num; @@ -16,7 +16,7 @@ namespace Cosmos.HAL public ConsoleKeyEx Key; public ConsoleKeyEx NumLockKey; - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, char ctrl, char shiftctrl, ConsoleKeyEx aKey, ConsoleKeyEx numKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, char ctrl, char shiftctrl, ConsoleKeyEx aKey, ConsoleKeyEx numKey) { Scancode = aScanCode; Value = norm; @@ -34,59 +34,59 @@ namespace Cosmos.HAL NumLockKey = numKey; } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, ConsoleKeyEx aKey, ConsoleKeyEx numKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, ConsoleKeyEx aKey, ConsoleKeyEx numKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, shiftaltgr, '\0', '\0', aKey, numKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, ConsoleKeyEx aKey, ConsoleKeyEx numKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, ConsoleKeyEx aKey, ConsoleKeyEx numKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, '\0', '\0', '\0', aKey, numKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, char ctrl, char shiftctrl, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, char ctrl, char shiftctrl, ConsoleKeyEx aKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, shiftaltgr, ctrl, shiftctrl, aKey, aKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, ConsoleKeyEx aKey) - : this (aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, shiftaltgr, '\0', '\0', aKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, char shiftaltgr, ConsoleKeyEx aKey) + : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, shiftaltgr, '\0', '\0', aKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, char altgr, ConsoleKeyEx aKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, altgr, '\0', '\0', '\0', aKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, ConsoleKeyEx aKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, '\0', '\0', '\0', '\0', aKey) { } - public KeyMapping(uint aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, ConsoleKeyEx aKey, ConsoleKeyEx numKey) + public KeyMapping(byte aScanCode, char norm, char shift, char num, char caps, char shiftcaps, char shiftnum, ConsoleKeyEx aKey, ConsoleKeyEx numKey) : this(aScanCode, norm, shift, num, caps, shiftcaps, shiftnum, '\0', aKey, numKey) { } - public KeyMapping(uint aScanCode, int norm, int shift, int num, int caps, int shiftcaps, int shiftnum, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, int norm, int shift, int num, int caps, int shiftcaps, int shiftnum, ConsoleKeyEx aKey) : this(aScanCode, (char)norm, (char)shift, (char)num, (char)caps, (char)shiftcaps, (char)shiftnum, aKey) { } - public KeyMapping(uint aScanCode, char num, ConsoleKeyEx aKey, ConsoleKeyEx numKey) + public KeyMapping(byte aScanCode, char num, ConsoleKeyEx aKey, ConsoleKeyEx numKey) : this(aScanCode, '\0', '\0', num, '\0', '\0', '\0', aKey, numKey) { } - public KeyMapping(uint aScanCode, char n, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, char n, ConsoleKeyEx aKey) : this(aScanCode, n, n, n, n, n, n, aKey) { } - public KeyMapping(uint aScanCode, ConsoleKeyEx aKey) + public KeyMapping(byte aScanCode, ConsoleKeyEx aKey) : this(aScanCode, '\0', '\0', '\0', '\0', '\0', '\0', aKey) { } } -} \ No newline at end of file +} diff --git a/source/Cosmos.System/Keyboard/KeyboardManager.cs b/source/Cosmos.System/Keyboard/KeyboardManager.cs new file mode 100644 index 000000000..3b03d524a --- /dev/null +++ b/source/Cosmos.System/Keyboard/KeyboardManager.cs @@ -0,0 +1,201 @@ +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; + } + } +} diff --git a/source/Cosmos.HAL/ScanMapBase.cs b/source/Cosmos.System/Keyboard/ScanMapBase.cs similarity index 86% rename from source/Cosmos.HAL/ScanMapBase.cs rename to source/Cosmos.System/Keyboard/ScanMapBase.cs index 082036ce0..f10a1713d 100644 --- a/source/Cosmos.HAL/ScanMapBase.cs +++ b/source/Cosmos.System/Keyboard/ScanMapBase.cs @@ -2,8 +2,9 @@ using System.Collections.Generic; using Cosmos.Debug.Kernel; +using Cosmos.HAL; -namespace Cosmos.HAL +namespace Cosmos.System { public abstract class ScanMapBase { @@ -82,5 +83,18 @@ namespace Cosmos.HAL return found ? keyev : null; } + + public bool ScanCodeMatchesKey(byte ScanCode, ConsoleKeyEx Key) + { + for (int i = 0; i < _keys.Count; i++) + { + if (_keys[i].Scancode == ScanCode && _keys[i].Key == Key) + { + return true; + } + } + + return false; + } } } diff --git a/source/Cosmos.System/ScanMaps/DE_Standard.cs b/source/Cosmos.System/Keyboard/ScanMaps/DE_Standard.cs similarity index 100% rename from source/Cosmos.System/ScanMaps/DE_Standard.cs rename to source/Cosmos.System/Keyboard/ScanMaps/DE_Standard.cs diff --git a/source/Cosmos.System/ScanMaps/FR_Standard.cs b/source/Cosmos.System/Keyboard/ScanMaps/FR_Standard.cs similarity index 100% rename from source/Cosmos.System/ScanMaps/FR_Standard.cs rename to source/Cosmos.System/Keyboard/ScanMaps/FR_Standard.cs diff --git a/source/Cosmos.System/ScanMaps/US_Standard.cs b/source/Cosmos.System/Keyboard/ScanMaps/US_Standard.cs similarity index 100% rename from source/Cosmos.System/ScanMaps/US_Standard.cs rename to source/Cosmos.System/Keyboard/ScanMaps/US_Standard.cs diff --git a/source/Cosmos.System/TestingHelpers.cs b/source/Cosmos.System/TestingHelpers.cs index 1692a3eb0..f73b5f5de 100644 --- a/source/Cosmos.System/TestingHelpers.cs +++ b/source/Cosmos.System/TestingHelpers.cs @@ -8,11 +8,7 @@ namespace Cosmos.System internal static void KeyboardAddFakeScanCode(byte aScanCode, bool aReleased) { Debugger.DoSend("Before HandleFakeScanCode"); - if (HAL.Global.Keyboard == null) - { - Debugger.DoSend("No Keyboard set!"); - } - HAL.Global.Keyboard.HandleFakeScanCode(aScanCode, aReleased); + KeyboardManager.HandleFakeScanCode(aScanCode, aReleased); Debugger.DoSend("After HandleFakeScanCode"); } }