public static void Run(string[] args)
        {
            var options = new Options();
            var optionsParser = new OptionsParser();
            if(!optionsParser.Parse(options, args))
            {
                return;
            }

            using(var context = ObjectCreator.OpenContext())
            {
                var monitor = new Emul8.UserInterface.Monitor();
                context.RegisterSurrogate(typeof(Emul8.UserInterface.Monitor), monitor);

                // we must initialize plugins AFTER registering monitor surrogate
                // as some plugins might need it for construction
                TypeManager.Instance.PluginManager.Init("CLI");

                Logger.AddBackend(ConsoleBackend.Instance, "console");

                EmulationManager.Instance.ProgressMonitor.Handler = new CLIProgressMonitor();

                var crashHandler = new CrashHandler();
                AppDomain.CurrentDomain.UnhandledException += (sender, e) => crashHandler.HandleCrash(e);

                var resetEvent = new ManualResetEventSlim();
                if(options.StdInOut)
                {
                    Logger.AddBackend(new FileBackend("logger.log"), "file");
                    var world = new StreamIOSource(Console.OpenStandardInput(), Console.OpenStandardOutput());
                    var io = new DetachableIO(world);
                    monitor.Quitted += resetEvent.Set;
                    var handler = new StdInOutHandler(io, monitor, options.Plain);
                    handler.Start();
                }
                else
                {
                    Shell shell = null;
                    Type preferredUARTAnalyzer = null;
                    if(options.Port > 0)
                    {
                        var io = new DetachableIO(new SocketIOSource(options.Port));
                        shell = ShellProvider.GenerateShell(io, monitor, true, false);
                        shell.Quitted += resetEvent.Set;
                    }
                    else if(options.ConsoleMode)
                    {
                        preferredUARTAnalyzer = typeof(UARTMultiplexedBackendAnalyzer);

                        var stream = new PtyUnixStream("/proc/self/fd/1");
                        var world = new StreamIOSource(stream, stream.Name);

                        Logger.AddBackend(new FileBackend("logger.log"), "file");
                        var consoleTerm = new ConsoleTerminal(world);
                        UARTMultiplexedBackendAnalyzer.Multiplexer = consoleTerm;
                   
                        monitor.Console = consoleTerm;

                        shell = ShellProvider.GenerateShell(monitor);
                        consoleTerm.AttachTerminal("shell", shell.Terminal);

                        shell.Quitted += resetEvent.Set;
                    }
                    else
                    {
                        preferredUARTAnalyzer = typeof(UARTWindowBackendAnalyzer);

                        var stream = new PtyUnixStream();
                        var dio = new DetachableIO(new StreamIOSource(stream, stream.Name));
                        var terminal = new UARTWindowBackendAnalyzer(dio);
                        shell = ShellProvider.GenerateShell(dio, monitor);     

                        shell.Quitted += resetEvent.Set;
                        monitor.Quitted += shell.Stop;

                        try
                        {
                            terminal.Show();
                        }
                        catch(InvalidOperationException ex)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Error.WriteLine(ex.Message);
                            resetEvent.Set();
                        }
                    }

                    if(preferredUARTAnalyzer != null)
                    {
                        EmulationManager.Instance.CurrentEmulation.BackendManager.SetPreferredAnalyzer(typeof(UARTBackend), preferredUARTAnalyzer);
                        EmulationManager.Instance.EmulationChanged += () =>
                        {
                            EmulationManager.Instance.CurrentEmulation.BackendManager.SetPreferredAnalyzer(typeof(UARTBackend), preferredUARTAnalyzer);
                        };
                    }
                    monitor.Interaction = shell.Writer;
                    monitor.UseConsole = options.ConsoleMode;
                    monitor.MachineChanged += emu => shell.SetPrompt(emu != null ? new Prompt(string.Format("({0}) ", emu), ConsoleColor.DarkYellow) : null);

                    if(options.Execute != null)
                    {
                        shell.Started += s => s.InjectInput(string.Format("{0}\n", options.Execute));
                    }
                    else if(!string.IsNullOrEmpty(options.ScriptPath))
                    {
                        shell.Started += s => s.InjectInput(string.Format("i $CWD/{0}\n", options.ScriptPath));
                    }

                    new Thread(x => shell.Start(true)) { IsBackground = true, Name = "Shell thread" }.Start();
                }

                resetEvent.Wait();
                EmulationManager.Instance.Clear();
                TypeManager.Instance.Dispose();
                Logger.Dispose();
            }
        }
