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; /// Ordinary Microsoft NativeAOT Main, called after the independently installed PAL/bootstrapper. internal static class Program { private const string ManagedDemoPath = "X:\\Programs\\ManagedHello\\ManagedHello.dll"; private static readonly GuiDiagnosticQueue guiDiagnostics = new(8); private static void DrainGuiDiagnostics() { for (;;) if (guiDiagnostics.TryRead(out string record)) NativePlatform.Write(record); else Thread.Sleep(4); } 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 scanouts = NativePlatform.ReadDisplays(); // Match this machine's measured Windows 4K UI scale. Native pixel // dimensions remain unchanged; layout coordinates are separate. int scalePercent = scanouts[0].Display.NativeWidth >= 3000 || scanouts[0].Display.NativeHeight >= 1800 ? 150 : 100; var displays = new FramebufferDisplayManager(scanouts, scalePercent); var canvas = new CpuFramebufferCanvas(new BootFramebufferPresenter(displays.Presenter), scalePercent: scalePercent, timestamp: NativePlatform.Nanoseconds); displays.AttachCanvas(canvas); 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); void UpdateDisplayReport() => workspace.WriteText(SystemPaths.Combine(SystemPaths.System, "Diagnostics\\Display.txt"), "XFESystem actual framebuffer geometry\n" + string.Concat(scanouts.Select(output => "Output " + output.Display.Id + ": " + output.Display.NativeWidth + " x " + output.Display.NativeHeight + " native pixels\n")) + "Virtual canvas pixels: " + canvas.NativeWidth + " x " + canvas.NativeHeight + "\nLogical desktop: " + canvas.Width + " x " + canvas.Height + "\nUI scale: " + canvas.ScalePercent + "%\nCPU frame submission target: 240 Hz\nPhysical refresh: not measured\nScanout/VSync driver: unavailable" + "\nNative executing CPUs: " + NativePlatform.NativeCpuCount() + " (AP kernel jobs)\n" + "Managed scheduler CPUs: 1 (single BSP; managed SMP unavailable)\nKernel timer target: 1 ms\n" + "F12 starts/stops an opt-in input-to-framebuffer timing capture; it does not measure panel scanout.\n"); 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.PostDiagnostic }; // 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(); 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.PostDiagnostic, () => 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.PostDiagnostic("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.PostDiagnostic("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, displays: displays) { Trace = NativePlatform.PostDiagnostic, 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), displays.Layout.ConstrainPointer); displays.Changed += () => { input.ConfigureViewport(canvas.NativeWidth, canvas.NativeHeight, canvas.ScalePercent, displays.Layout.ConstrainPointer); UpdateDisplayReport(); }; UpdateDisplayReport(); 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_NATIVE_FRAMEBUFFER_JOBS|OnlineCpus|" + NativePlatform.NativeCpuCount() + "|MaximumCopyCpus|" + NativePlatform.NativeCopyCpuLimit() + "|CompletedParallelCopies|" + NativePlatform.NativeCopyCount() + "|ManagedSchedulerCpus|1|GpuRendering|0|Physical240Hz|0\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"); new Thread(DrainGuiDiagnostics) { IsBackground = true, Name = "GUI diagnostics" }.Start(); NativePlatform.DeferDiagnostics(guiDiagnostics.PublishTrace); ReportWindowState(desktop); long nextUsb = NativePlatform.Milliseconds() + 2000; Pump(desktop, input, canvas, () => { 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, CpuFramebufferCanvas canvas, Action drainCompletions) { long previous = NativePlatform.Milliseconds(); // Submission pacing is separate from physical scanout. The independent // kernel has no native display-mode/vblank driver yet. var pacer = new FramePacer(1_000_000_000, 240_000); var timingProbe = new XFESystem.Kernel.NativePointerFrameProbe(16_384); XFESystem.Kernel.NativePointerTimingCounters InputCounters() { if (input is Ps2InputSource native) { var timing = native.InputTiming; return new((long)timing.Observed, (long)timing.Consumed, (long)timing.Lost); } return new(0, 0, 0); } NativePlatform.Write("XFE_DESKTOP_FRAME_POLICY|TargetMilliHz|240000|ClockFrequency|1000000000|HardwareRefreshMeasured|0\n"); 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++) { long dispatchedAt = NativePlatform.Nanoseconds(); if (report.Kind == NativeInputKind.TimingProbe) { if (timingProbe.IsCapturing) timingProbe.Stop(dispatchedAt, canvas.FramesPresented, InputCounters(), NativePlatform.Write); else { timingProbe.Start(1_000_000_000, dispatchedAt, canvas.FramesPresented, InputCounters()); NativePlatform.Write("XFE_POINTER_TIMING_STARTED\n"); } continue; } if (report.Kind == NativeInputKind.Pointer && report.ReportSequence > 0) timingProbe.ObserveConsumed(report.ReportSequence, report.ReportNanoseconds, dispatchedAt, report.X, report.Y); NativeInput.Dispatch(desktop, report, now); } desktop.AdvanceFeedback(now); long renderBegin = NativePlatform.Nanoseconds(); if (pacer.ShouldRender(renderBegin, desktop.NeedsRender)) { if (desktop.NeedsRender) { desktop.Render(); if (desktop.LastFrameCompleted) { pacer.Rendered(renderBegin, NativePlatform.Nanoseconds()); timingProbe.CapturePresent(canvas.FramesPresented, renderBegin, NativePlatform.Nanoseconds()); if (pendingConsolePath is { } presentedPath && desktop.ActiveWindow is { Application: DesktopApplication.Terminal } terminalWindow && terminalWindow.Id == pendingConsoleWindowId) { guiDiagnostics.Publish(7, "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); } } } long remaining = pacer.NextDeadlineTicks - NativePlatform.Nanoseconds(); Thread.Sleep(desktop.NeedsRender && remaining < 1_000_000 ? 0 : 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()) + "}"; guiDiagnostics.Publish(1, "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"; report += desktop.DisplayStateReport; 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; guiDiagnostics.Publish(0, "XFE_DESKTOP_ACTIVE|" + (desktop.ActiveWindow?.Application.ToString() ?? "Desktop") + "\n" + report + "XFE_DESKTOP_STATE_END\n"); } private static string lastBrowserState = "", lastBrowserInput = "", lastMonacoProof = ""; private static string? lastMonacoValue, lastMonacoPresentation; private static int lastMonacoWindowId; 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; guiDiagnostics.Publish(3, "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; guiDiagnostics.Publish(2, "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; guiDiagnostics.Publish(4, "XFE_MONACO_CSHARP_PROOF_BEGIN\n" + proof + "\nXFE_MONACO_CSHARP_PROOF_END\n"); } // Preview text is different from the editor model in a split view. // Otherwise reuse the model text already read above. Unchanged // text must not cause a second JS read/full serial dump every 200ms. string value = window.IsMarkdown && window.MarkdownView != MarkdownViewMode.Edit ? modelPage.ReadEditorText() ?? "Editor unavailable" : content; if (window.Id != lastMonacoWindowId || value != lastMonacoValue) { lastMonacoWindowId = window.Id; lastMonacoValue = value; guiDiagnostics.Publish(5, "XFE_MONACO_VALUE_BEGIN\n" + value + "\nXFE_MONACO_VALUE_END\n"); } if (modelPage is IBackgroundEditorSession background) { string presentation = "XFE_MONACO_PRESENTATION|Window|" + window.Id + "|RasterPaints|" + background.RasterPaintCount + "|CachedPaints|" + background.CachedPaintCount + "|WorkerThread|" + background.Diagnostics.WorkerThreadId + "\n"; if (presentation != lastMonacoPresentation) { lastMonacoPresentation = presentation; guiDiagnostics.Publish(6, presentation); } } } } }