diff --git a/BuildTime.txt b/BuildTime.txt
index d91312e..32cc382 100644
--- a/BuildTime.txt
+++ b/BuildTime.txt
@@ -1 +1 @@
-2026-03-06 21:05:30
\ No newline at end of file
+2026-03-08 19:50:50
\ No newline at end of file
diff --git a/CMLeonOS.csproj b/CMLeonOS.csproj
index 63e2a4f..1621d77 100644
--- a/CMLeonOS.csproj
+++ b/CMLeonOS.csproj
@@ -29,7 +29,7 @@
2
800x600x32
Always
- 1
+ 0
False
diff --git a/Driver/VMWareSVGAII.cs b/Driver/VMWareSVGAII.cs
index 08ce56e..5cb7660 100644
--- a/Driver/VMWareSVGAII.cs
+++ b/Driver/VMWareSVGAII.cs
@@ -525,8 +525,6 @@ namespace CMLeonOS.Driver
IRQPort = (ushort)(basePort + (uint)IOPortOffset.IRQ);
WriteRegister(Register.ID, (uint)ID.V2);
- if (ReadRegister(Register.ID) != (uint)ID.V2)
- return;
VideoMemory = new MemoryBlock(ReadRegister(Register.FrameBufferStart), ReadRegister(Register.VRamSize));
capabilities = ReadRegister(Register.Capabilities);
@@ -554,10 +552,8 @@ namespace CMLeonOS.Driver
/// Depth.
public void SetMode(uint width, uint height, uint depth = 32)
{
- //Disable the Driver before writing new values and initiating it again to avoid a memory exception
- //Disable();
+ Disable();
- // Depth is color depth in bytes.
this.depth = (depth / 8);
this.width = width;
this.height = height;
diff --git a/GitCommit.txt b/GitCommit.txt
index 2c624a1..b948120 100644
--- a/GitCommit.txt
+++ b/GitCommit.txt
@@ -1 +1 @@
-6c514df
\ No newline at end of file
+de16189
\ No newline at end of file
diff --git a/Gui/Apps/CodeStudio/Ide.cs b/Gui/Apps/CodeStudio/Ide.cs
index 7472353..05ce47b 100644
--- a/Gui/Apps/CodeStudio/Ide.cs
+++ b/Gui/Apps/CodeStudio/Ide.cs
@@ -1,4 +1,4 @@
-using CMLeonOS;
+using CMLeonOS;
using CMLeonOS.Gui.UILib;
using Cosmos.System.Graphics;
using System.Drawing;
@@ -17,6 +17,10 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
this.wm = wm;
}
+ [IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.AppIcons.CodeStudio.bmp")]
+ private static byte[] _iconBytes;
+ private static Bitmap iconBitmap = new Bitmap(_iconBytes);
+
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.CodeStudio.Run.bmp")]
private static byte[] _runBytes;
private static Bitmap runBitmap = new Bitmap(_runBytes);
@@ -175,6 +179,9 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
ILuaState lua = LuaAPI.NewState();
lua.L_OpenLibs();
+ LuaGuiLibrary.Initialize(wm, process);
+ LuaGuiLibrary.Register(lua);
+
lua.PushCSharpFunction(L =>
{
int n = L.GetTop();
@@ -275,6 +282,7 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
internal void Start()
{
mainWindow = new AppWindow(process, 96, 96, 800, 600);
+ mainWindow.Icon = iconBitmap;
mainWindow.Clear(Theme.Background);
mainWindow.Closing = process.TryStop;
mainWindow.CanResize = true;
diff --git a/Gui/Apps/CodeStudio/LuaGuiLibrary.cs b/Gui/Apps/CodeStudio/LuaGuiLibrary.cs
new file mode 100644
index 0000000..a710099
--- /dev/null
+++ b/Gui/Apps/CodeStudio/LuaGuiLibrary.cs
@@ -0,0 +1,439 @@
+using CMLeonOS.Gui;
+using CMLeonOS.Gui.UILib;
+using Cosmos.System.Graphics;
+using System.Drawing;
+using UniLua;
+using System;
+
+namespace CMLeonOS.Gui.Apps.CodeStudio
+{
+ internal class LuaGuiLibrary
+ {
+ private static WindowManager? wm = null;
+ private static Process? process = null;
+
+ public static void Initialize(WindowManager windowManager, Process currentProcess)
+ {
+ wm = windowManager;
+ process = currentProcess;
+ }
+
+ public static void Register(ILuaState lua)
+ {
+ if (wm == null || process == null)
+ {
+ throw new Exception("GUI library not initialized. Make sure you are running in GUI mode.");
+ }
+
+ lua.NewTable();
+
+ lua.PushString("createWindow");
+ lua.PushCSharpFunction(CreateWindow);
+ lua.SetTable(-3);
+
+ lua.PushString("showMessageBox");
+ lua.PushCSharpFunction(ShowMessageBox);
+ lua.SetTable(-3);
+
+ lua.PushString("closeWindow");
+ lua.PushCSharpFunction(CloseWindow);
+ lua.SetTable(-3);
+
+ lua.PushString("setWindowTitle");
+ lua.PushCSharpFunction(SetWindowTitle);
+ lua.SetTable(-3);
+
+ lua.PushString("setWindowSize");
+ lua.PushCSharpFunction(SetWindowSize);
+ lua.SetTable(-3);
+
+ lua.PushString("setWindowPosition");
+ lua.PushCSharpFunction(SetWindowPosition);
+ lua.SetTable(-3);
+
+ lua.PushString("clearWindow");
+ lua.PushCSharpFunction(ClearWindow);
+ lua.SetTable(-3);
+
+ lua.PushString("drawText");
+ lua.PushCSharpFunction(DrawText);
+ lua.SetTable(-3);
+
+ lua.PushString("drawRectangle");
+ lua.PushCSharpFunction(DrawRectangle);
+ lua.SetTable(-3);
+
+ lua.PushString("drawFilledRectangle");
+ lua.PushCSharpFunction(DrawFilledRectangle);
+ lua.SetTable(-3);
+
+ lua.PushString("drawCircle");
+ lua.PushCSharpFunction(DrawCircle);
+ lua.SetTable(-3);
+
+ lua.PushString("drawLine");
+ lua.PushCSharpFunction(DrawLine);
+ lua.SetTable(-3);
+
+ lua.PushString("drawPoint");
+ lua.PushCSharpFunction(DrawPoint);
+ lua.SetTable(-3);
+
+ lua.PushString("updateWindow");
+ lua.PushCSharpFunction(UpdateWindow);
+ lua.SetTable(-3);
+
+ lua.SetGlobal("gui");
+ }
+
+ private static int CreateWindow(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ string title = L.ToString(1);
+ int width = (int)L.ToNumber(2);
+ int height = (int)L.ToNumber(3);
+
+ int x = (int)((wm.ScreenWidth - width) / 2);
+ int y = (int)((wm.ScreenHeight - height) / 2);
+
+ AppWindow window = new AppWindow(process, x, y, width, height);
+ window.Title = title;
+ wm.AddWindow(window);
+
+ L.PushLightUserData(window);
+ return 1;
+ }
+
+ private static int ShowMessageBox(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ string title = L.ToString(1);
+ string message = L.ToString(2);
+
+ MessageBox messageBox = new MessageBox(process, title, message);
+ messageBox.Show();
+
+ return 0;
+ }
+
+ private static int CloseWindow(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ if (window != null)
+ {
+ wm.RemoveWindow(window);
+ }
+
+ return 0;
+ }
+
+ private static int SetWindowTitle(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ string title = L.ToString(2);
+
+ if (window != null)
+ {
+ window.Title = title;
+ wm.Update(window);
+ }
+
+ return 0;
+ }
+
+ private static int SetWindowSize(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int width = (int)L.ToNumber(2);
+ int height = (int)L.ToNumber(3);
+
+ if (window != null)
+ {
+ window.Resize(width, height);
+ }
+
+ return 0;
+ }
+
+ private static int SetWindowPosition(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x = (int)L.ToNumber(2);
+ int y = (int)L.ToNumber(3);
+
+ if (window != null)
+ {
+ window.Move(x, y);
+ }
+
+ return 0;
+ }
+
+ private static int ClearWindow(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ Color color = ParseColor(L, 2);
+
+ if (window != null)
+ {
+ window.Clear(color);
+ }
+
+ return 0;
+ }
+
+ private static int DrawText(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ string text = L.ToString(2);
+ Color color = ParseColor(L, 3);
+ int x = (int)L.ToNumber(4);
+ int y = (int)L.ToNumber(5);
+
+ if (window != null)
+ {
+ window.DrawString(text, color, x, y);
+ }
+
+ return 0;
+ }
+
+ private static int DrawRectangle(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x = (int)L.ToNumber(2);
+ int y = (int)L.ToNumber(3);
+ int width = (int)L.ToNumber(4);
+ int height = (int)L.ToNumber(5);
+ Color color = ParseColor(L, 6);
+
+ if (window != null)
+ {
+ window.DrawRectangle(x, y, width, height, color);
+ }
+
+ return 0;
+ }
+
+ private static int DrawFilledRectangle(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x = (int)L.ToNumber(2);
+ int y = (int)L.ToNumber(3);
+ int width = (int)L.ToNumber(4);
+ int height = (int)L.ToNumber(5);
+ Color color = ParseColor(L, 6);
+
+ if (window != null)
+ {
+ window.DrawFilledRectangle(x, y, width, height, color);
+ }
+
+ return 0;
+ }
+
+ private static int DrawCircle(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x = (int)L.ToNumber(2);
+ int y = (int)L.ToNumber(3);
+ int radius = (int)L.ToNumber(4);
+ Color color = ParseColor(L, 5);
+
+ if (window != null)
+ {
+ window.DrawCircle(x, y, radius, color);
+ }
+
+ return 0;
+ }
+
+ private static int DrawLine(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x1 = (int)L.ToNumber(2);
+ int y1 = (int)L.ToNumber(3);
+ int x2 = (int)L.ToNumber(4);
+ int y2 = (int)L.ToNumber(5);
+ Color color = ParseColor(L, 6);
+
+ if (window != null)
+ {
+ window.DrawLine(x1, y1, x2, y2, color);
+ }
+
+ return 0;
+ }
+
+ private static int DrawPoint(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+ int x = (int)L.ToNumber(2);
+ int y = (int)L.ToNumber(3);
+ Color color = ParseColor(L, 4);
+
+ if (window != null)
+ {
+ window.DrawPoint(x, y, color);
+ }
+
+ return 0;
+ }
+
+ private static int UpdateWindow(ILuaState L)
+ {
+ if (wm == null || process == null)
+ {
+ L.PushString("GUI library not initialized");
+ L.Error();
+ return 1;
+ }
+
+ AppWindow window = L.ToUserData(1) as AppWindow;
+
+ if (window != null)
+ {
+ wm.Update(window);
+ }
+
+ return 0;
+ }
+
+ private static Color ParseColor(ILuaState L, int index)
+ {
+ if (L.IsTable(index))
+ {
+ L.GetField(index, "r");
+ int r = (int)L.ToNumber(-1);
+ L.Pop(1);
+
+ L.GetField(index, "g");
+ int g = (int)L.ToNumber(-1);
+ L.Pop(1);
+
+ L.GetField(index, "b");
+ int b = (int)L.ToNumber(-1);
+ L.Pop(1);
+
+ return Color.FromArgb(r, g, b);
+ }
+ else if (L.IsString(index))
+ {
+ string colorName = L.ToString(index).ToLower();
+ return colorName switch
+ {
+ "red" => Color.Red,
+ "green" => Color.Green,
+ "blue" => Color.Blue,
+ "yellow" => Color.Yellow,
+ "orange" => Color.Orange,
+ "purple" => Color.Purple,
+ "pink" => Color.Pink,
+ "black" => Color.Black,
+ "white" => Color.White,
+ "gray" => Color.Gray,
+ "lightgray" => Color.LightGray,
+ "darkgray" => Color.DarkGray,
+ "cyan" => Color.Cyan,
+ "magenta" => Color.Magenta,
+ "lime" => Color.Lime,
+ "brown" => Color.Brown,
+ _ => Color.White
+ };
+ }
+ else
+ {
+ return Color.White;
+ }
+ }
+ }
+}
diff --git a/Gui/UILib/TextBox.cs b/Gui/UILib/TextBox.cs
index b6b3481..6c93d01 100644
--- a/Gui/UILib/TextBox.cs
+++ b/Gui/UILib/TextBox.cs
@@ -345,11 +345,18 @@ namespace CMLeonOS.Gui.UILib
return;
}
- if (markedLinesBegin == -1 || markedLinesEnd == -1) return;
-
AutoScroll();
- for (int i = markedLinesBegin; i <= markedLinesEnd; i++)
+ int startLine = markedLinesBegin;
+ int endLine = markedLinesEnd;
+
+ if (startLine == -1 || endLine == -1)
+ {
+ startLine = (scrollY / fontHeight);
+ endLine = Math.Min(lines.Count - 1, ((scrollY + Height) / fontHeight));
+ }
+
+ for (int i = startLine; i <= endLine; i++)
{
int lineY = (i * fontHeight) - scrollY;
if (lineY < 0) continue;
diff --git a/LuaApps/Hello.lua b/LuaApps/Hello.lua
new file mode 100644
index 0000000..3155242
--- /dev/null
+++ b/LuaApps/Hello.lua
@@ -0,0 +1,7 @@
+local window = gui.createWindow("Hello", 400, 300)
+
+gui.clearWindow(window, "white")
+
+gui.drawText(window, "Hello world!", "black", 10, 10)
+
+gui.updateWindow(window)
diff --git a/docs/cmleonos/docs/.vuepress/config.js b/docs/cmleonos/docs/.vuepress/config.js
index 8dc56a8..52800ad 100644
--- a/docs/cmleonos/docs/.vuepress/config.js
+++ b/docs/cmleonos/docs/.vuepress/config.js
@@ -6,7 +6,7 @@ export default defineUserConfig({
lang: 'zh-CN',
title: 'CMLeonOS官方文档站',
- description: 'CMLeonOS是一个基于微内核架构的操作系统,它的目标是提供一个简单、可靠、安全的操作系统环境。',
+ description: 'CMLeonOS是一个x86架构64位操作系统,它的目标是提供一个简单、可靠、安全的操作系统环境。',
theme: defaultTheme({
// logo: 'https://vuejs.press/images/hero.png',
diff --git a/docs/cmleonos/docs/lua.md b/docs/cmleonos/docs/lua.md
index dcae27a..3c4968e 100644
--- a/docs/cmleonos/docs/lua.md
+++ b/docs/cmleonos/docs/lua.md
@@ -1230,6 +1230,140 @@ local jsonStr = json.stringify(data)
print(jsonStr)
```
+---
+## GUI 库 (gui)
+
+### gui.createWindow(title, x, y, width, height)
+创建一个窗口。
+
+```lua
+local window = gui.createWindow("My Window", 100, 100, 400, 300)
+```
+
+**参数**:
+- `title` - 窗口标题
+- `x` - 窗口左上角 X 坐标
+- `y` - 窗口左上角 Y 坐标
+- `width` - 窗口宽度
+- `height` - 窗口高度
+
+### gui.createButton(parent, text, x, y, width, height, callback)
+创建一个按钮。
+
+```lua
+local button = gui.createButton(window, "Click Me", 10, 10, 100, 30, function()
+ print("Button clicked!")
+end)
+```
+
+**参数**:
+- `parent` - 父窗口
+- `text` - 按钮文本
+- `x` - 按钮左上角 X 坐标
+- `y` - 按钮左上角 Y 坐标
+- `width` - 按钮宽度
+- `height` - 按钮高度
+- `callback` - 点击回调函数
+
+### gui.createLabel(parent, text, x, y)
+创建一个标签。
+
+```lua
+local label = gui.createLabel(window, "Hello, World!", 10, 50)
+```
+
+**参数**:
+- `parent` - 父窗口
+- `text` - 标签文本
+- `x` - 标签左上角 X 坐标
+- `y` - 标签左上角 Y 坐标
+
+### gui.createTextBox(parent, x, y, width, height)
+创建一个文本框。
+
+```lua
+local textbox = gui.createTextBox(window, 10, 80, 200, 25)
+```
+
+**参数**:
+- `parent` - 父窗口
+- `x` - 文本框左上角 X 坐标
+- `y` - 文本框左上角 Y 坐标
+- `width` - 文本框宽度
+- `height` - 文本框高度
+
+### gui.getText(textbox)
+获取文本框的内容。
+
+```lua
+local text = gui.getText(textbox)
+print(text)
+```
+
+### gui.setText(textbox, text)
+设置文本框的内容。
+
+```lua
+gui.setText(textbox, "New text")
+```
+
+### gui.show(window)
+显示窗口。
+
+```lua
+gui.show(window)
+```
+
+### gui.hide(window)
+隐藏窗口。
+
+```lua
+gui.hide(window)
+```
+
+### gui.close(window)
+关闭窗口。
+
+```lua
+gui.close(window)
+```
+
+### gui.setMessageLoop(callback)
+设置消息循环回调函数。
+
+```lua
+gui.setMessageLoop(function()
+ -- 处理消息循环
+end)
+```
+
+### gui.alert(message)
+显示警告对话框。
+
+```lua
+gui.alert("Operation completed!")
+```
+
+### gui.confirm(message)
+显示确认对话框,返回 true 或 false。
+
+```lua
+local result = gui.confirm("Are you sure?")
+if result then
+ print("User confirmed")
+else
+ print("User cancelled")
+end
+```
+
+### gui.prompt(message, default)
+显示输入对话框,返回用户输入的字符串。
+
+```lua
+local input = gui.prompt("Enter your name:", "John")
+print("Hello, " .. input)
+```
+
---
## 包库 (package)