Code cleanup

This commit is contained in:
Stone_Red
2026-06-08 21:30:40 +02:00
parent 124b5368b1
commit 145055b77e
25 changed files with 232 additions and 192 deletions
+9 -9
View File
@@ -1,6 +1,3 @@
using System;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Engines;
@@ -8,6 +5,9 @@ using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using System.Security.Cryptography;
using System.Text;
public static class BcAesCrypto public static class BcAesCrypto
{ {
private const int KeySize = 32; // 256-bit AES private const int KeySize = 32; // 256-bit AES
@@ -21,7 +21,7 @@ public static class BcAesCrypto
// ----------------------------- // -----------------------------
private static byte[] DeriveKey(string password, byte[] salt) private static byte[] DeriveKey(string password, byte[] salt)
{ {
var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest()); Pkcs5S2ParametersGenerator generator = new(new Sha256Digest());
generator.Init( generator.Init(
PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()), PbeParametersGenerator.Pkcs5PasswordToBytes(password.ToCharArray()),
@@ -29,7 +29,7 @@ public static class BcAesCrypto
Iterations Iterations
); );
var keyParam = (KeyParameter)generator.GenerateDerivedMacParameters(KeySize * 8); KeyParameter keyParam = (KeyParameter)generator.GenerateDerivedMacParameters(KeySize * 8);
return keyParam.GetKey(); return keyParam.GetKey();
} }
@@ -46,7 +46,7 @@ public static class BcAesCrypto
byte[] nonce = new byte[NonceSize]; byte[] nonce = new byte[NonceSize];
RandomNumberGenerator.Fill(nonce); RandomNumberGenerator.Fill(nonce);
var cipher = new GcmBlockCipher(new AesEngine()); GcmBlockCipher cipher = new(new AesEngine());
cipher.Init(true, new AeadParameters( cipher.Init(true, new AeadParameters(
new KeyParameter(key), new KeyParameter(key),
@@ -58,7 +58,7 @@ public static class BcAesCrypto
byte[] output = new byte[cipher.GetOutputSize(input.Length)]; byte[] output = new byte[cipher.GetOutputSize(input.Length)];
int len = cipher.ProcessBytes(input, 0, input.Length, output, 0); int len = cipher.ProcessBytes(input, 0, input.Length, output, 0);
cipher.DoFinal(output, len); _ = cipher.DoFinal(output, len);
// Combine: salt + nonce + ciphertext // Combine: salt + nonce + ciphertext
byte[] result = new byte[salt.Length + nonce.Length + output.Length]; byte[] result = new byte[salt.Length + nonce.Length + output.Length];
@@ -90,7 +90,7 @@ public static class BcAesCrypto
byte[] key = DeriveKey(password, salt); byte[] key = DeriveKey(password, salt);
var cipher = new GcmBlockCipher(new AesEngine()); GcmBlockCipher cipher = new(new AesEngine());
cipher.Init(false, new AeadParameters( cipher.Init(false, new AeadParameters(
new KeyParameter(key), new KeyParameter(key),
@@ -101,7 +101,7 @@ public static class BcAesCrypto
byte[] plain = new byte[cipher.GetOutputSize(cipherBytes.Length)]; byte[] plain = new byte[cipher.GetOutputSize(cipherBytes.Length)];
int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plain, 0); int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plain, 0);
cipher.DoFinal(plain, len); _ = cipher.DoFinal(plain, len);
return Encoding.UTF8.GetString(plain); return Encoding.UTF8.GetString(plain);
} }
+16 -16
View File
@@ -1,17 +1,15 @@
global using Sys = Cosmos.Kernel.System; global using Sys = Cosmos.Kernel.System;
using System.Diagnostics;
using Cosmos.Kernel.Core;
using RemSox.Processing.IPC;
using RemSox.UI.CLI;
using RemSox.UI.CLI.Commands;
using RemSox.UI.GUI.UIEelements.Shapes;
using RemSox.UI.GUI.Windows;
using System.Drawing; using System.Drawing;
using System.Runtime; using System.Runtime;
using System.Runtime.InteropServices;
using Cosmos.Build.API.Attributes;
using Cosmos.Kernel.Core;
using Cosmos.Kernel.System.Graphics;
using RemSox.Processing;
using RemSox.Processing.IPC;
using RemSox.UI.GUI.CLI;
using RemSox.UI.GUI.CLI.Commands;
using RemSox.UI.GUI.Rendering;
using RemSox.UI.GUI.Windows;
namespace RemSox; namespace RemSox;
@@ -25,8 +23,8 @@ public class Kernel : Sys.Kernel
Console.WriteLine("Cosmos booted successfully!"); Console.WriteLine("Cosmos booted successfully!");
Console.WriteLine("Type a command to get it executed."); Console.WriteLine("Type a command to get it executed.");
CommandManager.RegisterCommands(new ICommand[] CommandManager.RegisterCommands(
{ [
new HelpCommand(), new HelpCommand(),
new ClearCommand(), new ClearCommand(),
new HaltCommand(), new HaltCommand(),
@@ -34,7 +32,7 @@ public class Kernel : Sys.Kernel
new ListProcessesCommand(), new ListProcessesCommand(),
new StopProcessCommand(), new StopProcessCommand(),
new StartGuiCommand() new StartGuiCommand()
}); ]);
Sys.Mouse.MouseManager.Initialize(); Sys.Mouse.MouseManager.Initialize();
Sys.Keyboard.KeyboardManager.Initialize(); Sys.Keyboard.KeyboardManager.Initialize();
@@ -82,7 +80,7 @@ public class TestProcess() : Processing.Process("Test Process")
Window window = WindowManager.CreateWindow(this, "Test Window", Point.Empty, new Size(200, 150)); Window window = WindowManager.CreateWindow(this, "Test Window", Point.Empty, new Size(200, 150));
window.AutoFlush = true; window.AutoFlush = true;
var circle = window.CreateUIElement<UI.GUI.UIEelements.Shapes.Circle>(rect => Circle circle = window.CreateUIElement<UI.GUI.UIEelements.Shapes.Circle>(rect =>
{ {
rect.Position = new Point(10, 10); rect.Position = new Point(10, 10);
rect.Radius = 50; rect.Radius = 50;
@@ -119,9 +117,11 @@ public static unsafe partial class StartupCodeHelpers
public static double fmod(double x, double y) public static double fmod(double x, double y)
{ {
if (Math.Abs(y) < double.Epsilon) if (Math.Abs(y) < double.Epsilon)
{
return double.NaN; return double.NaN;
}
double q = Math.Truncate(x / y); double q = Math.Truncate(x / y);
return x - q * y; return x - (q * y);
} }
} }
@@ -1,25 +1,24 @@
using System;
using Cosmos.Build.API.Attributes; using Cosmos.Build.API.Attributes;
namespace MyKernel.Plugs; namespace RemSox.Plugs;
[Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")] [Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")]
public static unsafe class RandomNumberGeneratorImplementationImpl public static unsafe class RandomNumberGeneratorImplementationImpl
{ {
// Cryptographic stream generator based on ChaCha20. // Cryptographic stream generator based on ChaCha20.
// Initial entropy is limited at boot; depends on hardware events. // Initial entropy is limited at boot; depends on hardware events.
private static uint[] key = new uint[8]; private static readonly uint[] key = new uint[8];
private static uint[] counter = new uint[4]; private static readonly uint[] counter = new uint[4];
private static uint[] state = new uint[16]; private static readonly uint[] state = new uint[16];
private static ulong e0, e1, e2, e3; private static ulong e0, e1, e2, e3;
private static int entropyCounter; private static int entropyCounter;
private static bool initialized = false; private static bool initialized = false;
private static readonly uint[] constants = private static readonly uint[] constants =
{ [
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574 0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
}; ];
private static uint RotL(uint x, int n) private static uint RotL(uint x, int n)
{ {
@@ -38,10 +37,25 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
{ {
uint[] x = new uint[16]; uint[] x = new uint[16];
for (int i = 0; i < 4; i++) x[i] = constants[i]; for (int i = 0; i < 4; i++)
for (int i = 0; i < 8; i++) x[4 + i] = key[i]; {
for (int i = 0; i < 4; i++) x[12 + i] = counter[i]; x[i] = constants[i];
for (int i = 0; i < 16; i++) state[i] = x[i]; }
for (int i = 0; i < 8; i++)
{
x[4 + i] = key[i];
}
for (int i = 0; i < 4; i++)
{
x[12 + i] = counter[i];
}
for (int i = 0; i < 16; i++)
{
state[i] = x[i];
}
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
@@ -57,7 +71,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
} }
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{
output[i] = x[i] + state[i]; output[i] = x[i] + state[i];
}
counter[0]++; counter[0]++;
if (counter[0] == 0) if (counter[0] == 0)
@@ -66,7 +82,10 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
if (counter[1] == 0) if (counter[1] == 0)
{ {
counter[2]++; counter[2]++;
if (counter[2] == 0) counter[3]++; if (counter[2] == 0)
{
counter[3]++;
}
} }
} }
} }
@@ -102,7 +121,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
private static void MaybeReseed() private static void MaybeReseed()
{ {
if (++entropyCounter % 64 == 0) if (++entropyCounter % 64 == 0)
{
Reseed(); Reseed();
}
} }
private static ulong ReadTSC() private static ulong ReadTSC()
@@ -112,14 +133,20 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
private static void EnsureInitialized() private static void EnsureInitialized()
{ {
if (initialized) return; if (initialized)
{
return;
}
initialized = true; initialized = true;
const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL; const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL;
ulong heapBits; ulong heapBits;
fixed (byte* p = new byte[1]) fixed (byte* p = new byte[1])
{
heapBits = (ulong)p; heapBits = (ulong)p;
}
Mix(BUILD_NONCE); Mix(BUILD_NONCE);
Mix(ReadTSC()); Mix(ReadTSC());
@@ -131,7 +158,7 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
private static readonly Lock _lock = new(); private static readonly Lock _lock = new();
private static uint[] buffer = new uint[16]; private static readonly uint[] buffer = new uint[16];
private static int bufferIndex = 16; private static int bufferIndex = 16;
private static uint NextUInt32() private static uint NextUInt32()
@@ -196,7 +223,7 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
{ {
Mix(scanCode); Mix(scanCode);
Mix(flags); Mix(flags);
Mix((ulong)keyChar); Mix(keyChar);
Mix(tsc); Mix(tsc);
MaybeReseed(); MaybeReseed();
} }
@@ -208,7 +235,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
lock (_lock) lock (_lock)
{ {
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
{
data[i] = NextByte(); data[i] = NextByte();
}
} }
} }
@@ -218,7 +247,9 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
lock (_lock) lock (_lock)
{ {
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{
bufferPtr[i] = NextByte(); bufferPtr[i] = NextByte();
}
} }
} }
} }
+6 -7
View File
@@ -1,6 +1,5 @@
using System;
using System.Threading;
using Cosmos.Kernel.System.Graphics; using Cosmos.Kernel.System.Graphics;
using RemSox.Processing; using RemSox.Processing;
using RemSox.UI.GUI.Rendering; using RemSox.UI.GUI.Rendering;
using RemSox.UI.GUI.Windows; using RemSox.UI.GUI.Windows;
@@ -28,18 +27,18 @@ public class DesktopProcess : Process
} }
// Trigger Canvas initialization // Trigger Canvas initialization
FullScreenCanvas.GetFullScreenCanvas(); _ = FullScreenCanvas.GetFullScreenCanvas();
// Force existing windows to redraw onto the new canvas renderer // Force existing windows to redraw onto the new canvas renderer
WindowManager.InvalidateAll(); WindowManager.InvalidateAll();
// Start the terminal process within the desktop environment // Start the terminal process within the desktop environment
ProcessManager.SpawnProcess<TerminalProcess>(); _ = ProcessManager.SpawnProcess<TerminalProcess>();
// Create a test window for new UI controls // Create a test window for new UI controls
Window testWindow = WindowManager.CreateWindow(this, "UI Controls Test", new System.Drawing.Point(500, 50), new System.Drawing.Size(200, 180)); Window testWindow = WindowManager.CreateWindow(this, "UI Controls Test", new System.Drawing.Point(500, 50), new System.Drawing.Size(200, 180));
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.Button>(b => _ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.Button>(b =>
{ {
b.Position = new System.Drawing.Point(20, 30); b.Position = new System.Drawing.Point(20, 30);
b.Size = new System.Drawing.Size(100, 30); b.Size = new System.Drawing.Size(100, 30);
@@ -47,14 +46,14 @@ public class DesktopProcess : Process
b.BackgroundColor = System.Drawing.Color.LightBlue; b.BackgroundColor = System.Drawing.Color.LightBlue;
}); });
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.CheckBox>(c => _ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Controls.CheckBox>(c =>
{ {
c.Position = new System.Drawing.Point(20, 80); c.Position = new System.Drawing.Point(20, 80);
c.Text = "Check Me"; c.Text = "Check Me";
c.IsChecked = true; c.IsChecked = true;
}); });
testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Shapes.Line>(l => _ = testWindow.CreateUIElement<RemSox.UI.GUI.UIEelements.Shapes.Line>(l =>
{ {
l.Position = new System.Drawing.Point(20, 130); l.Position = new System.Drawing.Point(20, 130);
l.EndPosition = new System.Drawing.Point(180, 130); l.EndPosition = new System.Drawing.Point(180, 130);
+26 -18
View File
@@ -1,24 +1,23 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using Cosmos.Kernel.System;
using Cosmos.Kernel.System.Keyboard; using Cosmos.Kernel.System.Keyboard;
using RemSox.Processing; using RemSox.Processing;
using RemSox.UI.CLI;
using RemSox.UI.GUI.UIEelements; using RemSox.UI.GUI.UIEelements;
using RemSox.UI.GUI.Windows; using RemSox.UI.GUI.Windows;
using RemSox.UI.GUI.CLI;
using System.Drawing;
namespace RemSox.Processes; namespace RemSox.Processes;
public class TerminalProcess : Process public class TerminalProcess : Process
{ {
private Window? window; private Window? window;
private readonly List<string> history = new(); private readonly List<string> history = [];
private string currentInput = ""; private string currentInput = "";
private readonly List<Text> textLines = new(); private readonly List<Text> textLines = [];
private readonly object textLinesLock = new object(); private readonly Lock textLinesLock = new();
private const int LineHeight = 30; private const int LineHeight = 30;
private Size lastSize = new Size(-1, -1); private Size lastSize = new(-1, -1);
public TerminalProcess() : base("Terminal") public TerminalProcess() : base("Terminal")
{ {
@@ -64,7 +63,7 @@ public class TerminalProcess : Process
} }
else else
{ {
bool found = CommandManager.TryExecute(cmd, line => PrintLine(line)); bool found = CommandManager.TryExecute(cmd, PrintLine);
if (!found) if (!found)
{ {
PrintLine($"\"{cmd}\" is not a command"); PrintLine($"\"{cmd}\" is not a command");
@@ -77,11 +76,11 @@ public class TerminalProcess : Process
{ {
if (currentInput.Length > 0) if (currentInput.Length > 0)
{ {
currentInput = currentInput.Substring(0, currentInput.Length - 1); currentInput = currentInput[..^1];
UpdateDisplay(); UpdateDisplay();
} }
} }
else if (keyEvent.KeyChar >= 32 && keyEvent.KeyChar <= 126) // Printable chars else if (keyEvent.KeyChar is >= (char)32 and <= (char)126) // Printable chars
{ {
currentInput += keyEvent.KeyChar; currentInput += keyEvent.KeyChar;
UpdateDisplay(); UpdateDisplay();
@@ -100,19 +99,25 @@ public class TerminalProcess : Process
private void UpdateDisplay() private void UpdateDisplay()
{ {
if (window == null) return; if (window == null)
{
return;
}
int availableHeight = window.Size.Height - 24; // 18 for title + 6 margin int availableHeight = window.Size.Height - 24; // 18 for title + 6 margin
int maxLines = availableHeight / LineHeight - 1; // -1 for input line int maxLines = (availableHeight / LineHeight) - 1; // -1 for input line
if (maxLines < 1) maxLines = 1; if (maxLines < 1)
{
maxLines = 1;
}
lock (textLinesLock) lock (textLinesLock)
{ {
// Ensure we have enough Text elements for maxLines + 1 (input line) // Ensure we have enough Text elements for maxLines + 1 (input line)
while (textLines.Count <= maxLines) while (textLines.Count <= maxLines)
{ {
var textElement = window.CreateUIElement<Text>(t => Text textElement = window.CreateUIElement<Text>(t =>
{ {
t.Color = Color.LightGreen; t.Color = Color.LightGreen;
t.Content = ""; t.Content = "";
@@ -122,7 +127,10 @@ public class TerminalProcess : Process
// Calculate starting Y to align everything flush to the bottom margin // Calculate starting Y to align everything flush to the bottom margin
int startY = window.Size.Height - ((maxLines + 1) * LineHeight) - 5; int startY = window.Size.Height - ((maxLines + 1) * LineHeight) - 5;
if (startY < 20) startY = 20; if (startY < 20)
{
startY = 20;
}
for (int i = 0; i < maxLines; i++) for (int i = 0; i < maxLines; i++)
{ {
@@ -140,7 +148,7 @@ public class TerminalProcess : Process
// The last line is the input line // The last line is the input line
textLines[maxLines].Content = "> " + currentInput + "_"; textLines[maxLines].Content = "> " + currentInput + "_";
textLines[maxLines].Position = new Point(5, startY + (maxLines * LineHeight)); textLines[maxLines].Position = new Point(5, startY + (maxLines * LineHeight));
// Hide any extra text lines we don't need // Hide any extra text lines we don't need
for (int i = maxLines + 1; i < textLines.Count; i++) for (int i = maxLines + 1; i < textLines.Count; i++)
{ {
textLines[i].Content = ""; textLines[i].Content = "";
+1 -4
View File
@@ -1,6 +1,3 @@
using System;
using RemSox.Processing;
namespace RemSox.Processing.IPC; namespace RemSox.Processing.IPC;
internal static class InterProcessCommunicator internal static class InterProcessCommunicator
@@ -15,7 +12,7 @@ internal static class InterProcessCommunicator
{ {
message.SenderProcessId = sender.Id; // automatically set message.SenderProcessId = sender.Id; // automatically set
foreach (var process in ProcessManager.GetAllProcesses()) foreach (Process process in ProcessManager.GetAllProcesses())
{ {
process.HandleInterProcessMessage(message); process.HandleInterProcessMessage(message);
} }
-2
View File
@@ -1,5 +1,3 @@
using System;
namespace RemSox.Processing.IPC; namespace RemSox.Processing.IPC;
public abstract class Message public abstract class Message
-1
View File
@@ -1,4 +1,3 @@
using System;
using RemSox.Processing.IPC; using RemSox.Processing.IPC;
namespace RemSox.Processing; namespace RemSox.Processing;
+12 -10
View File
@@ -1,7 +1,7 @@
using System;
using System.Collections.Concurrent;
using RemSox.UI.GUI.Windows; using RemSox.UI.GUI.Windows;
using System.Collections.Concurrent;
namespace RemSox.Processing; namespace RemSox.Processing;
public static class ProcessManager public static class ProcessManager
@@ -31,12 +31,12 @@ public static class ProcessManager
} }
finally finally
{ {
processes.TryRemove(id, out _); _ = processes.TryRemove(id, out _);
WindowManager.CloseWindowsForProcess(id); WindowManager.CloseWindowsForProcess(id);
} }
}); });
processes.TryAdd(id, (process, thread)); _ = processes.TryAdd(id, (process, thread));
thread.Start(); thread.Start();
@@ -45,19 +45,21 @@ public static class ProcessManager
public static void StopProcess(int processId) public static void StopProcess(int processId)
{ {
if (!processes.TryGetValue(processId, out var entry)) if (!processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
{
return; return;
}
entry.Process.RequestStop(); entry.Process.RequestStop();
WindowManager.CloseWindowsForProcess(processId); WindowManager.CloseWindowsForProcess(processId);
processes.TryRemove(processId, out _); _ = processes.TryRemove(processId, out _);
} }
public static void StopAllProcesses() public static void StopAllProcesses()
{ {
foreach (var entry in processes.Values) foreach ((Process Process, Thread Thread) entry in processes.Values)
{ {
StopProcess(entry.Process.Id); StopProcess(entry.Process.Id);
} }
@@ -67,7 +69,7 @@ public static class ProcessManager
public static Process? GetProcess(int processId) public static Process? GetProcess(int processId)
{ {
if (processes.TryGetValue(processId, out var entry)) if (processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
{ {
return entry.Process; return entry.Process;
} }
@@ -77,7 +79,7 @@ public static class ProcessManager
public static IEnumerable<Process> GetAllProcesses() public static IEnumerable<Process> GetAllProcesses()
{ {
foreach (var entry in processes.Values) foreach ((Process Process, Thread Thread) entry in processes.Values)
{ {
yield return entry.Process; yield return entry.Process;
} }
@@ -85,7 +87,7 @@ public static class ProcessManager
public static bool TryGetProcess(int processId, out Process? process) public static bool TryGetProcess(int processId, out Process? process)
{ {
if (processes.TryGetValue(processId, out var entry)) if (processes.TryGetValue(processId, out (Process Process, Thread Thread) entry))
{ {
process = entry.Process; process = entry.Process;
return true; return true;
+2 -4
View File
@@ -1,6 +1,4 @@
using System; namespace RemSox.UI.CLI;
namespace RemSox.UI.GUI.CLI;
public static class CommandManager public static class CommandManager
{ {
@@ -48,7 +46,7 @@ public static class CommandManager
if (trimmedInput.Length > commandName.Length) if (trimmedInput.Length > commandName.Length)
{ {
arguments = trimmedInput.Substring(commandName.Length).TrimStart(); arguments = trimmedInput[commandName.Length..].TrimStart();
} }
entry.Value.Execute(arguments, printLine); entry.Value.Execute(arguments, printLine);
+1 -3
View File
@@ -1,6 +1,4 @@
using System; namespace RemSox.UI.CLI.Commands;
namespace RemSox.UI.GUI.CLI.Commands;
public sealed class ClearCommand : ICommand public sealed class ClearCommand : ICommand
{ {
+2 -2
View File
@@ -1,6 +1,6 @@
using System; using RemSox.UI.CLI;
namespace RemSox.UI.GUI.CLI.Commands; namespace RemSox.UI.CLI.Commands;
public sealed class HaltCommand : ICommand public sealed class HaltCommand : ICommand
{ {
+2 -2
View File
@@ -1,6 +1,6 @@
using System; using RemSox.UI.CLI;
namespace RemSox.UI.GUI.CLI.Commands; namespace RemSox.UI.CLI.Commands;
public sealed class HelpCommand : ICommand public sealed class HelpCommand : ICommand
{ {
+2 -2
View File
@@ -1,7 +1,7 @@
using System;
using RemSox.Processing; using RemSox.Processing;
using RemSox.UI.CLI;
namespace RemSox.UI.GUI.CLI.Commands; namespace RemSox.UI.CLI.Commands;
public sealed class SpawnTestProcessCommand : ICommand public sealed class SpawnTestProcessCommand : ICommand
{ {
+4 -5
View File
@@ -1,9 +1,8 @@
using System;
using RemSox.Processing;
using RemSox.Processes; using RemSox.Processes;
using RemSox.UI.GUI.CLI; using RemSox.Processing;
using RemSox.UI.CLI;
namespace RemSox.UI.GUI.CLI.Commands; namespace RemSox.UI.CLI.Commands;
public class StartGuiCommand : ICommand public class StartGuiCommand : ICommand
{ {
@@ -13,6 +12,6 @@ public class StartGuiCommand : ICommand
public void Execute(string? arguments, Action<string> printLine) public void Execute(string? arguments, Action<string> printLine)
{ {
printLine("Starting Desktop Process..."); printLine("Starting Desktop Process...");
ProcessManager.SpawnProcess<DesktopProcess>(); _ = ProcessManager.SpawnProcess<DesktopProcess>();
} }
} }
+1 -4
View File
@@ -1,7 +1,4 @@
namespace RemSox.UI.GUI.CLI; namespace RemSox.UI.CLI;
using System;
/// <summary> /// <summary>
/// Defines a command executable via the CLI or GUI terminal. /// Defines a command executable via the CLI or GUI terminal.
/// </summary> /// </summary>
+14 -16
View File
@@ -1,23 +1,21 @@
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using Cosmos.Kernel.System.Graphics; using Cosmos.Kernel.System.Graphics;
using Cosmos.Kernel.System.Graphics.Fonts; using Cosmos.Kernel.System.Graphics.Fonts;
using System.Drawing;
namespace RemSox.UI.GUI.Rendering; namespace RemSox.UI.GUI.Rendering;
public sealed class CanvasRenderSource : IRenderSource public sealed class CanvasRenderSource : IRenderSource
{ {
private static readonly Dictionary<int, Canvas> windowCanvases = new(); private static readonly Dictionary<int, Canvas> windowCanvases = [];
private static readonly Dictionary<int, Point> windowPositions = new(); private static readonly Dictionary<int, Point> windowPositions = [];
private static readonly Dictionary<int, int> windowZIndices = new(); private static readonly Dictionary<int, int> windowZIndices = [];
private static bool isDirty = true; private static bool isDirty = true;
private static Point lastPointerPosition = new Point(-1, -1); private static Point lastPointerPosition = new(-1, -1);
private static List<int> orderedWindowsCache = new(); private static List<int> orderedWindowsCache = [];
private static bool isZOrderDirty = true; private static bool isZOrderDirty = true;
private static readonly object renderLock = new object(); private static readonly Lock renderLock = new();
public void Render(IEnumerable<RenderCommand> commands) public void Render(IEnumerable<RenderCommand> commands)
{ {
@@ -29,14 +27,14 @@ public sealed class CanvasRenderSource : IRenderSource
changed = true; changed = true;
if (command.ElementType == "WindowClose") if (command.ElementType == "WindowClose")
{ {
windowCanvases.Remove(command.WindowId); _ = windowCanvases.Remove(command.WindowId);
windowPositions.Remove(command.WindowId); _ = windowPositions.Remove(command.WindowId);
windowZIndices.Remove(command.WindowId); _ = windowZIndices.Remove(command.WindowId);
isZOrderDirty = true; isZOrderDirty = true;
continue; continue;
} }
if (command.ElementType == "Window" || command.ElementType == "WindowMove") if (command.ElementType is "Window" or "WindowMove")
{ {
if (command.Properties.TryGetValue("ZIndex", out object? rawZIndex) && rawZIndex is int z) if (command.Properties.TryGetValue("ZIndex", out object? rawZIndex) && rawZIndex is int z)
{ {
@@ -134,7 +132,7 @@ public sealed class CanvasRenderSource : IRenderSource
screenCanvas.Clear(Color.Black); screenCanvas.Clear(Color.Black);
foreach (var windowId in orderedWindowsCache) foreach (int windowId in orderedWindowsCache)
{ {
if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas)) if (windowPositions.TryGetValue(windowId, out Point position) && windowCanvases.TryGetValue(windowId, out Canvas? windowCanvas))
{ {
@@ -256,7 +254,7 @@ public sealed class CanvasRenderSource : IRenderSource
{ {
Color bgColor = command.Properties.TryGetValue("BackgroundColor", out object? rawBgColor) && rawBgColor is Color c1 ? c1 : Color.LightGray; Color bgColor = command.Properties.TryGetValue("BackgroundColor", out object? rawBgColor) && rawBgColor is Color c1 ? c1 : Color.LightGray;
Color textColor = command.Properties.TryGetValue("TextColor", out object? rawTextColor) && rawTextColor is Color c2 ? c2 : Color.White; Color textColor = command.Properties.TryGetValue("TextColor", out object? rawTextColor) && rawTextColor is Color c2 ? c2 : Color.White;
bool isChecked = command.Properties.TryGetValue("IsChecked", out object? rawChecked) && rawChecked is bool chk ? chk : false; bool isChecked = command.Properties.TryGetValue("IsChecked", out object? rawChecked) && rawChecked is bool chk && chk;
string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty; string text = command.Properties.TryGetValue("Text", out object? rawText) && rawText is string t ? t : string.Empty;
int boxSize = 12; int boxSize = 12;
+1 -1
View File
@@ -2,5 +2,5 @@ namespace RemSox.UI.GUI.Rendering;
public interface IRenderSource public interface IRenderSource
{ {
public void Render(IEnumerable<RenderCommand> commands); void Render(IEnumerable<RenderCommand> commands);
} }
-1
View File
@@ -1,4 +1,3 @@
using System;
using System.Drawing; using System.Drawing;
namespace RemSox.UI.GUI.Rendering; namespace RemSox.UI.GUI.Rendering;
-1
View File
@@ -1,4 +1,3 @@
using System;
using System.Drawing; using System.Drawing;
namespace RemSox.UI.GUI.UIEelements; namespace RemSox.UI.GUI.UIEelements;
-2
View File
@@ -1,5 +1,3 @@
using System.Drawing;
namespace RemSox.UI.GUI.UIEelements.Shapes; namespace RemSox.UI.GUI.UIEelements.Shapes;
public class Circle() : Shape("Circle") public class Circle() : Shape("Circle")
+4 -5
View File
@@ -1,10 +1,9 @@
namespace RemSox.UI.GUI.UIEelements;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using RemSox.Utils; using RemSox.Utils;
using System.Drawing;
namespace RemSox.UI.GUI.UIEelements;
public abstract class UIElement(string type) : ChangedPropertiesTracker public abstract class UIElement(string type) : ChangedPropertiesTracker
{ {
public int Id { get; init; } public int Id { get; init; }
+42 -23
View File
@@ -1,9 +1,8 @@
using System;
using System.Drawing;
using System.Reflection;
using RemSox.UI.GUI.Rendering; using RemSox.UI.GUI.Rendering;
using RemSox.UI.GUI.UIEelements; using RemSox.UI.GUI.UIEelements;
using System.Drawing;
namespace RemSox.UI.GUI.Windows; namespace RemSox.UI.GUI.Windows;
/// <summary> /// <summary>
@@ -38,11 +37,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
/// <summary> Gets or sets whether this window is currently focused. </summary> /// <summary> Gets or sets whether this window is currently focused. </summary>
public bool IsFocused public bool IsFocused
{ {
get => WindowManager.IsWindowFocused(this); get => WindowManager.IsWindowFocused(this); set => WindowManager.FocusWindow(value ? this : null);
set
{
WindowManager.FocusWindow(value ? this : null);
}
} }
/// <summary> Gets or sets whether the window is visible. </summary> /// <summary> Gets or sets whether the window is visible. </summary>
@@ -63,7 +58,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
/// <summary> Gets whether the window is currently being dragged. </summary> /// <summary> Gets whether the window is currently being dragged. </summary>
public bool IsDragging => currentInteraction == InteractionMode.Drag; public bool IsDragging => currentInteraction == InteractionMode.Drag;
private readonly object uiElementsLock = new object(); private readonly Lock uiElementsLock = new();
private readonly Dictionary<int, UIElement> uiElements = []; private readonly Dictionary<int, UIElement> uiElements = [];
private int nextUIElementId = 1; private int nextUIElementId = 1;
@@ -74,8 +69,8 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
private Point interactionStartPointer; private Point interactionStartPointer;
private Point dragOffset; private Point dragOffset;
private Point lastRenderedPosition = new Point(-1, -1); private Point lastRenderedPosition = new(-1, -1);
private Size lastRenderedSize = new Size(-1, -1); private Size lastRenderedSize = new(-1, -1);
private bool lastRenderedIsFocused = false; private bool lastRenderedIsFocused = false;
private string lastRenderedTitle = string.Empty; private string lastRenderedTitle = string.Empty;
private int lastRenderedZIndex = -1; private int lastRenderedZIndex = -1;
@@ -235,14 +230,38 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
if (IsResizable) if (IsResizable)
{ {
if (onTop && onLeft) currentInteraction = InteractionMode.ResizeTopLeft; if (onTop && onLeft)
else if (onTop && onRight) currentInteraction = InteractionMode.ResizeTopRight; {
else if (onBottom && onLeft) currentInteraction = InteractionMode.ResizeBottomLeft; currentInteraction = InteractionMode.ResizeTopLeft;
else if (onBottom && onRight) currentInteraction = InteractionMode.ResizeBottomRight; }
else if (onLeft && inBounds) currentInteraction = InteractionMode.ResizeLeft; else if (onTop && onRight)
else if (onRight && inBounds) currentInteraction = InteractionMode.ResizeRight; {
else if (onTop && inBounds) currentInteraction = InteractionMode.ResizeTop; currentInteraction = InteractionMode.ResizeTopRight;
else if (onBottom && inBounds) currentInteraction = InteractionMode.ResizeBottom; }
else if (onBottom && onLeft)
{
currentInteraction = InteractionMode.ResizeBottomLeft;
}
else if (onBottom && onRight)
{
currentInteraction = InteractionMode.ResizeBottomRight;
}
else if (onLeft && inBounds)
{
currentInteraction = InteractionMode.ResizeLeft;
}
else if (onRight && inBounds)
{
currentInteraction = InteractionMode.ResizeRight;
}
else if (onTop && inBounds)
{
currentInteraction = InteractionMode.ResizeTop;
}
else if (onBottom && inBounds)
{
currentInteraction = InteractionMode.ResizeBottom;
}
} }
if (currentInteraction == InteractionMode.None && IsDraggable && IsPointInTitleBar(pointerPosition)) if (currentInteraction == InteractionMode.None && IsDraggable && IsPointInTitleBar(pointerPosition))
@@ -297,22 +316,22 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
const int minWidth = 100; const int minWidth = 100;
const int minHeight = 50; const int minHeight = 50;
if (currentInteraction == InteractionMode.ResizeRight || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeTopRight) if (currentInteraction is InteractionMode.ResizeRight or InteractionMode.ResizeBottomRight or InteractionMode.ResizeTopRight)
{ {
newW = Math.Max(minWidth, interactionStartBounds.Width + dx); newW = Math.Max(minWidth, interactionStartBounds.Width + dx);
} }
if (currentInteraction == InteractionMode.ResizeBottom || currentInteraction == InteractionMode.ResizeBottomRight || currentInteraction == InteractionMode.ResizeBottomLeft) if (currentInteraction is InteractionMode.ResizeBottom or InteractionMode.ResizeBottomRight or InteractionMode.ResizeBottomLeft)
{ {
newH = Math.Max(minHeight, interactionStartBounds.Height + dy); newH = Math.Max(minHeight, interactionStartBounds.Height + dy);
} }
if (currentInteraction == InteractionMode.ResizeLeft || currentInteraction == InteractionMode.ResizeBottomLeft || currentInteraction == InteractionMode.ResizeTopLeft) if (currentInteraction is InteractionMode.ResizeLeft or InteractionMode.ResizeBottomLeft or InteractionMode.ResizeTopLeft)
{ {
int maxDx = interactionStartBounds.Width - minWidth; int maxDx = interactionStartBounds.Width - minWidth;
int clampedDx = Math.Min(dx, maxDx); int clampedDx = Math.Min(dx, maxDx);
newX = Math.Max(0, interactionStartBounds.X + clampedDx); newX = Math.Max(0, interactionStartBounds.X + clampedDx);
newW = interactionStartBounds.Width - clampedDx; newW = interactionStartBounds.Width - clampedDx;
} }
if (currentInteraction == InteractionMode.ResizeTop || currentInteraction == InteractionMode.ResizeTopLeft || currentInteraction == InteractionMode.ResizeTopRight) if (currentInteraction is InteractionMode.ResizeTop or InteractionMode.ResizeTopLeft or InteractionMode.ResizeTopRight)
{ {
int maxDy = interactionStartBounds.Height - minHeight; int maxDy = interactionStartBounds.Height - minHeight;
int clampedDy = Math.Min(dy, maxDy); int clampedDy = Math.Min(dy, maxDy);
+31 -32
View File
@@ -1,14 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Cosmos.Kernel.System.Graphics; using Cosmos.Kernel.System.Graphics;
using Cosmos.Kernel.System.Mouse;
using Cosmos.Kernel.System.Keyboard; using Cosmos.Kernel.System.Keyboard;
using Cosmos.Kernel.System.Mouse;
using RemSox.Processing; using RemSox.Processing;
using RemSox.UI.GUI.Rendering; using RemSox.UI.GUI.Rendering;
using System.Drawing;
namespace RemSox.UI.GUI.Windows; namespace RemSox.UI.GUI.Windows;
/// <summary> /// <summary>
@@ -16,9 +14,9 @@ namespace RemSox.UI.GUI.Windows;
/// </summary> /// </summary>
public static class WindowManager public static class WindowManager
{ {
private static readonly object windowsLock = new object(); private static readonly Lock windowsLock = new();
// Process ID to list of windows // Process ID to list of windows
private static readonly Dictionary<int, List<Window>> windows = new(); private static readonly Dictionary<int, List<Window>> windows = [];
private static int nextWindowId = 1; private static int nextWindowId = 1;
private static int nextZIndex = 1; private static int nextZIndex = 1;
@@ -28,7 +26,6 @@ public static class WindowManager
private static Window? activeInteractWindow = null; private static Window? activeInteractWindow = null;
private static Point lastPointerPosition = Point.Empty; private static Point lastPointerPosition = Point.Empty;
private static bool wasLeftButtonDown = false; private static bool wasLeftButtonDown = false;
private static int mousePollCounter = 0;
private static readonly MuliRenderSource renderSource = new([]); private static readonly MuliRenderSource renderSource = new([]);
@@ -37,10 +34,9 @@ public static class WindowManager
/// </summary> /// </summary>
public static void Update() public static void Update()
{ {
mousePollCounter++;
MouseManager.Poll(); MouseManager.Poll();
Point pointerPosition = new((int)MouseManager.X, (int)MouseManager.Y); Point pointerPosition = new(MouseManager.X, MouseManager.Y);
bool leftButtonDown = MouseManager.LeftButton; bool leftButtonDown = MouseManager.LeftButton;
if (leftButtonDown && !wasLeftButtonDown) if (leftButtonDown && !wasLeftButtonDown)
@@ -59,7 +55,7 @@ public static class WindowManager
wasLeftButtonDown = leftButtonDown; wasLeftButtonDown = leftButtonDown;
while (KeyboardManager.TryReadKey(out KeyEvent keyEvent)) while (KeyboardManager.TryReadKey(out KeyEvent? keyEvent) && keyEvent is not null)
{ {
focusedWindow?.HandleKeyEvent(keyEvent); focusedWindow?.HandleKeyEvent(keyEvent);
} }
@@ -73,12 +69,18 @@ public static class WindowManager
/// <summary> /// <summary>
/// Adds a new rendering source to the compositor. /// Adds a new rendering source to the compositor.
/// </summary> /// </summary>
public static void AddRenderSource(IRenderSource source) => renderSource.AddSource(source); public static void AddRenderSource(IRenderSource source)
{
renderSource.AddSource(source);
}
/// <summary> /// <summary>
/// Removes an existing rendering source from the compositor. /// Removes an existing rendering source from the compositor.
/// </summary> /// </summary>
public static void RemoveRenderSource(IRenderSource source) => renderSource.RemoveSource(source); public static void RemoveRenderSource(IRenderSource source)
{
renderSource.RemoveSource(source);
}
/// <summary> /// <summary>
/// Creates and registers a new window for the specified process. /// Creates and registers a new window for the specified process.
@@ -112,13 +114,13 @@ public static class WindowManager
{ {
lock (windowsLock) lock (windowsLock)
{ {
if (windows.TryGetValue(window.ProcessId, out var processWindows)) if (windows.TryGetValue(window.ProcessId, out List<Window>? processWindows))
{ {
processWindows.Remove(window); _ = processWindows.Remove(window);
} }
} }
renderSource.Render(new[] { new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() } }); renderSource.Render([new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() }]);
} }
/// <summary> /// <summary>
@@ -128,7 +130,7 @@ public static class WindowManager
{ {
lock (windowsLock) lock (windowsLock)
{ {
if (windows.TryGetValue(process.Id, out var processWindows)) if (windows.TryGetValue(process.Id, out List<Window>? processWindows))
{ {
return processWindows.ToList(); return processWindows.ToList();
} }
@@ -150,20 +152,20 @@ public static class WindowManager
/// </summary> /// </summary>
public static void CloseWindowsForProcess(int processId) public static void CloseWindowsForProcess(int processId)
{ {
List<Window> windowsToClose = new(); List<Window> windowsToClose = [];
lock (windowsLock) lock (windowsLock)
{ {
if (windows.TryGetValue(processId, out var processWindows)) if (windows.TryGetValue(processId, out List<Window>? processWindows))
{ {
windowsToClose.AddRange(processWindows); windowsToClose.AddRange(processWindows);
windows.Remove(processId); _ = windows.Remove(processId);
} }
} }
if (windowsToClose.Count > 0) if (windowsToClose.Count > 0)
{ {
List<RenderCommand> closeCommands = new(); List<RenderCommand> closeCommands = [];
foreach (var window in windowsToClose) foreach (Window window in windowsToClose)
{ {
closeCommands.Add(new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() }); closeCommands.Add(new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() });
} }
@@ -181,10 +183,7 @@ public static class WindowManager
return; return;
} }
if (window != null) _ = window?.ZIndex = nextZIndex++;
{
window.ZIndex = nextZIndex++;
}
Window? previousFocusedWindow = focusedWindow; Window? previousFocusedWindow = focusedWindow;
focusedWindow = window; focusedWindow = window;
@@ -212,7 +211,7 @@ public static class WindowManager
allWindows = windows.Values.SelectMany(w => w).OrderByDescending(w => w.ZIndex).ToList(); allWindows = windows.Values.SelectMany(w => w).OrderByDescending(w => w.ZIndex).ToList();
} }
foreach (var window in allWindows) foreach (Window window in allWindows)
{ {
if (window.TryBeginInteract(pointerPosition)) if (window.TryBeginInteract(pointerPosition))
{ {
@@ -233,7 +232,7 @@ public static class WindowManager
allWindows = windows.Values.SelectMany(w => w).ToList(); allWindows = windows.Values.SelectMany(w => w).ToList();
} }
foreach (var window in allWindows) foreach (Window window in allWindows)
{ {
window.Invalidate(); window.Invalidate();
} }
@@ -244,9 +243,9 @@ public static class WindowManager
return nextWindowId++; return nextWindowId++;
} }
sealed private class MuliRenderSource(List<IRenderSource> sources) : IRenderSource private sealed class MuliRenderSource(List<IRenderSource> sources) : IRenderSource
{ {
private readonly object sourcesLock = new object(); private readonly Lock sourcesLock = new();
public void AddSource(IRenderSource source) public void AddSource(IRenderSource source)
{ {
@@ -260,7 +259,7 @@ public static class WindowManager
{ {
lock (sourcesLock) lock (sourcesLock)
{ {
sources.Remove(source); _ = sources.Remove(source);
} }
} }
+10 -7
View File
@@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
namespace RemSox.Utils; namespace RemSox.Utils;
@@ -14,7 +11,7 @@ public abstract class ChangedPropertiesTracker : INotifyPropertyChanged
{ {
get get
{ {
var changes = new Dictionary<string, object?>(); Dictionary<string, object?> changes = new();
foreach (var name in changedPropertyNames) foreach (var name in changedPropertyNames)
{ {
if (properties.TryGetValue(name, out var value)) if (properties.TryGetValue(name, out var value))
@@ -38,12 +35,18 @@ public abstract class ChangedPropertiesTracker : INotifyPropertyChanged
{ {
field = value; field = value;
properties[name] = value; properties[name] = value;
changedPropertyNames.Add(name); _ = changedPropertyNames.Add(name);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
} }
} }
public void ClearChangedProperties() => changedPropertyNames.Clear(); public void ClearChangedProperties()
{
changedPropertyNames.Clear();
}
public bool IsPropertyChanged(string name) => changedPropertyNames.Contains(name); public bool IsPropertyChanged(string name)
{
return changedPropertyNames.Contains(name);
}
} }