1 //
2 // Copyright (c) 2010-2022 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using AntShell.Terminal;
9 using TermSharp;
10 using TermSharp.Vt100;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.UI;
13 using Antmicro.Migrant;
14 
15 namespace Antmicro.Renode.UI
16 {
17     [Transient]
18     public class TerminalIOSource : IActiveIOSource, IDisposable
19     {
TerminalIOSource(Terminal terminal)20         public TerminalIOSource(Terminal terminal)
21         {
22             vt100decoder = new TermSharp.Vt100.Decoder(terminal, b => HandleInput(b), new TerminalToRenodeLogger(terminal));
23             utfDecoder = new ByteUtf8Decoder(x => ApplicationExtensions.InvokeInUIThread(() => vt100decoder.Feed(x)));
24         }
25 
Dispose()26         public void Dispose()
27         {
28             HandleInput(-1);
29         }
30 
Flush()31         public void Flush()
32         {
33             // do nothing
34         }
35 
Pause()36         public void Pause()
37         {
38             // Required by IActiveIOSource interface
39         }
40 
Resume()41         public void Resume()
42         {
43             // Required by IActiveIOSource interface
44         }
45 
Write(byte b)46         public void Write(byte b)
47         {
48             BeforeWrite?.Invoke(b);
49             utfDecoder.Feed(b);
50         }
51 
HandleInput(int b)52         public void HandleInput(int b)
53         {
54             var br = ByteRead;
55             if(br != null)
56             {
57                 br(b);
58             }
59         }
60 
61         public bool IsAnythingAttached { get { return ByteRead != null; } }
62 
63         public event Action<int> ByteRead;
64         public event Action<byte> BeforeWrite;
65 
66         private readonly TermSharp.Vt100.Decoder vt100decoder;
67         private readonly ByteUtf8Decoder utfDecoder;
68 
69         private class TerminalToRenodeLogger : IDecoderLogger
70         {
TerminalToRenodeLogger(Terminal t)71             public TerminalToRenodeLogger(Terminal t)
72             {
73                 terminal = t;
74             }
75 
Log(string format, params object[] args)76             public void Log(string format, params object[] args)
77             {
78                 Logger.LogAs(terminal, LogLevel.Warning, format, args);
79             }
80 
81             private readonly Terminal terminal;
82         }
83     }
84 }
85 
86