// // Copyright (c) Antmicro // // Full license details are defined in the 'LICENSE' file. // using System; using System.Collections.Generic; using Xwt; namespace TermSharp.Vt100 { public sealed class Encoder { public Encoder(Action dataCallback) { this.dataCallback = dataCallback; keyHandlers = new Dictionary { { Key.Escape, new [] { (byte)ControlByte.Escape } }, { Key.Return, new [] { (byte)ControlByte.CarriageReturn } }, { Key.BackSpace, new [] { (byte)ControlByte.Delete } }, { Key.Tab, new [] { (byte)ControlByte.HorizontalTab } }, { Key.Up, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'A' } }, { Key.Down, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'B' } }, { Key.Right, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'C' } }, { Key.Left, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'D' } }, { Key.Home, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'1', (byte)'~' } }, { Key.Insert, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'2', (byte)'~' } }, { Key.Delete, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'3', (byte)'~' } }, { Key.End, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'4', (byte)'~' } }, { Key.PageUp, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'5', (byte)'~' } }, { Key.PageDown, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'6', (byte)'~' } }, { Key.NumPad0, new [] { (byte)'0' } }, { Key.NumPad1, new [] { (byte)'1' } }, { Key.NumPad2, new [] { (byte)'2' } }, { Key.NumPad3, new [] { (byte)'3' } }, { Key.NumPad4, new [] { (byte)'4' } }, { Key.NumPad5, new [] { (byte)'5' } }, { Key.NumPad6, new [] { (byte)'6' } }, { Key.NumPad7, new [] { (byte)'7' } }, { Key.NumPad8, new [] { (byte)'8' } }, { Key.NumPad9, new [] { (byte)'9' } }, { Key.NumPadAdd, new [] { (byte)'+' } }, { Key.NumPadSubtract, new [] { (byte)'-' } }, { Key.NumPadMultiply, new [] { (byte)'*' } }, { Key.NumPadDivide, new [] { (byte)'/' } }, { Key.NumPadDecimal, new [] { (byte)'.' } }, { Key.NumPadEnter, new [] { (byte)ControlByte.CarriageReturn } }, { Key.Caret, new [] { (byte)'^' } }, { Key.Equal, new [] { (byte)'=' } }, { Key.F1, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'O', (byte)'P' } }, { Key.F2, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'O', (byte)'Q' } }, { Key.F3, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'O', (byte)'R' } }, { Key.F4, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)'O', (byte)'S' } }, { Key.F5, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'1', (byte)'5', (byte)'~' } }, { Key.F6, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'1', (byte)'7', (byte)'~' } }, { Key.F7, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'1', (byte)'8', (byte)'~' } }, { Key.F8, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'1', (byte)'9', (byte)'~' } }, { Key.F9, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'2', (byte)'0', (byte)'~' } }, { Key.F10, new [] { (byte)ControlByte.Escape, (byte)ControlByte.ControlSequenceIntroducer, (byte)ControlByte.ControlSequenceIntroducer, (byte)'2', (byte)'1', (byte)'~' } }, }; } public void Feed(Key key, ModifierKeys modifiers) { if(IsModifierOnly(key)) { return; } if((modifiers & ModifierKeys.Control) != 0) { HandleControlModifier(key); return; } if((modifiers & ModifierKeys.Alt) != 0) { HandleAltModifier(key); return; } if((key >= Key.Space && key <= (Key)126)) { dataCallback((byte)key); return; } byte[] response; if(keyHandlers.TryGetValue(key, out response)) { foreach(var b in response) { dataCallback(b); } } } private void HandleControlModifier(Key key) { // CtrlLeftArrow/CtrlRightArrow if(key == Key.Right || key == Key.Left) { // Invoke correct Vt100 sequence for AntShell dataCallback((byte)ControlByte.Escape); dataCallback((byte)ControlByte.ControlSequenceIntroducer); dataCallback((byte)'1'); dataCallback((byte)';'); dataCallback((byte)'5'); if(key == Key.Left) { dataCallback((byte)'D'); } else if(key == Key.Right) { dataCallback((byte)'C'); } return; } if(key >= Key.a && key <= Key.z) { key -= 32; } if(key >= Key.At && key <= (Key)95) { dataCallback((byte)(key - Key.At)); } } private void HandleAltModifier(Key key) { dataCallback((byte)ControlByte.Escape); if(key == Key.BackSpace) { dataCallback((byte)ControlByte.Delete); return; } if((key >= Key.Space && key <= (Key)126)) { dataCallback((byte)key); return; } } private static bool IsModifierOnly(Key key) { return key == Key.ControlLeft || key == Key.ControlRight || key == Key.AltLeft || key == Key.AltRight || key == Key.ShiftLeft || key == Key.ShiftRight; } private readonly Action dataCallback; private readonly Dictionary keyHandlers; } }