Exemple #2
0
		public MainWindow(string title, string pty)
		{
			Title = title;
			Width = 700;
			Height = 400;

			terminal = new TermSharp.Terminal();
			Content = terminal;
			terminal.InnerMargin = new WidgetSpacing(5, 0, 5, 0);
			Padding = new WidgetSpacing();

			terminal.Cursor.Enabled = true;

			Font.RegisterFontFromFile(Path.Combine(Directory.GetCurrentDirectory(), "External/TermsharpConsole/RobotoMono-Regular.ttf"));
			var robotoMonoFont = Font.FromName("Roboto Mono");
			if(robotoMonoFont.Family.Contains("Roboto"))
			{
				terminal.CurrentFont = robotoMonoFont;
			}

			var contextMenu = new Menu();

			var copyMenuItem = new MenuItem("Copy");
			copyMenuItem.Clicked += (sender, e) => Clipboard.SetText(terminal.CollectClipboardData().Text);
			contextMenu.Items.Add(copyMenuItem);

			var pasteMenuItem = new MenuItem("Paste");
			contextMenu.Items.Add(pasteMenuItem);

			terminal.ContextMenu = contextMenu;

			CloseRequested += delegate
			{
				Application.Exit();
			};

			terminal.SetFocus();

			var readerThread = new Thread(() =>
			{
				var stream = new PtyUnixStream(pty);
				var vt100decoder = new TermSharp.Vt100.Decoder(terminal, stream.WriteByte, new ConsoleDecoderLogger());
				var utfDecoder = new ByteUtf8Decoder(vt100decoder.Feed);

				Application.Invoke(() =>
				{
					pasteMenuItem.Clicked += delegate
					{
						var text = Clipboard.GetText();
						var textAsBytes = Encoding.UTF8.GetBytes(text);
						foreach(var b in textAsBytes)
						{
							stream.WriteByte(b);
						}
					};
				});

				var encoder = new TermSharp.Vt100.Encoder(x => 
				{
					terminal.ClearSelection();
					terminal.MoveScrollbarToEnd();
					stream.WriteByte(x); 
				});

				terminal.KeyPressed += (s, a) =>
				{
					a.Handled = true;

					var modifiers = a.Modifiers;
					if(!Utilities.IsOnOsX)
					{
						modifiers &= ~(ModifierKeys.Command);
					}

					if(modifiers== ModifierKeys.Shift)
					{
						if(a.Key == Key.PageUp)
						{
							terminal.PageUp();
							return;
						}
						if(a.Key == Key.PageDown)
						{
							terminal.PageDown();
							return;
						}
					}
					encoder.Feed(a.Key, modifiers);
				};

				var buffer = new List<byte>();
				var noTimeoutNextTime = true;
				while(true)
				{
					if(noTimeoutNextTime)
					{
						noTimeoutNextTime = false;
					}
					else
					{
						stream.ReadTimeout = 10;
					}
					var readByte = buffer.Count > 1024 ? BufferFull : stream.ReadByte();
					if(readByte == StreamClosed)
					{
						Application.Invoke(Application.Exit);
						return;
					}
					if(readByte >= 0)
					{
						buffer.Add((byte)readByte);
					}
					else
					{
						var bufferToWrite = buffer;
						Application.Invoke(() =>
						{
							foreach (var b in bufferToWrite)
							{
								utfDecoder.Feed(b);
							}
						});
						buffer = new List<byte>();
						noTimeoutNextTime = true;
					}
				}
			})
			{ IsBackground = true };

			readerThread.Start();
		}