1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System.IO;
  7 using System.Os;
  8 
  9 namespace System
 10 {
 11     public class TerminalState
 12     {
 13         static TerminalState() : instance(new TerminalState())
 14         {
 15         }
 16         public static TerminalState& Instance()
 17         {
 18             return *instance;
 19         }
 20         private TerminalState() : tty(Open("/dev/tty"cast<OpenFlags>(OpenFlags.read | OpenFlags.write)0))
 21         {
 22         }
 23         public ~TerminalState()
 24         {
 25             Close(tty);
 26         }
 27         public nothrow int Descriptor()
 28         {
 29             return tty;
 30         }
 31         private static UniquePtr<TerminalState> instance;
 32         private int tty;
 33     }
 34     
 35     public static class Terminal
 36     {
 37         static nothrow Terminal() : 
 38             in(SharedPtr<Stream>(new FileStream(TerminalState.Instance().Descriptor())))
 39             out(SharedPtr<Stream>(new FileStream(TerminalState.Instance().Descriptor())))
 40             err(SharedPtr<Stream>(new FileStream(TerminalState.Instance().Descriptor())))
 41         {
 42         }
 43         public static void Write(const char* s)
 44         {
 45             out.Write(s);
 46         }
 47         public static void Write(const wchar* s)
 48         {
 49             out.Write(s);
 50         }
 51         public static void Write(const uchar* s)
 52         {
 53             out.Write(s);
 54         }
 55         public static void Write(const string& s)
 56         {
 57             out.Write(s);
 58         }
 59         public static void Write(const wstring& s)
 60         {
 61             out.Write(s);
 62         }
 63         public static void Write(const ustring& s)
 64         {
 65             out.Write(s);
 66         }
 67         public static void Write(bool b)
 68         {
 69             out.Write(b);
 70         }
 71         public static void Write(char c)
 72         {
 73             out.Write(c);
 74         }
 75         public static void Write(wchar w)
 76         {
 77             out.Write(w);
 78         }
 79         public static void Write(uchar u)
 80         {
 81             out.Write(u);
 82         }
 83         public static void Write(sbyte s)
 84         {
 85             out.Write(s);
 86         }
 87         public static void Write(byte b)
 88         {
 89             out.Write(b);
 90         }
 91         public static void Write(short s)
 92         {
 93             out.Write(s);
 94         }
 95         public static void Write(ushort u)
 96         {
 97             out.Write(u);
 98         }
 99         public static void Write(int i)
100         {
101             out.Write(i);
102         }
103         public static void Write(uint u)
104         {
105             out.Write(u);
106         }
107         public static void Write(long l)
108         {
109             out.Write(l);
110         }
111         public static void Write(ulong u)
112         {
113             out.Write(u);
114         }
115         public static void Write(float f)
116         {
117             out.Write(f);
118         }
119         public static void Write(double d)
120         {
121             out.Write(d);
122         }
123         public static void Write(const Date& date)
124         {
125             out.Write(date);
126         }
127         public static void Write(const DateTime& dateTime)
128         {
129             out.Write(dateTime);
130         }
131         public static void WriteLine()
132         {
133             out.WriteLine();
134         }
135         public static void WriteLine(const char* s)
136         {
137             out.WriteLine(s);
138         }
139         public static void WriteLine(const wchar* s)
140         {
141             out.WriteLine(s);
142         }
143         public static void WriteLine(const uchar* s)
144         {
145             out.WriteLine(s);
146         }
147         public static void WriteLine(const string& s)
148         {
149             out.WriteLine(s);
150         }
151         public static void WriteLine(const wstring& s)
152         {
153             out.WriteLine(s);
154         }
155         public static void WriteLine(const ustring& s)
156         {
157             out.WriteLine(s);
158         }
159         public static void WriteLine(bool b)
160         {
161             out.WriteLine(b);
162         }
163         public static void WriteLine(char x)
164         {
165             out.WriteLine(x);
166         }
167         public static void WriteLine(wchar x)
168         {
169             out.WriteLine(x);
170         }
171         public static void WriteLine(uchar x)
172         {
173             out.WriteLine(x);
174         }
175         public static void WriteLine(sbyte s)
176         {
177             out.WriteLine(s);
178         }
179         public static void WriteLine(byte b)
180         {
181             out.WriteLine(b);
182         }
183         public static void WriteLine(short s)
184         {
185             out.WriteLine(s);
186         }
187         public static void WriteLine(ushort u)
188         {
189             out.WriteLine(u);
190         }
191         public static void WriteLine(int i)
192         {
193             out.WriteLine(i);
194         }
195         public static void WriteLine(uint u)
196         {
197             out.WriteLine(u);
198         }
199         public static void WriteLine(long l)
200         {
201             out.WriteLine(l);
202         }
203         public static void WriteLine(ulong u)
204         {
205             out.WriteLine(u);
206         }
207         public static void WriteLine(float f)
208         {
209             out.WriteLine(f);
210         }
211         public static void WriteLine(double d)
212         {
213             out.WriteLine(d);
214         }
215         public static void WriteLine(const Date& date)
216         {
217             out.WriteLine(date);
218         }
219         public static void WriteLine(const DateTime& dateTime)
220         {
221             out.WriteLine(dateTime);
222         }
223         public static int Read()
224         {
225             return in.Read();
226         }
227         public static string ReadLine()
228         {
229             return in.ReadLine();
230         }
231         public static string ReadToEnd()
232         {
233             return in.ReadToEnd();
234         }
235         public static nothrow StreamReader& In()
236         {
237             return in;
238         }
239         public static nothrow StreamWriter& Out()
240         {
241             return out;
242         }
243         public static nothrow StreamWriter& Error()
244         {
245             return err;
246         }
247         public static nothrow int Descriptor()
248         {
249             return TerminalState.Instance().Descriptor();
250         }
251         private static StreamReader in;
252         private static StreamWriter out;
253         private static StreamWriter err;
254     }
255     
256     public nothrow bool IsConsole(int fd)
257     {
258         return IOCtl(fdIOControlItem.isConsolenull0) == 1;
259     }
260     
261     public void SetEcho(int fdbool value)
262     {
263         byte arg = cast<byte>(value);
264         IOCtl(fdIOControlItem.set_echo&arg1);
265     }
266     
267     public void SetRaw(int fd)
268     {
269         IOCtl(fdIOControlItem.set_rawnull0);
270     }
271 
272     public void SetCooked(int fd)
273     {
274         IOCtl(fdIOControlItem.set_cookednull0);
275     }
276     
277     public nothrow int TerminalWindowWidth()
278     {
279         return IOCtl(Terminal.Descriptor()IOControlItem.columnsnull0);
280     }
281 
282     public nothrow int TerminalWindowHeight()
283     {
284         return IOCtl(Terminal.Descriptor()IOControlItem.rowsnull0);
285     }
286     
287     public nothrow int CursorX()
288     {
289         return IOCtl(Terminal.Descriptor()IOControlItem.cursor_xnull0);
290     }
291 
292     public nothrow int CursorY()
293     {
294         return IOCtl(Terminal.Descriptor()IOControlItem.cursor_ynull0);
295     }
296 
297     public nothrow void SetCursorPos(int xint y)
298     {
299         byte[8] args;
300         MemoryWriter writer(&args[0]8);
301         writer.Write(x);
302         writer.Write(y);
303         IOCtl(Terminal.Descriptor()IOControlItem.set_cursor_pos&args[0]8);
304     }
305 
306     public void ClearScreen(int screenWidthint screenHeight)
307     {
308         int cursorX = CursorX();
309         int cursorY = CursorY();
310         ustring line(' 'screenWidth);
311         for (int i = 0; i < screenHeight; ++i;)
312         {
313             SetCursorPos(0i);
314             Terminal.Out() << line;
315         }
316         SetCursorPos(cursorXcursorY);
317     }
318     
319     public void PushLines()
320     {
321         IOCtl(Terminal.Descriptor()IOControlItem.push_linesnull0);
322     }
323     
324     public void PopLines()
325     {
326         IOCtl(Terminal.Descriptor()IOControlItem.pop_linesnull0);
327     }
328 }