using XFESystem.Browser;
using XFESystem.Console;
using XFESystem.ConsoleDemo;
using XFESystem.Core;
using XFESystem.Desktop;
using XFESystem.ManagedRuntime;
using XFESystem.Platform;
using XFESystem.NativeRuntime.Application.Web;
namespace XFESystem.NativeRuntime.Application;
/// <summary>Ordinary Microsoft NativeAOT Main, called after the independently installed PAL/bootstrapper.</summary>
internal static class Program
{
private const string ManagedDemoPath = "X:\\Programs\\ManagedHello\\ManagedHello.dll";
private static int Main()
{
NativePlatform.Write("XFE_INDEPENDENT_APPLICATION_ENTER\nXFE_SYSTEM_EDITION|Desktop\n");
try
{
global::System.Console.SetOut(new NativeDiagnosticWriter());
global::System.Console.SetError(new NativeDiagnosticWriter());
NativePlatform.RequireClock();
RuntimeSelfCheck.Run();
var surface = NativePlatform.ReadFramebuffer();
int scalePercent = surface.Width >= 3000 || surface.Height >= 1800 ? 200 : 100;
var canvas = new CpuFramebufferCanvas(new BootFramebufferPresenter(new MemoryFramebufferPresenter(surface)), scalePercent: scalePercent, timestamp: NativePlatform.Nanoseconds);
var workspace = CreateWorkspace();
workspace.CreateDirectory(SystemPaths.Combine(SystemPaths.System, "Diagnostics"));
var gpuReport = NativeGpuDiagnostics.ReadReport(out bool hasRtx5090);
var gpuReportPath = SystemPaths.Combine(SystemPaths.System, "Diagnostics\\Gpu.txt");
var usbReportPath = SystemPaths.Combine(SystemPaths.System, "Diagnostics\\Usb.txt");
workspace.WriteText(usbReportPath, NativeUsbDiagnostics.ReadReport());
workspace.WriteText(gpuReportPath, gpuReport);
var browser = new BrowserService(new NativeWebTransport(), limits: new BrowserLimits
{
MaximumExternalResourceCharacters = 2_500_000,
// First-use cryptographic setup also counts toward the bounded
// request, including under QEMU TCG. It runs on the navigation worker.
NetworkTimeout = TimeSpan.FromSeconds(60)
}) { Trace = NativePlatform.Write };
// RuntimeSelfCheck has exercised real GC/EH/TLS and managed threads.
// Each page keeps one thread owner; navigation cannot block editor work.
using var editorWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Editor worker failed: " + error.Message));
using var navigationWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Navigation worker failed: " + error.Message));
using var programWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Program worker failed: " + error.Message));
var uiCompletions = new Queue<Action>();
object completionGate = new();
void PostCompletion(Action completed) { lock (completionGate) uiCompletions.Enqueue(completed); }
void DrainCompletions()
{
for (int count = 0; count < 64; count++)
{
Action? completed;
lock (completionGate) completed = uiCompletions.Count > 0 ? uiCompletions.Dequeue() : null;
if (completed is null) return;
completed();
}
}
var editorPreparation = new BrowserEditorPreparationService(browser, editorWorker, canvas,
NativePlatform.Write, () => Environment.CurrentManagedThreadId, NativePlatform.Milliseconds, navigationWorker);
var terminal = new TerminalBuffer(100, 30);
var writer = new TerminalTextWriter(terminal);
DesktopSession? desktop = null;
void RunConsoleDemo()
{
terminal.Reset(); ConsoleDemoScenario.Run(writer); ConsoleDemoScenario.RunXfeConsoleApi(writer);
terminal.Complete();
var snapshot = writer.Snapshot();
string text = string.Concat(snapshot.Cells.Select(cell => cell.Text));
if (!text.Contains(ConsoleDemoScenario.SuccessMarker, StringComparison.Ordinal) ||
!text.Contains("XFEConsole API: Real NuGet 2.6.0", StringComparison.Ordinal))
throw new InvalidOperationException("The real console demo did not produce its terminal markers.");
desktop!.SetTerminalSnapshot(snapshot);
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_DEMO_OK ANSI XFEConsole2.6.0 terminal_cells\n");
}
void RunManagedApplication(string path)
{
var programTerminal = new TerminalBuffer(100, 30);
var programOutput = new TerminalTextWriter(programTerminal);
if (!programWorker.TryQueue(() =>
{
ExecuteManagedApplication(path, programOutput);
programTerminal.Complete();
var snapshot = programOutput.Snapshot();
PostCompletion(() =>
{
desktop!.SetTerminalSnapshot(snapshot);
pendingConsoleWindowId = desktop.ActiveWindow?.Id ?? 0; pendingConsolePath = path;
});
})) desktop!.WriteTerminalOutput("Program queue is busy.\n");
}
void ExecuteManagedApplication(string path, TerminalTextWriter output)
{
try
{
var result = new ManagedApplicationRunner().Execute(workspace.ReadBytes(path), new TerminalManagedConsole(output));
output.WriteLine("Managed ConsoleIL exit: " + result.ExitCode);
var sampleText = string.Concat(output.Snapshot().Cells.Select(cell => cell.Text));
if (result.ExitCode == 0 && sampleText.Contains("XFE_MANAGED_APP_OK", StringComparison.Ordinal) &&
sampleText.Contains("XFE_MANAGED_XFECONSOLE_OK", StringComparison.Ordinal))
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_IL_OK actual_embedded_net10_PE bounded_interpreter\n");
}
catch (Exception error) when (error is not OutOfMemoryException and not StackOverflowException)
{ output.WriteLine("Managed program failed: " + error.Message); }
}
desktop = new DesktopSession(canvas, workspace, browser, RunConsoleDemo, RunManagedApplication,
NativePlatform.Milliseconds, editorPreparation: editorPreparation,
threadIdentity: () => Environment.CurrentManagedThreadId)
{
Trace = NativePlatform.Write,
TerminalProgramRequested = request =>
{
if (!programWorker.TryQueue(() =>
{
ExecuteManagedApplication(request.Path, request.Output);
PostCompletion(() =>
{
desktop!.RefreshTerminalOutput(request.WindowId);
pendingConsoleWindowId = request.WindowId; pendingConsolePath = request.Path;
});
}))
{
request.Output.WriteLine("Program queue is busy.");
PostCompletion(() => desktop!.RefreshTerminalOutput(request.WindowId));
}
}
};
var input = new Ps2InputSource(new NativePs2ReportBackend(), canvas.NativeWidth, canvas.NativeHeight, canvas.ScalePercent,
() => new(desktop.HasBrowserContentFocus, desktop.ActiveWindow?.Application));
desktop.Open(DesktopApplication.Files);
// Entity tests must be readable even before native USB HID works.
// This is a plain RAM text file; no web/Monaco initialization is needed.
if (hasRtx5090) desktop.OpenFile(gpuReportPath);
desktop.Pointer(input.PointerX, input.PointerY, false, timestampMs: NativePlatform.Milliseconds());
desktop.Render();
if (!desktop.LastFrameCompleted || canvas.FramesPresented == 0)
throw new InvalidOperationException("The desktop did not finish an actual raw framebuffer presentation.");
NativePlatform.Write("XFE_INDEPENDENT_DESKTOP_FIRST_FRAME|Width|" + canvas.NativeWidth + "|Height|" + canvas.NativeHeight +
"|ScalePercent|" + canvas.ScalePercent + "|Presented|" + canvas.FramesPresented + "\n");
NativePlatform.Write("XFE_INDEPENDENT_INPUT|Connected|" + (input.IsAvailable ? 1 : 0) + "|Keyboard|" + (input.Capabilities & 1) +
"|Mouse|" + ((input.Capabilities >> 1) & 1) + "|Wheel|" + ((input.Capabilities >> 2) & 1) + "|Backend|PS2+xHCI|UsbHid|" + NativeUsbDiagnostics.KeyboardMouse + "\n");
NativePlatform.Write("XFE_INDEPENDENT_CAPABILITIES|RAMOnly|"+(workspace.IsPersistent?0:1)+"|NativeNetwork|1|NetworkBackend|E1000_StaticQemuNat|Gpu|0|Cuda|0|BackgroundEditor|1|EditorThread|" +
editorWorker.WorkerThreadId + "|NavigationThread|" + navigationWorker.WorkerThreadId + "|UiThread|" + Environment.CurrentManagedThreadId + "\n");
ReportWindowState(desktop);
long nextUsb = NativePlatform.Milliseconds() + 2000;
Pump(desktop, input, () => {
DrainCompletions(); long now = NativePlatform.Milliseconds();
if (now >= nextUsb) { nextUsb = now + 2000; workspace.WriteText(usbReportPath, NativeUsbDiagnostics.ReadReport()); }
});
return 0;
}
catch (Exception error)
{
NativePlatform.Write("XFE_INDEPENDENT_APPLICATION_FAILED|" + error.Message + "\n");
NativePlatform.Halt("Managed desktop failed: " + error.Message);
return 1;
}
}
private static IWorkspaceBinaryStorage CreateWorkspace()
{
var workspace = NativeWorkspace.Open();
string welcome=SystemPaths.Combine(SystemPaths.Desktop,"Welcome.md");
if(!workspace.Exists(welcome))workspace.WriteText(welcome,workspace.IsPersistent?"# XFESystem\n\nFiles and settings are saved to the boot USB workspace.\n":"# XFESystem\n\nRAM fallback: no usable boot USB storage. Files disappear after shutdown.\n");
string helloJs=SystemPaths.Combine(SystemPaths.Documents,"Hello.js");
if(!workspace.Exists(helloJs))workspace.WriteText(helloJs,"const greeting = 'XFESystem';\nconsole.log(`Hello from ${greeting}!`);\n");
string helloCs=SystemPaths.Combine(SystemPaths.Documents,"Hello.cs");
if(!workspace.Exists(helloCs))workspace.WriteText(helloCs,"using System;\n\nConsole.ForegroundColor = ConsoleColor.Cyan;\nConsole.WriteLine(\"Hello XFESystem!\");\nConsole.ResetColor();\n");
string readme=SystemPaths.Combine(SystemPaths.Documents,"Readme.md");
if(!workspace.Exists(readme))workspace.WriteText(readme, """
# XFESystem 独立内核
启动 U 盘可用时,文件和设置保存到物理 U 盘;没有可用启动 U 盘时明确回退到 RAM 会话。
- 原有 Desktop、Browser、Documents 和 Terminal 接口继续使用。
- PS/2 与 xHCI HID 输入已接入,实体兼容仍需验收。
- X:\UsbFiles 对应 U 盘 UserFiles 文件夹,可以运行符合 ConsoleIL 范围的 .dll。
- QEMU e1000 网络已接入;GPU/CUDA 尚未实现。
""");
string parity=SystemPaths.Combine(SystemPaths.Documents,"WebsiteParity.md");
if(!workspace.Exists(parity))workspace.WriteText(parity,
XFESystem.Documents.WebsiteAssets.ReadText("Fixtures/WebsiteParity.md"));
workspace.CreateDirectory("X:\\Programs\\ManagedHello");
using var sample = typeof(Program).Assembly.GetManifestResourceStream("ApplicationSamples/ManagedHello.dll")
?? throw new InvalidOperationException("The actual ConsoleIL sample assembly is missing.");
if (sample.Length > ManagedRuntimeCapabilities.MaxImageBytes) throw new InvalidDataException("Managed sample exceeds the ConsoleIL image budget.");
byte[] image = new byte[checked((int)sample.Length)]; sample.ReadExactly(image);
if(!workspace.Exists(ManagedDemoPath))workspace.WriteBytes(ManagedDemoPath, image);
string samplePath=SystemPaths.Combine(SystemPaths.Documents,"ManagedHello.dll");
if(!workspace.Exists(samplePath))workspace.WriteBytes(samplePath,image);
return workspace;
}
// Input remains an explicit optional adapter. No fabricated reports or host window input enter this loop.
private static void Pump(DesktopSession desktop, INativeInputSource? input, Action drainCompletions)
{
long previous = NativePlatform.Milliseconds(), nextTick = previous;
for (;;)
{
long now = NativePlatform.Milliseconds();
if (now < previous) throw new InvalidOperationException("The native monotonic clock moved backward.");
previous = now;
drainCompletions();
if (input is { IsAvailable: true })
for (int reports = 0; reports < 256 && input.TryRead(out var report); reports++) NativeInput.Dispatch(desktop, report, now);
if (now >= nextTick)
{
desktop.AdvanceFeedback(now);
if (desktop.NeedsRender)
{
desktop.Render();
if (desktop.LastFrameCompleted)
{
if (pendingConsolePath is { } presentedPath && desktop.ActiveWindow is { Application: DesktopApplication.Terminal } terminalWindow &&
terminalWindow.Id == pendingConsoleWindowId)
{
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_PRESENTED|Path|" + presentedPath + "|Window|" + terminalWindow.Id + "\n");
pendingConsolePath = null;
}
ReportWindowState(desktop);
ReportTerminalState(desktop);
if (desktop.ActiveWindow is { } active && (active.BrowserSession is not null || active.PreviewSession is not null)) ReportBrowserState(active, now);
}
}
nextTick = now + 16;
}
Thread.Sleep(1);
}
}
private static string lastWindowState = "";
private static string? pendingConsolePath;
private static int pendingConsoleWindowId;
private static TerminalSnapshot? lastTerminalSnapshot;
private static int lastTerminalWindowId;
private static void ReportTerminalState(DesktopSession desktop)
{
if (desktop.ActiveWindow is not { Application: DesktopApplication.Terminal, Terminal: { } snapshot, Shell: { } shell } window ||
window.Id == lastTerminalWindowId && ReferenceEquals(snapshot, lastTerminalSnapshot)) return;
lastTerminalWindowId = window.Id; lastTerminalSnapshot = snapshot;
var text = new System.Text.StringBuilder();
for (int row = Math.Max(0, snapshot.CursorRow - 31); row <= Math.Min(snapshot.CursorRow, snapshot.Rows - 1); row++)
{
for (int col = 0; col < snapshot.Columns; col++)
{
var cell = snapshot.GetCell(col, row);
if (!cell.IsContinuation) text.Append(cell.Text);
}
text.Append('\n');
}
string json = "{\"WindowId\":" + window.Id + ",\"Text\":" + NativeWebTransport.Quote(text.ToString()) +
",\"Input\":" + NativeWebTransport.Quote(shell.Input) + ",\"Prompt\":" + NativeWebTransport.Quote(shell.Prompt) +
",\"Busy\":" + (window.TerminalProgramRunning ? "true" : "false") + ",\"Version\":" + NativeWebTransport.Quote(shell.Version) +
",\"LastCommand\":" + NativeWebTransport.Quote(shell.History.LastOrDefault()) + "}";
NativePlatform.Write("XFE_TERMINAL_SNAPSHOT_BEGIN\n" + json + "\nXFE_TERMINAL_SNAPSHOT_END\n");
}
private static void ReportWindowState(DesktopSession desktop)
{
string report = "XFE_DESKTOP_FLAGS|" + (desktop.IsStartMenuOpen ? 1 : 0) + "|" + (desktop.IsWindowSwitching ? 1 : 0) +
"|Active|" + (desktop.ActiveWindow?.Id ?? 0) + "\n" +
"XFE_DESKTOP_APPEARANCE|" + desktop.Theme.Mode + "|" + desktop.Theme.Accent.ToString("X6") +
"|Persistent|" + (desktop.IsAppearancePersistent ? 1 : 0) + "\n";
foreach (var window in desktop.Windows)
{
var b = window.Bounds;
report += "XFE_WINDOW_STATE|" + window.Id + "|" + window.Application + "|" + b.X + "|" + b.Y + "|" + b.Width + "|" + b.Height +
"|" + (window.IsMinimized ? 1 : 0) + "|" + (window.IsMaximized ? 1 : 0) + "|" + (window.IsSnapped ? 1 : 0) + "\n";
if (window.IsMarkdown)
report += "XFE_WINDOW_DOCUMENT|" + window.Id + "|" + window.Location + "|" + window.MarkdownView + "|" + (window.IsDirty ? 1 : 0) +
"|" + (window.IsEditorPreparing ? 1 : 0) + "|" + (window.IsPreviewPreparing ? 1 : 0) + "|" +
window.Status.Replace('|', '/').Replace('\n', ' ').Replace('\r', ' ') + "\n";
}
if (report == lastWindowState) return;
lastWindowState = report;
NativePlatform.Write("XFE_DESKTOP_ACTIVE|" + (desktop.ActiveWindow?.Application.ToString() ?? "Desktop") + "\n" + report + "XFE_DESKTOP_STATE_END\n");
}
private static string lastBrowserState = "", lastBrowserInput = "", lastMonacoProof = "";
private static long lastBrowserReport;
private static void ReportBrowserState(DesktopWindow window, long now)
{
var visible = window.IsMarkdown && window.MarkdownView != MarkdownViewMode.Edit ? window.PreviewSession : window.BrowserSession;
var editor = window.BrowserSession;
var diagnostics = (editor as IBackgroundEditorSession)?.Diagnostics;
string inputTrace = diagnostics?.LastInputTrace ?? (visible as IBackgroundEditorSession)?.Diagnostics.LastInputTrace ??
(visible as BrowserService)?.LastInputTrace ?? "";
if (inputTrace != lastBrowserInput)
{
lastBrowserInput = inputTrace;
NativePlatform.Write("XFE_BROWSER_INPUT|" + lastBrowserInput + "\n");
}
if (now - lastBrowserReport < 200) return;
lastBrowserReport = now;
string content = window.IsMarkdown && window.MarkdownView != MarkdownViewMode.Edit
? visible?.CurrentPage.Text ?? window.Content : editor?.ReadEditorText() ?? window.Content;
string body = content.Length <= 4096 ? content : content[..4096];
string state = window.Id + "|" + window.Location + "\n" + body;
if (state != lastBrowserState)
{
lastBrowserState = state;
NativePlatform.Write("XFE_BROWSER_STATE_BEGIN\n" + state + "\nXFE_BROWSER_STATE_END\n");
}
var modelPage = editor ?? visible;
if (modelPage is not null && Uri.TryCreate(modelPage.CurrentPage.Address, UriKind.Absolute, out var uri) && BrowserService.IsMonacoAddress(uri))
{
string proof = diagnostics?.MonacoProof ?? (modelPage as IBackgroundEditorSession)?.Diagnostics.MonacoProof ??
(modelPage as BrowserService)?.ReadMonacoProof() ?? "{}";
if (proof != "{}" && proof != lastMonacoProof)
{
lastMonacoProof = proof;
NativePlatform.Write("XFE_MONACO_CSHARP_PROOF_BEGIN\n" + proof + "\nXFE_MONACO_CSHARP_PROOF_END\n");
}
NativePlatform.Write("XFE_MONACO_VALUE_BEGIN\n" + (modelPage.ReadEditorText() ?? "Editor unavailable") + "\nXFE_MONACO_VALUE_END\n");
if (modelPage is IBackgroundEditorSession background)
NativePlatform.Write("XFE_MONACO_PRESENTATION|Window|" + window.Id + "|RasterPaints|" + background.RasterPaintCount +
"|CachedPaints|" + background.CachedPaintCount + "|WorkerThread|" + background.Diagnostics.WorkerThreadId + "\n");
}
}
}
using XFESystem.Browser;
using XFESystem.Console;
using XFESystem.ConsoleDemo;
using XFESystem.Core;
using XFESystem.Desktop;
using XFESystem.ManagedRuntime;
using XFESystem.Platform;
using XFESystem.NativeRuntime.Application.Web;
namespace XFESystem.NativeRuntime.Application;
/// <summary>Ordinary Microsoft NativeAOT Main, called after the independently installed PAL/bootstrapper.</summary>
internal static class Program
{
private const string ManagedDemoPath = "X:\\Programs\\ManagedHello\\ManagedHello.dll";
private static int Main()
{
NativePlatform.Write("XFE_INDEPENDENT_APPLICATION_ENTER\nXFE_SYSTEM_EDITION|Desktop\n");
try
{
global::System.Console.SetOut(new NativeDiagnosticWriter());
global::System.Console.SetError(new NativeDiagnosticWriter());
NativePlatform.RequireClock();
RuntimeSelfCheck.Run();
var surface = NativePlatform.ReadFramebuffer();
int scalePercent = surface.Width >= 3000 || surface.Height >= 1800 ? 200 : 100;
var canvas = new CpuFramebufferCanvas(new BootFramebufferPresenter(new MemoryFramebufferPresenter(surface)), scalePercent: scalePercent, timestamp: NativePlatform.Nanoseconds);
var workspace = CreateWorkspace();
workspace.CreateDirectory(SystemPaths.Combine(SystemPaths.System, "Diagnostics"));
var gpuReport = NativeGpuDiagnostics.ReadReport(out bool hasRtx5090);
var gpuReportPath = SystemPaths.Combine(SystemPaths.System, "Diagnostics\\Gpu.txt");
var usbReportPath = SystemPaths.Combine(SystemPaths.System, "Diagnostics\\Usb.txt");
workspace.WriteText(usbReportPath, NativeUsbDiagnostics.ReadReport());
workspace.WriteText(gpuReportPath, gpuReport);
var browser = new BrowserService(new NativeWebTransport(), limits: new BrowserLimits
{
MaximumExternalResourceCharacters = 2_500_000,
// First-use cryptographic setup also counts toward the bounded
// request, including under QEMU TCG. It runs on the navigation worker.
NetworkTimeout = TimeSpan.FromSeconds(60)
}) { Trace = NativePlatform.Write };
// RuntimeSelfCheck has exercised real GC/EH/TLS and managed threads.
// Each page keeps one thread owner; navigation cannot block editor work.
using var editorWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Editor worker failed: " + error.Message));
using var navigationWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Navigation worker failed: " + error.Message));
using var programWorker = new DesktopBackgroundWorkScheduler(error => NativePlatform.Halt("Program worker failed: " + error.Message));
var uiCompletions = new Queue<Action>();
object completionGate = new();
void PostCompletion(Action completed) { lock (completionGate) uiCompletions.Enqueue(completed); }
void DrainCompletions()
{
for (int count = 0; count < 64; count++)
{
Action? completed;
lock (completionGate) completed = uiCompletions.Count > 0 ? uiCompletions.Dequeue() : null;
if (completed is null) return;
completed();
}
}
var editorPreparation = new BrowserEditorPreparationService(browser, editorWorker, canvas,
NativePlatform.Write, () => Environment.CurrentManagedThreadId, NativePlatform.Milliseconds, navigationWorker);
var terminal = new TerminalBuffer(100, 30);
var writer = new TerminalTextWriter(terminal);
DesktopSession? desktop = null;
void RunConsoleDemo()
{
terminal.Reset(); ConsoleDemoScenario.Run(writer); ConsoleDemoScenario.RunXfeConsoleApi(writer);
terminal.Complete();
var snapshot = writer.Snapshot();
string text = string.Concat(snapshot.Cells.Select(cell => cell.Text));
if (!text.Contains(ConsoleDemoScenario.SuccessMarker, StringComparison.Ordinal) ||
!text.Contains("XFEConsole API: Real NuGet 2.6.0", StringComparison.Ordinal))
throw new InvalidOperationException("The real console demo did not produce its terminal markers.");
desktop!.SetTerminalSnapshot(snapshot);
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_DEMO_OK ANSI XFEConsole2.6.0 terminal_cells\n");
}
void RunManagedApplication(string path)
{
var programTerminal = new TerminalBuffer(100, 30);
var programOutput = new TerminalTextWriter(programTerminal);
if (!programWorker.TryQueue(() =>
{
ExecuteManagedApplication(path, programOutput);
programTerminal.Complete();
var snapshot = programOutput.Snapshot();
PostCompletion(() =>
{
desktop!.SetTerminalSnapshot(snapshot);
pendingConsoleWindowId = desktop.ActiveWindow?.Id ?? 0; pendingConsolePath = path;
});
})) desktop!.WriteTerminalOutput("Program queue is busy.\n");
}
void ExecuteManagedApplication(string path, TerminalTextWriter output)
{
try
{
var result = new ManagedApplicationRunner().Execute(workspace.ReadBytes(path), new TerminalManagedConsole(output));
output.WriteLine("Managed ConsoleIL exit: " + result.ExitCode);
var sampleText = string.Concat(output.Snapshot().Cells.Select(cell => cell.Text));
if (result.ExitCode == 0 && sampleText.Contains("XFE_MANAGED_APP_OK", StringComparison.Ordinal) &&
sampleText.Contains("XFE_MANAGED_XFECONSOLE_OK", StringComparison.Ordinal))
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_IL_OK actual_embedded_net10_PE bounded_interpreter\n");
}
catch (Exception error) when (error is not OutOfMemoryException and not StackOverflowException)
{ output.WriteLine("Managed program failed: " + error.Message); }
}
desktop = new DesktopSession(canvas, workspace, browser, RunConsoleDemo, RunManagedApplication,
NativePlatform.Milliseconds, editorPreparation: editorPreparation,
threadIdentity: () => Environment.CurrentManagedThreadId)
{
Trace = NativePlatform.Write,
TerminalProgramRequested = request =>
{
if (!programWorker.TryQueue(() =>
{
ExecuteManagedApplication(request.Path, request.Output);
PostCompletion(() =>
{
desktop!.RefreshTerminalOutput(request.WindowId);
pendingConsoleWindowId = request.WindowId; pendingConsolePath = request.Path;
});
}))
{
request.Output.WriteLine("Program queue is busy.");
PostCompletion(() => desktop!.RefreshTerminalOutput(request.WindowId));
}
}
};
var input = new Ps2InputSource(new NativePs2ReportBackend(), canvas.NativeWidth, canvas.NativeHeight, canvas.ScalePercent,
() => new(desktop.HasBrowserContentFocus, desktop.ActiveWindow?.Application));
desktop.Open(DesktopApplication.Files);
// Entity tests must be readable even before native USB HID works.
// This is a plain RAM text file; no web/Monaco initialization is needed.
if (hasRtx5090) desktop.OpenFile(gpuReportPath);
desktop.Pointer(input.PointerX, input.PointerY, false, timestampMs: NativePlatform.Milliseconds());
desktop.Render();
if (!desktop.LastFrameCompleted || canvas.FramesPresented == 0)
throw new InvalidOperationException("The desktop did not finish an actual raw framebuffer presentation.");
NativePlatform.Write("XFE_INDEPENDENT_DESKTOP_FIRST_FRAME|Width|" + canvas.NativeWidth + "|Height|" + canvas.NativeHeight +
"|ScalePercent|" + canvas.ScalePercent + "|Presented|" + canvas.FramesPresented + "\n");
NativePlatform.Write("XFE_INDEPENDENT_INPUT|Connected|" + (input.IsAvailable ? 1 : 0) + "|Keyboard|" + (input.Capabilities & 1) +
"|Mouse|" + ((input.Capabilities >> 1) & 1) + "|Wheel|" + ((input.Capabilities >> 2) & 1) + "|Backend|PS2+xHCI|UsbHid|" + NativeUsbDiagnostics.KeyboardMouse + "\n");
NativePlatform.Write("XFE_INDEPENDENT_CAPABILITIES|RAMOnly|"+(workspace.IsPersistent?0:1)+"|NativeNetwork|1|NetworkBackend|E1000_StaticQemuNat|Gpu|0|Cuda|0|BackgroundEditor|1|EditorThread|" +
editorWorker.WorkerThreadId + "|NavigationThread|" + navigationWorker.WorkerThreadId + "|UiThread|" + Environment.CurrentManagedThreadId + "\n");
ReportWindowState(desktop);
long nextUsb = NativePlatform.Milliseconds() + 2000;
Pump(desktop, input, () => {
DrainCompletions(); long now = NativePlatform.Milliseconds();
if (now >= nextUsb) { nextUsb = now + 2000; workspace.WriteText(usbReportPath, NativeUsbDiagnostics.ReadReport()); }
});
return 0;
}
catch (Exception error)
{
NativePlatform.Write("XFE_INDEPENDENT_APPLICATION_FAILED|" + error.Message + "\n");
NativePlatform.Halt("Managed desktop failed: " + error.Message);
return 1;
}
}
private static IWorkspaceBinaryStorage CreateWorkspace()
{
var workspace = NativeWorkspace.Open();
string welcome=SystemPaths.Combine(SystemPaths.Desktop,"Welcome.md");
if(!workspace.Exists(welcome))workspace.WriteText(welcome,workspace.IsPersistent?"# XFESystem\n\nFiles and settings are saved to the boot USB workspace.\n":"# XFESystem\n\nRAM fallback: no usable boot USB storage. Files disappear after shutdown.\n");
string helloJs=SystemPaths.Combine(SystemPaths.Documents,"Hello.js");
if(!workspace.Exists(helloJs))workspace.WriteText(helloJs,"const greeting = 'XFESystem';\nconsole.log(`Hello from ${greeting}!`);\n");
string helloCs=SystemPaths.Combine(SystemPaths.Documents,"Hello.cs");
if(!workspace.Exists(helloCs))workspace.WriteText(helloCs,"using System;\n\nConsole.ForegroundColor = ConsoleColor.Cyan;\nConsole.WriteLine(\"Hello XFESystem!\");\nConsole.ResetColor();\n");
string readme=SystemPaths.Combine(SystemPaths.Documents,"Readme.md");
if(!workspace.Exists(readme))workspace.WriteText(readme, """
# XFESystem 独立内核
启动 U 盘可用时,文件和设置保存到物理 U 盘;没有可用启动 U 盘时明确回退到 RAM 会话。
- 原有 Desktop、Browser、Documents 和 Terminal 接口继续使用。
- PS/2 与 xHCI HID 输入已接入,实体兼容仍需验收。
- X:\UsbFiles 对应 U 盘 UserFiles 文件夹,可以运行符合 ConsoleIL 范围的 .dll。
- QEMU e1000 网络已接入;GPU/CUDA 尚未实现。
""");
string parity=SystemPaths.Combine(SystemPaths.Documents,"WebsiteParity.md");
if(!workspace.Exists(parity))workspace.WriteText(parity,
XFESystem.Documents.WebsiteAssets.ReadText("Fixtures/WebsiteParity.md"));
workspace.CreateDirectory("X:\\Programs\\ManagedHello");
using var sample = typeof(Program).Assembly.GetManifestResourceStream("ApplicationSamples/ManagedHello.dll")
?? throw new InvalidOperationException("The actual ConsoleIL sample assembly is missing.");
if (sample.Length > ManagedRuntimeCapabilities.MaxImageBytes) throw new InvalidDataException("Managed sample exceeds the ConsoleIL image budget.");
byte[] image = new byte[checked((int)sample.Length)]; sample.ReadExactly(image);
if(!workspace.Exists(ManagedDemoPath))workspace.WriteBytes(ManagedDemoPath, image);
string samplePath=SystemPaths.Combine(SystemPaths.Documents,"ManagedHello.dll");
if(!workspace.Exists(samplePath))workspace.WriteBytes(samplePath,image);
return workspace;
}
// Input remains an explicit optional adapter. No fabricated reports or host window input enter this loop.
private static void Pump(DesktopSession desktop, INativeInputSource? input, Action drainCompletions)
{
long previous = NativePlatform.Milliseconds(), nextTick = previous;
for (;;)
{
long now = NativePlatform.Milliseconds();
if (now < previous) throw new InvalidOperationException("The native monotonic clock moved backward.");
previous = now;
drainCompletions();
if (input is { IsAvailable: true })
for (int reports = 0; reports < 256 && input.TryRead(out var report); reports++) NativeInput.Dispatch(desktop, report, now);
if (now >= nextTick)
{
desktop.AdvanceFeedback(now);
if (desktop.NeedsRender)
{
desktop.Render();
if (desktop.LastFrameCompleted)
{
if (pendingConsolePath is { } presentedPath && desktop.ActiveWindow is { Application: DesktopApplication.Terminal } terminalWindow &&
terminalWindow.Id == pendingConsoleWindowId)
{
NativePlatform.Write("XFE_INDEPENDENT_CONSOLE_PRESENTED|Path|" + presentedPath + "|Window|" + terminalWindow.Id + "\n");
pendingConsolePath = null;
}
ReportWindowState(desktop);
ReportTerminalState(desktop);
if (desktop.ActiveWindow is { } active && (active.BrowserSession is not null || active.PreviewSession is not null)) ReportBrowserState(active, now);
}
}
nextTick = now + 16;
}
Thread.Sleep(1);
}
}
private static string lastWindowState = "";
private static string? pendingConsolePath;
private static int pendingConsoleWindowId;
private static TerminalSnapshot? lastTerminalSnapshot;
private static int lastTerminalWindowId;
private static void ReportTerminalState(DesktopSession desktop)
{
if (desktop.ActiveWindow is not { Application: DesktopApplication.Terminal, Terminal: { } snapshot, Shell: { } shell } window ||
window.Id == lastTerminalWindowId && ReferenceEquals(snapshot, lastTerminalSnapshot)) return;
lastTerminalWindowId = window.Id; lastTerminalSnapshot = snapshot;
var text = new System.Text.StringBuilder();
for (int row = Math.Max(0, snapshot.CursorRow - 31); row <= Math.Min(snapshot.CursorRow, snapshot.Rows - 1); row++)
{
for (int col = 0; col < snapshot.Columns; col++)
{
var cell = snapshot.GetCell(col, row);
if (!cell.IsContinuation) text.Append(cell.Text);
}
text.Append('\n');
}
string json = "{\"WindowId\":" + window.Id + ",\"Text\":" + NativeWebTransport.Quote(text.ToString()) +
",\"Input\":" + NativeWebTransport.Quote(shell.Input) + ",\"Prompt\":" + NativeWebTransport.Quote(shell.Prompt) +
",\"Busy\":" + (window.TerminalProgramRunning ? "true" : "false") + ",\"Version\":" + NativeWebTransport.Quote(shell.Version) +
",\"LastCommand\":" + NativeWebTransport.Quote(shell.History.LastOrDefault()) + "}";
NativePlatform.Write("XFE_TERMINAL_SNAPSHOT_BEGIN\n" + json + "\nXFE_TERMINAL_SNAPSHOT_END\n");
}
private static void ReportWindowState(DesktopSession desktop)
{
string report = "XFE_DESKTOP_FLAGS|" + (desktop.IsStartMenuOpen ? 1 : 0) + "|" + (desktop.IsWindowSwitching ? 1 : 0) +
"|Active|" + (desktop.ActiveWindow?.Id ?? 0) + "\n" +
"XFE_DESKTOP_APPEARANCE|" + desktop.Theme.Mode + "|" + desktop.Theme.Accent.ToString("X6") +
"|Persistent|" + (desktop.IsAppearancePersistent ? 1 : 0) + "\n";
foreach (var window in desktop.Windows)
{
var b = window.Bounds;
report += "XFE_WINDOW_STATE|" + window.Id + "|" + window.Application + "|" + b.X + "|" + b.Y + "|" + b.Width + "|" + b.Height +
"|" + (window.IsMinimized ? 1 : 0) + "|" + (window.IsMaximized ? 1 : 0) + "|" + (window.IsSnapped ? 1 : 0) + "\n";
if (window.IsMarkdown)
report += "XFE_WINDOW_DOCUMENT|" + window.Id + "|" + window.Location + "|" + window.MarkdownView + "|" + (window.IsDirty ? 1 : 0) +
"|" + (window.IsEditorPreparing ? 1 : 0) + "|" + (window.IsPreviewPreparing ? 1 : 0) + "|" +
window.Status.Replace('|', '/').Replace('\n', ' ').Replace('\r', ' ') + "\n";
}
if (report == lastWindowState) return;
lastWindowState = report;
NativePlatform.Write("XFE_DESKTOP_ACTIVE|" + (desktop.ActiveWindow?.Application.ToString() ?? "Desktop") + "\n" + report + "XFE_DESKTOP_STATE_END\n");
}
private static string lastBrowserState = "", lastBrowserInput = "", lastMonacoProof = "";
private static long lastBrowserReport;
private static void ReportBrowserState(DesktopWindow window, long now)
{
var visible = window.IsMarkdown && window.MarkdownView != MarkdownViewMode.Edit ? window.PreviewSession : window.BrowserSession;
var editor = window.BrowserSession;
var diagnostics = (editor as IBackgroundEditorSession)?.Diagnostics;
string inputTrace = diagnostics?.LastInputTrace ?? (visible as IBackgroundEditorSession)?.Diagnostics.LastInputTrace ??
(visible as BrowserService)?.LastInputTrace ?? "";
if (inputTrace != lastBrowserInput)
{
lastBrowserInput = inputTrace;
NativePlatform.Write("XFE_BROWSER_INPUT|" + lastBrowserInput + "\n");
}
if (now - lastBrowserReport < 200) return;
lastBrowserReport = now;
string content = window.IsMarkdown && window.MarkdownView != MarkdownViewMode.Edit
? visible?.CurrentPage.Text ?? window.Content : editor?.ReadEditorText() ?? window.Content;
string body = content.Length <= 4096 ? content : content[..4096];
string state = window.Id + "|" + window.Location + "\n" + body;
if (state != lastBrowserState)
{
lastBrowserState = state;
NativePlatform.Write("XFE_BROWSER_STATE_BEGIN\n" + state + "\nXFE_BROWSER_STATE_END\n");
}
var modelPage = editor ?? visible;
if (modelPage is not null && Uri.TryCreate(modelPage.CurrentPage.Address, UriKind.Absolute, out var uri) && BrowserService.IsMonacoAddress(uri))
{
string proof = diagnostics?.MonacoProof ?? (modelPage as IBackgroundEditorSession)?.Diagnostics.MonacoProof ??
(modelPage as BrowserService)?.ReadMonacoProof() ?? "{}";
if (proof != "{}" && proof != lastMonacoProof)
{
lastMonacoProof = proof;
NativePlatform.Write("XFE_MONACO_CSHARP_PROOF_BEGIN\n" + proof + "\nXFE_MONACO_CSHARP_PROOF_END\n");
}
NativePlatform.Write("XFE_MONACO_VALUE_BEGIN\n" + (modelPage.ReadEditorText() ?? "Editor unavailable") + "\nXFE_MONACO_VALUE_END\n");
if (modelPage is IBackgroundEditorSession background)
NativePlatform.Write("XFE_MONACO_PRESENTATION|Window|" + window.Id + "|RasterPaints|" + background.RasterPaintCount +
"|CachedPaints|" + background.CachedPaintCount + "|WorkerThread|" + background.Diagnostics.WorkerThreadId + "\n");
}
}
}