mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 18:58:40 +00:00
BrewOS 1.40 Beta
BrewOS 1.31 > BrewOS 1.40 Brewkernel 2.3.0 Alpha > Brewkernel 2.3.1 Beta This update is a feature focused update. It features loads of quality of life and major UX improvements. New features: -Drag and drop for files and applications (shortcuts for apps can be made by dragging an app from the start menu into the desktop) -Customizable desktop (auto align, snap to grid -Recycle bin (rm in the CMD skips this)
This commit is contained in:
parent
8e3202f6d8
commit
4c21e732fc
72 changed files with 2365 additions and 488 deletions
|
|
@ -1,4 +1,5 @@
|
|||
# Brew OS 1.20 Alpha
|
||||
# Brew OS 1.40 Beta
|
||||
BrewOS is now in a Beta stage as i have brought over all apps from brewkernel and have made the DE a lot more usable and stable.
|
||||
|
||||
## Brewkernel is now BrewOS!
|
||||
Brewkernel will from now on be deprecated as it's core became too messy. I have built a less bloated kernel and wrote a DE above it, which is why it is now an OS instead of a kernel (in my opinion).
|
||||
|
|
@ -9,12 +10,16 @@ Brew Kernel is a simple x86_64 hobbyist operating system.
|
|||
It features a DE (and WM), a FAT32 filesystem, customizable UI and much much more!
|
||||
|
||||
## Features
|
||||
- Drag and drop mouse centered UI
|
||||
- Customizable UI
|
||||
- Basic Networking Stack
|
||||
- Brew WM
|
||||
- Fat 32 FS
|
||||
- 64-bit long mode support
|
||||
- Multiboot2 compliant
|
||||
- Text editor
|
||||
- Markdown Viewer
|
||||
- Minesweeper
|
||||
- IDT
|
||||
- Ability to run on actual x86_64 hardware
|
||||
- CLI
|
||||
|
|
|
|||
BIN
brewos.iso
BIN
brewos.iso
Binary file not shown.
BIN
build/about.o
BIN
build/about.o
Binary file not shown.
BIN
build/brewos.elf
BIN
build/brewos.elf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/cmd.o
BIN
build/cmd.o
Binary file not shown.
Binary file not shown.
BIN
build/dns.o
BIN
build/dns.o
Binary file not shown.
BIN
build/e1000.o
BIN
build/e1000.o
Binary file not shown.
BIN
build/editor.o
BIN
build/editor.o
Binary file not shown.
BIN
build/explorer.o
BIN
build/explorer.o
Binary file not shown.
BIN
build/fat32.o
BIN
build/fat32.o
Binary file not shown.
BIN
build/graphics.o
BIN
build/graphics.o
Binary file not shown.
BIN
build/http.o
BIN
build/http.o
Binary file not shown.
BIN
build/icmp.o
BIN
build/icmp.o
Binary file not shown.
BIN
build/idt.o
BIN
build/idt.o
Binary file not shown.
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
build/markdown.o
BIN
build/markdown.o
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/network.o
BIN
build/network.o
Binary file not shown.
BIN
build/notepad.o
BIN
build/notepad.o
Binary file not shown.
BIN
build/pci.o
BIN
build/pci.o
Binary file not shown.
BIN
build/platform.o
BIN
build/platform.o
Binary file not shown.
BIN
build/ps2.o
BIN
build/ps2.o
Binary file not shown.
BIN
build/rtc.o
BIN
build/rtc.o
Binary file not shown.
BIN
build/tcp.o
BIN
build/tcp.o
Binary file not shown.
BIN
build/vm.o
BIN
build/vm.o
Binary file not shown.
BIN
build/wm.o
BIN
build/wm.o
Binary file not shown.
Binary file not shown.
|
|
@ -35,8 +35,8 @@ static void about_paint(Window *win) {
|
|||
|
||||
// Version info
|
||||
draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK);
|
||||
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.30", COLOR_BLACK);
|
||||
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.0", COLOR_BLACK);
|
||||
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.40", COLOR_BLACK);
|
||||
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
|
||||
|
||||
// Copyright
|
||||
draw_string(offset_x, offset_y + 150, "(C) 2026 boreddevnl.", COLOR_BLACK);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
void cli_cmd_brewver(char *args) {
|
||||
(void)args;
|
||||
cli_write("BrewOS v1.30 Alpha\n");
|
||||
cli_write("BrewOS Kernel V2.3.0 Pre-Alpha\n");
|
||||
cli_write("BrewOS v1.40 Beta\n");
|
||||
cli_write("BrewOS Kernel V2.3.1 Beta\n");
|
||||
}
|
||||
|
|
|
|||
193
src/kernel/cmd.c
193
src/kernel/cmd.c
|
|
@ -158,8 +158,6 @@ static void cmd_set_line_content(const char *str) {
|
|||
}
|
||||
}
|
||||
|
||||
// Manual and license pages are now in the individual command files
|
||||
|
||||
// --- Terminal Emulation ---
|
||||
|
||||
static void cmd_scroll_up() {
|
||||
|
|
@ -293,8 +291,8 @@ void pager_wrap_content(const char **lines, int count) {
|
|||
int chunk_len = remaining;
|
||||
if (chunk_len > CMD_COLS) chunk_len = CMD_COLS;
|
||||
|
||||
// If we are cutting a word, backtrack to last space
|
||||
if (chunk_len < remaining) { // Only check if we are actually wrapping
|
||||
// If cutting a word, backtrack to last space
|
||||
if (chunk_len < remaining) { // Only check if actually wrapping
|
||||
int split_point = chunk_len;
|
||||
while (split_point > 0 && line[processed + split_point] != ' ') {
|
||||
split_point--;
|
||||
|
|
@ -328,6 +326,45 @@ void pager_set_mode(void) {
|
|||
current_mode = MODE_PAGER;
|
||||
}
|
||||
|
||||
// Internal LS command to avoid stack overflow in external module
|
||||
static void internal_cmd_ls(char *args) {
|
||||
char path[256];
|
||||
if (args && *args) {
|
||||
int i=0;
|
||||
while(args[i] && i < 255) { path[i] = args[i]; i++; }
|
||||
path[i] = 0;
|
||||
} else {
|
||||
path[0] = '.'; path[1] = 0;
|
||||
}
|
||||
|
||||
int max_files = 64;
|
||||
FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(max_files * sizeof(FAT32_FileInfo));
|
||||
if (!files) {
|
||||
cmd_write("Error: Out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int count = fat32_list_directory(path, files, max_files);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (files[i].is_directory) {
|
||||
cmd_write("[DIR] ");
|
||||
} else {
|
||||
cmd_write("[FILE] ");
|
||||
}
|
||||
|
||||
cmd_write(files[i].name);
|
||||
if (!files[i].is_directory) {
|
||||
cmd_write(" ");
|
||||
cmd_write_int(files[i].size);
|
||||
cmd_write("b");
|
||||
}
|
||||
cmd_write("\n");
|
||||
}
|
||||
|
||||
kfree(files);
|
||||
}
|
||||
|
||||
// --- Commands (now delegated to cli_apps/) ---
|
||||
|
||||
// Command dispatch table
|
||||
|
|
@ -374,8 +411,8 @@ static const CommandEntry commands[] = {
|
|||
{"cd", cli_cmd_cd},
|
||||
{"PWD", cli_cmd_pwd},
|
||||
{"pwd", cli_cmd_pwd},
|
||||
{"LS", cli_cmd_ls},
|
||||
{"ls", cli_cmd_ls},
|
||||
{"LS", internal_cmd_ls},
|
||||
{"ls", internal_cmd_ls},
|
||||
{"MKDIR", cli_cmd_mkdir},
|
||||
{"mkdir", cli_cmd_mkdir},
|
||||
{"RM", cli_cmd_rm},
|
||||
|
|
@ -895,12 +932,26 @@ void cmd_reset(void) {
|
|||
}
|
||||
|
||||
static void create_test_files(void) {
|
||||
fat32_mkdir("Documents");
|
||||
fat32_mkdir("Projects");
|
||||
fat32_mkdir("Documents/Important");
|
||||
fat32_mkdir("Apps");
|
||||
if (!fat32_exists("Documents")) fat32_mkdir("Documents");
|
||||
if (!fat32_exists("Projects")) fat32_mkdir("Projects");
|
||||
if (!fat32_exists("Documents/Important")) fat32_mkdir("Documents/Important");
|
||||
if (!fat32_exists("Apps")) fat32_mkdir("Apps");
|
||||
if (!fat32_exists("Desktop")) fat32_mkdir("Desktop");
|
||||
if (!fat32_exists("RecycleBin")) fat32_mkdir("RecycleBin");
|
||||
|
||||
FAT32_FileHandle *fh = fat32_open("README.md", "w");
|
||||
// Create Desktop Shortcuts
|
||||
FAT32_FileHandle *fh;
|
||||
fh = fat32_open("Desktop/Explorer.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Notepad.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Calculator.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Minesweeper.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Control Panel.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Terminal.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/About.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
fh = fat32_open("Desktop/Recycle Bin.shortcut", "w"); if(fh) fat32_close(fh);
|
||||
|
||||
// Always try to write README to ensure content exists
|
||||
fh = fat32_open("README.md", "w");
|
||||
if (fh) {
|
||||
const char *content =
|
||||
"# Brew OS 1.01 Alpha\n\n"
|
||||
|
|
@ -992,8 +1043,8 @@ static void create_test_files(void) {
|
|||
"The above attribution requirements are informational and intended to\n"
|
||||
"ensure proper credit is given. They do not alter or supersede the\n"
|
||||
"terms of the GNU General Public License (GPL), which governs this work.\n";
|
||||
fat32_write(fh, (void *)content, cmd_strlen(content));
|
||||
fat32_close(fh);
|
||||
fat32_write(fh, (void *)content, cmd_strlen(content));
|
||||
fat32_close(fh);
|
||||
}
|
||||
|
||||
fh = fat32_open("Apps/README.md", "w");
|
||||
|
|
@ -1001,7 +1052,7 @@ static void create_test_files(void) {
|
|||
const char *content =
|
||||
"# All compiled C files in this directory are openable from any other directory by typing in the name of the compiled file by typing in the name of the compiled file.\n\n"
|
||||
"The c file 'wordofgod.c' contains a C program similar to one in TempleOS, which Terry A. Davis (RIP) saw as 'words from god' telling him what to do with his kernel.\n"
|
||||
"I made this file as a tribute to him, as he also inspired me to create this project in '24. If you want to run it you simply do cc (or compc) wordofgod.c and then run ./wordofgod \n";
|
||||
"I made this file as a tribute to him, as he also inspired me to create this project in '24. If you want to run it you simply do cc (or compc) wordgod.c and then run ./wordgod \n";
|
||||
fat32_write(fh, (void *)content, cmd_strlen(content));
|
||||
fat32_close(fh);
|
||||
}
|
||||
|
|
@ -1024,74 +1075,60 @@ static void create_test_files(void) {
|
|||
|
||||
fh = fat32_open("Apps/wordofgod.c", "w");
|
||||
if (fh) {
|
||||
char *h = "int main(){int l;l=malloc(1200);";
|
||||
fat32_write(fh, h, cmd_strlen(h));
|
||||
char *w1 = "poke(l+0,\"In \");poke(l+4,\"the \");poke(l+8,\"beginning \");poke(l+12,\"God \");poke(l+16,\"created \");poke(l+20,\"heaven \");poke(l+24,\"and \");poke(l+28,\"earth \");poke(l+32,\"light \");poke(l+36,\"darkness \");";
|
||||
fat32_write(fh, w1, cmd_strlen(w1));
|
||||
char *w2 = "poke(l+40,\"day \");poke(l+44,\"night \");poke(l+48,\"waters \");poke(l+52,\"firmament \");poke(l+56,\"evening \");poke(l+60,\"morning \");poke(l+64,\"land \");poke(l+68,\"seas \");poke(l+72,\"grass \");poke(l+76,\"herb \");";
|
||||
fat32_write(fh, w2, cmd_strlen(w2));
|
||||
char *w3 = "poke(l+80,\"seed \");poke(l+84,\"fruit \");poke(l+88,\"tree \");poke(l+92,\"sun \");poke(l+96,\"moon \");poke(l+100,\"stars \");poke(l+104,\"signs \");poke(l+108,\"seasons \");poke(l+112,\"days \");poke(l+116,\"years \");";
|
||||
fat32_write(fh, w3, cmd_strlen(w3));
|
||||
char *w4 = "poke(l+120,\"creature \");poke(l+124,\"life \");poke(l+128,\"fowl \");poke(l+132,\"whales \");poke(l+136,\"cattle \");poke(l+140,\"creeping \");poke(l+144,\"beast \");poke(l+148,\"man \");poke(l+152,\"image \");poke(l+156,\"likeness \");";
|
||||
fat32_write(fh, w4, cmd_strlen(w4));
|
||||
char *w5 = "poke(l+160,\"dominion \");poke(l+164,\"fish \");poke(l+168,\"air \");poke(l+172,\"every \");poke(l+176,\"CIA \");poke(l+180,\"meat \");poke(l+184,\"holy \");poke(l+188,\"rest \");poke(l+192,\"dust \");poke(l+196,\"breath \");";
|
||||
fat32_write(fh, w5, cmd_strlen(w5));
|
||||
char *w6 = "poke(l+200,\"soul \");poke(l+204,\"garden \");poke(l+208,\"east \");poke(l+212,\"Eden \");poke(l+216,\"ground \");poke(l+220,\"sight \");poke(l+224,\"good \");poke(l+228,\"evil \");poke(l+232,\"river \");poke(l+236,\"gold \");";
|
||||
fat32_write(fh, w6, cmd_strlen(w6));
|
||||
char *w7 = "poke(l+240,\"stone \");poke(l+244,\"woman \");poke(l+248,\"wife \");poke(l+252,\"flesh \");poke(l+256,\"bone \");poke(l+260,\"naked \");poke(l+264,\"serpent \");poke(l+268,\"subtle \");poke(l+272,\"eat \");poke(l+276,\"eyes \");";
|
||||
fat32_write(fh, w7, cmd_strlen(w7));
|
||||
char *w8 = "poke(l+280,\"wise \");poke(l+284,\"cool \");poke(l+288,\"voice \");poke(l+292,\"fear \");poke(l+296,\"hid \");poke(l+300,\"cursed \");poke(l+304,\"belly \");poke(l+308,\"enmity \");poke(l+312,\"sorrow \");poke(l+316,\"conception \");";
|
||||
fat32_write(fh, w8, cmd_strlen(w8));
|
||||
char *w9 = "poke(l+320,\"children \");poke(l+324,\"desire \");poke(l+328,\"husband \");poke(l+332,\"thorns \");poke(l+336,\"thistles \");poke(l+340,\"sweat \");poke(l+344,\"bread \");poke(l+348,\"mother \");poke(l+352,\"skin \");poke(l+356,\"coats \");";
|
||||
fat32_write(fh, w9, cmd_strlen(w9));
|
||||
char *w10 = "poke(l+360,\"cherubims \");poke(l+364,\"sword \");poke(l+368,\"gate \");poke(l+372,\"offering \");poke(l+376,\"respect \");poke(l+380,\"sin \");poke(l+384,\"door \");poke(l+388,\"blood \");poke(l+392,\"brother \");poke(l+396,\"keeper \");";
|
||||
fat32_write(fh, w10, cmd_strlen(w10));
|
||||
char *w11 = "poke(l+400,\"voice \");poke(l+404,\"heard \");poke(l+408,\"walking \");poke(l+412,\"cool \");poke(l+416,\"day \");poke(l+420,\"where \");poke(l+424,\"art \");poke(l+428,\"thou \");poke(l+432,\"told \");poke(l+436,\"thee \");";
|
||||
fat32_write(fh, w11, cmd_strlen(w11));
|
||||
char *w12 = "poke(l+440,\"hast \");poke(l+444,\"eaten \");poke(l+448,\"tree \");poke(l+452,\"whereof \");poke(l+456,\"commanded \");poke(l+460,\"shouldest \");poke(l+464,\"not \");poke(l+468,\"eat \");poke(l+472,\"gave \");poke(l+476,\"me \");";
|
||||
fat32_write(fh, w12, cmd_strlen(w12));
|
||||
char *w13 = "poke(l+480,\"beguiled \");poke(l+484,\"belly \");poke(l+488,\"go \");poke(l+492,\"dust \");poke(l+496,\"shalt \");poke(l+500,\"eat \");poke(l+504,\"days \");poke(l+508,\"life \");poke(l+512,\"put \");poke(l+516,\"enmity \");";
|
||||
fat32_write(fh, w13, cmd_strlen(w13));
|
||||
char *w14 = "poke(l+520,\"between \");poke(l+524,\"seed \");poke(l+528,\"bruise \");poke(l+532,\"head \");poke(l+536,\"heel \");poke(l+540,\"multiply \");poke(l+544,\"sorrow \");poke(l+548,\"conception \");poke(l+552,\"forth \");poke(l+556,\"children \");";
|
||||
fat32_write(fh, w14, cmd_strlen(w14));
|
||||
char *w15 = "poke(l+560,\"desire \");poke(l+564,\"rule \");poke(l+568,\"over \");poke(l+572,\"sake \");poke(l+576,\"sweat \");poke(l+580,\"face \");poke(l+584,\"till \");poke(l+588,\"return \");poke(l+592,\"ground \");poke(l+596,\"taken \");";
|
||||
fat32_write(fh, w15, cmd_strlen(w15));
|
||||
char *w16 = "poke(l+600,\"mother \");poke(l+604,\"living \");poke(l+608,\"coats \");poke(l+612,\"skins \");poke(l+616,\"clothed \");poke(l+620,\"become \");poke(l+624,\"one \");poke(l+628,\"us \");poke(l+632,\"know \");poke(l+636,\"good \");";
|
||||
fat32_write(fh, w16, cmd_strlen(w16));
|
||||
char *w17 = "poke(l+640,\"evil \");poke(l+644,\"lest \");poke(l+648,\"put \");poke(l+652,\"hand \");poke(l+656,\"take \");poke(l+660,\"live \");poke(l+664,\"ever \");poke(l+668,\"sent \");poke(l+672,\"garden \");poke(l+676,\"eden \");";
|
||||
fat32_write(fh, w17, cmd_strlen(w17));
|
||||
char *w18 = "poke(l+680,\"flaming \");poke(l+684,\"sword \");poke(l+688,\"turned \");poke(l+692,\"way \");poke(l+696,\"knew \");poke(l+700,\"conceived \");poke(l+704,\"bare \");poke(l+708,\"cain \");poke(l+712,\"said \");poke(l+716,\"gotten \");";
|
||||
fat32_write(fh, w18, cmd_strlen(w18));
|
||||
char *w19 = "poke(l+720,\"lord \");poke(l+724,\"again \");poke(l+728,\"abel \");poke(l+732,\"sheep \");poke(l+736,\"tiller \");poke(l+740,\"process \");poke(l+744,\"time \");poke(l+748,\"pass \");poke(l+752,\"brought \");poke(l+756,\"fruit \");";
|
||||
fat32_write(fh, w19, cmd_strlen(w19));
|
||||
char *w20 = "poke(l+760,\"offering \");poke(l+764,\"firstlings \");poke(l+768,\"flock \");poke(l+772,\"fat \");poke(l+776,\"thereof \");poke(l+780,\"respect \");poke(l+784,\"wroth \");poke(l+788,\"countenance \");poke(l+792,\"fallen \");poke(l+796,\"well \");";
|
||||
fat32_write(fh, w20, cmd_strlen(w20));
|
||||
char *w21 = "poke(l+800,\"accepted \");poke(l+804,\"not \");poke(l+808,\"sin \");poke(l+812,\"lieth \");poke(l+816,\"door \");poke(l+820,\"unto \");poke(l+824,\"rule \");poke(l+828,\"talked \");poke(l+832,\"field \");poke(l+836,\"rose \");";
|
||||
fat32_write(fh, w21, cmd_strlen(w21));
|
||||
char *w22 = "poke(l+840,\"slew \");poke(l+844,\"done \");poke(l+848,\"crieth \");poke(l+852,\"mouth \");poke(l+856,\"receive \");poke(l+860,\"strength \");poke(l+864,\"fugitive \");poke(l+868,\"vagabond \");poke(l+872,\"punishment \");poke(l+876,\"greater \");";
|
||||
fat32_write(fh, w22, cmd_strlen(w22));
|
||||
char *w23 = "poke(l+880,\"bear \");poke(l+884,\"driven \");poke(l+888,\"hid \");poke(l+892,\"findeth \");poke(l+896,\"slay \");poke(l+900,\"vengeance \");poke(l+904,\"sevenfold \");poke(l+908,\"mark \");poke(l+912,\"finding \");poke(l+916,\"kill \");";
|
||||
fat32_write(fh, w23, cmd_strlen(w23));
|
||||
char *w24 = "poke(l+920,\"presence \");poke(l+924,\"dwelt \");poke(l+928,\"nod \");poke(l+932,\"enoch \");poke(l+936,\"city \");poke(l+940,\"irad \");poke(l+944,\"mehujael \");poke(l+948,\"methusael \");poke(l+952,\"lamech \");poke(l+956,\"adah \");";
|
||||
fat32_write(fh, w24, cmd_strlen(w24));
|
||||
char *w25 = "poke(l+960,\"zillah \");poke(l+964,\"jabal \");poke(l+968,\"tent \");poke(l+972,\"cattle \");poke(l+976,\"jubal \");poke(l+980,\"harp \");poke(l+984,\"organ \");poke(l+988,\"tubalcain \");poke(l+992,\"brass \");poke(l+996,\"iron \");";
|
||||
fat32_write(fh, w25, cmd_strlen(w25));
|
||||
char *w26 = "poke(l+1000,\"naamah \");poke(l+1004,\"wives \");poke(l+1008,\"hear \");poke(l+1012,\"speech \");poke(l+1016,\"hearken \");poke(l+1020,\"young \");poke(l+1024,\"hurt \");poke(l+1028,\"wounding \");poke(l+1032,\"avenged \");poke(l+1036,\"seventy \");";
|
||||
fat32_write(fh, w26, cmd_strlen(w26));
|
||||
char *w27 = "poke(l+1040,\"seth \");poke(l+1044,\"appointed \");poke(l+1048,\"enos \");poke(l+1052,\"began \");poke(l+1056,\"call \");poke(l+1060,\"name \");poke(l+1064,\"generations \");poke(l+1068,\"adam \");poke(l+1072,\"likeness \");poke(l+1076,\"blessed \");";
|
||||
fat32_write(fh, w27, cmd_strlen(w27));
|
||||
char *w28 = "poke(l+1080,\"begat \");poke(l+1084,\"sons \");poke(l+1088,\"daughters \");poke(l+1092,\"lived \");poke(l+1096,\"died \");poke(l+1100,\"cainan \");poke(l+1104,\"mahalaleel \");poke(l+1108,\"jared \");poke(l+1112,\"walked \");poke(l+1116,\"three \");";
|
||||
fat32_write(fh, w28, cmd_strlen(w28));
|
||||
char *w29 = "poke(l+1120,\"hundred \");poke(l+1124,\"sixty \");poke(l+1128,\"five \");poke(l+1132,\"methuselah \");poke(l+1136,\"lamech \");poke(l+1140,\"noah \");poke(l+1144,\"comfort \");poke(l+1148,\"work \");poke(l+1152,\"toil \");poke(l+1156,\"hands \");";
|
||||
fat32_write(fh, w29, cmd_strlen(w29));
|
||||
char *w30 = "poke(l+1160,\"shem \");poke(l+1164,\"ham \");poke(l+1168,\"japheth \");poke(l+1172,\"men \");poke(l+1176,\"daughters \");poke(l+1180,\"born \");poke(l+1184,\"fair \");poke(l+1188,\"chose \");poke(l+1192,\"spirit \");poke(l+1196,\"strive \");";
|
||||
fat32_write(fh, w30, cmd_strlen(w30));
|
||||
char *e = "int c;int r;r=abs(rand());r=r-(r/5)*5;c=14+r;int i;i=0;while(i<c){int x;x=abs(rand());x=x-(x/300)*300;int w;w=peek(l+x*4);print_str(w);i=i+1;}nl();}";
|
||||
fat32_write(fh, e, cmd_strlen(e));
|
||||
// Buffer the entire file content to write in one go
|
||||
// This prevents issues with multiple small writes causing truncation
|
||||
char *buf = (char*)kmalloc(8192);
|
||||
if (buf) {
|
||||
int p = 0;
|
||||
const char *strs[] = {
|
||||
"int main(){int l;l=malloc(1200);",
|
||||
"poke(l+0,\"In \");poke(l+4,\"the \");poke(l+8,\"beginning \");poke(l+12,\"God \");poke(l+16,\"created \");poke(l+20,\"heaven \");poke(l+24,\"and \");poke(l+28,\"earth \");poke(l+32,\"light \");poke(l+36,\"darkness \");",
|
||||
"poke(l+40,\"day \");poke(l+44,\"night \");poke(l+48,\"waters \");poke(l+52,\"firmament \");poke(l+56,\"evening \");poke(l+60,\"morning \");poke(l+64,\"land \");poke(l+68,\"seas \");poke(l+72,\"grass \");poke(l+76,\"herb \");",
|
||||
"poke(l+80,\"seed \");poke(l+84,\"fruit \");poke(l+88,\"tree \");poke(l+92,\"sun \");poke(l+96,\"moon \");poke(l+100,\"stars \");poke(l+104,\"signs \");poke(l+108,\"seasons \");poke(l+112,\"days \");poke(l+116,\"years \");",
|
||||
"poke(l+120,\"creature \");poke(l+124,\"life \");poke(l+128,\"fowl \");poke(l+132,\"whales \");poke(l+136,\"cattle \");poke(l+140,\"creeping \");poke(l+144,\"beast \");poke(l+148,\"man \");poke(l+152,\"image \");poke(l+156,\"likeness \");",
|
||||
"poke(l+160,\"dominion \");poke(l+164,\"fish \");poke(l+168,\"air \");poke(l+172,\"every \");poke(l+176,\"CIA \");poke(l+180,\"meat \");poke(l+184,\"holy \");poke(l+188,\"rest \");poke(l+192,\"dust \");poke(l+196,\"breath \");",
|
||||
"poke(l+200,\"soul \");poke(l+204,\"garden \");poke(l+208,\"east \");poke(l+212,\"Eden \");poke(l+216,\"ground \");poke(l+220,\"sight \");poke(l+224,\"good \");poke(l+228,\"evil \");poke(l+232,\"river \");poke(l+236,\"gold \");",
|
||||
"poke(l+240,\"stone \");poke(l+244,\"woman \");poke(l+248,\"wife \");poke(l+252,\"flesh \");poke(l+256,\"bone \");poke(l+260,\"naked \");poke(l+264,\"serpent \");poke(l+268,\"subtle \");poke(l+272,\"eat \");poke(l+276,\"eyes \");",
|
||||
"poke(l+280,\"wise \");poke(l+284,\"cool \");poke(l+288,\"voice \");poke(l+292,\"fear \");poke(l+296,\"hid \");poke(l+300,\"cursed \");poke(l+304,\"belly \");poke(l+308,\"enmity \");poke(l+312,\"sorrow \");poke(l+316,\"conception \");",
|
||||
"poke(l+320,\"children \");poke(l+324,\"desire \");poke(l+328,\"husband \");poke(l+332,\"thorns \");poke(l+336,\"thistles \");poke(l+340,\"sweat \");poke(l+344,\"bread \");poke(l+348,\"mother \");poke(l+352,\"skin \");poke(l+356,\"coats \");",
|
||||
"poke(l+360,\"cherubims \");poke(l+364,\"sword \");poke(l+368,\"gate \");poke(l+372,\"offering \");poke(l+376,\"respect \");poke(l+380,\"sin \");poke(l+384,\"door \");poke(l+388,\"blood \");poke(l+392,\"brother \");poke(l+396,\"keeper \");",
|
||||
"poke(l+400,\"voice \");poke(l+404,\"heard \");poke(l+408,\"walking \");poke(l+412,\"cool \");poke(l+416,\"day \");poke(l+420,\"where \");poke(l+424,\"art \");poke(l+428,\"thou \");poke(l+432,\"told \");poke(l+436,\"thee \");",
|
||||
"poke(l+440,\"hast \");poke(l+444,\"eaten \");poke(l+448,\"tree \");poke(l+452,\"whereof \");poke(l+456,\"commanded \");poke(l+460,\"shouldest \");poke(l+464,\"not \");poke(l+468,\"eat \");poke(l+472,\"gave \");poke(l+476,\"me \");",
|
||||
"poke(l+480,\"beguiled \");poke(l+484,\"belly \");poke(l+488,\"go \");poke(l+492,\"dust \");poke(l+496,\"shalt \");poke(l+500,\"eat \");poke(l+504,\"days \");poke(l+508,\"life \");poke(l+512,\"put \");poke(l+516,\"enmity \");",
|
||||
"poke(l+520,\"between \");poke(l+524,\"seed \");poke(l+528,\"bruise \");poke(l+532,\"head \");poke(l+536,\"heel \");poke(l+540,\"multiply \");poke(l+544,\"sorrow \");poke(l+548,\"conception \");poke(l+552,\"forth \");poke(l+556,\"children \");",
|
||||
"poke(l+560,\"desire \");poke(l+564,\"rule \");poke(l+568,\"over \");poke(l+572,\"sake \");poke(l+576,\"sweat \");poke(l+580,\"face \");poke(l+584,\"till \");poke(l+588,\"return \");poke(l+592,\"ground \");poke(l+596,\"taken \");",
|
||||
"poke(l+600,\"mother \");poke(l+604,\"living \");poke(l+608,\"coats \");poke(l+612,\"skins \");poke(l+616,\"clothed \");poke(l+620,\"become \");poke(l+624,\"one \");poke(l+628,\"us \");poke(l+632,\"know \");poke(l+636,\"good \");",
|
||||
"poke(l+640,\"evil \");poke(l+644,\"lest \");poke(l+648,\"put \");poke(l+652,\"hand \");poke(l+656,\"take \");poke(l+660,\"live \");poke(l+664,\"ever \");poke(l+668,\"sent \");poke(l+672,\"garden \");poke(l+676,\"eden \");",
|
||||
"poke(l+680,\"flaming \");poke(l+684,\"sword \");poke(l+688,\"turned \");poke(l+692,\"way \");poke(l+696,\"knew \");poke(l+700,\"conceived \");poke(l+704,\"bare \");poke(l+708,\"cain \");poke(l+712,\"said \");poke(l+716,\"gotten \");",
|
||||
"poke(l+720,\"lord \");poke(l+724,\"again \");poke(l+728,\"abel \");poke(l+732,\"sheep \");poke(l+736,\"tiller \");poke(l+740,\"process \");poke(l+744,\"time \");poke(l+748,\"pass \");poke(l+752,\"brought \");poke(l+756,\"fruit \");",
|
||||
"poke(l+760,\"offering \");poke(l+764,\"firstlings \");poke(l+768,\"flock \");poke(l+772,\"fat \");poke(l+776,\"thereof \");poke(l+780,\"respect \");poke(l+784,\"wroth \");poke(l+788,\"countenance \");poke(l+792,\"fallen \");poke(l+796,\"well \");",
|
||||
"poke(l+800,\"accepted \");poke(l+804,\"not \");poke(l+808,\"sin \");poke(l+812,\"lieth \");poke(l+816,\"door \");poke(l+820,\"unto \");poke(l+824,\"rule \");poke(l+828,\"talked \");poke(l+832,\"field \");poke(l+836,\"rose \");",
|
||||
"poke(l+840,\"slew \");poke(l+844,\"done \");poke(l+848,\"crieth \");poke(l+852,\"mouth \");poke(l+856,\"receive \");poke(l+860,\"strength \");poke(l+864,\"fugitive \");poke(l+868,\"vagabond \");poke(l+872,\"punishment \");poke(l+876,\"greater \");",
|
||||
"poke(l+880,\"bear \");poke(l+884,\"driven \");poke(l+888,\"hid \");poke(l+892,\"findeth \");poke(l+896,\"slay \");poke(l+900,\"vengeance \");poke(l+904,\"sevenfold \");poke(l+908,\"mark \");poke(l+912,\"finding \");poke(l+916,\"kill \");",
|
||||
"poke(l+920,\"presence \");poke(l+924,\"dwelt \");poke(l+928,\"nod \");poke(l+932,\"enoch \");poke(l+936,\"city \");poke(l+940,\"irad \");poke(l+944,\"mehujael \");poke(l+948,\"methusael \");poke(l+952,\"lamech \");poke(l+956,\"adah \");",
|
||||
"poke(l+960,\"zillah \");poke(l+964,\"jabal \");poke(l+968,\"tent \");poke(l+972,\"cattle \");poke(l+976,\"jubal \");poke(l+980,\"harp \");poke(l+984,\"organ \");poke(l+988,\"tubalcain \");poke(l+992,\"brass \");poke(l+996,\"iron \");",
|
||||
"poke(l+1000,\"naamah \");poke(l+1004,\"wives \");poke(l+1008,\"hear \");poke(l+1012,\"speech \");poke(l+1016,\"hearken \");poke(l+1020,\"young \");poke(l+1024,\"hurt \");poke(l+1028,\"wounding \");poke(l+1032,\"avenged \");poke(l+1036,\"seventy \");",
|
||||
"poke(l+1040,\"seth \");poke(l+1044,\"appointed \");poke(l+1048,\"enos \");poke(l+1052,\"began \");poke(l+1056,\"call \");poke(l+1060,\"name \");poke(l+1064,\"generations \");poke(l+1068,\"adam \");poke(l+1072,\"likeness \");poke(l+1076,\"blessed \");",
|
||||
"poke(l+1080,\"begat \");poke(l+1084,\"sons \");poke(l+1088,\"daughters \");poke(l+1092,\"lived \");poke(l+1096,\"died \");poke(l+1100,\"cainan \");poke(l+1104,\"mahalaleel \");poke(l+1108,\"jared \");poke(l+1112,\"walked \");poke(l+1116,\"three \");",
|
||||
"poke(l+1120,\"hundred \");poke(l+1124,\"sixty \");poke(l+1128,\"five \");poke(l+1132,\"methuselah \");poke(l+1136,\"lamech \");poke(l+1140,\"noah \");poke(l+1144,\"comfort \");poke(l+1148,\"work \");poke(l+1152,\"toil \");poke(l+1156,\"hands \");",
|
||||
"poke(l+1160,\"shem \");poke(l+1164,\"ham \");poke(l+1168,\"japheth \");poke(l+1172,\"men \");poke(l+1176,\"daughters \");poke(l+1180,\"born \");poke(l+1184,\"fair \");poke(l+1188,\"chose \");poke(l+1192,\"spirit \");poke(l+1196,\"strive \");",
|
||||
"int c;int r;r=abs(rand());r=r-(r/5)*5;c=14+r;int i;i=0;while(i<c){int x;x=abs(rand());x=x-(x/300)*300;int w;w=peek(l+x*4);print_str(w);i=i+1;}nl();}",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i = 0; strs[i]; i++) {
|
||||
const char *s = strs[i];
|
||||
while (*s && p < 8191) buf[p++] = *s++;
|
||||
}
|
||||
|
||||
fat32_write(fh, buf, p);
|
||||
kfree(buf);
|
||||
}
|
||||
fat32_close(fh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cmd_init(void) {
|
||||
fat32_init(); // Init FAT32 filesystem
|
||||
create_test_files();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ Window win_control_panel;
|
|||
#define VIEW_MAIN 0
|
||||
#define VIEW_WALLPAPER 1
|
||||
#define VIEW_NETWORK 2
|
||||
#define VIEW_DESKTOP 3
|
||||
|
||||
static int current_view = VIEW_MAIN;
|
||||
static char rgb_r[4] = "";
|
||||
|
|
@ -197,6 +198,16 @@ static void control_panel_paint_main(Window *win) {
|
|||
draw_rect(offset_x + 23, net_offset_y + 5, 1, 11, 0xFFFFFFFF);
|
||||
|
||||
draw_string(offset_x + 40, net_offset_y + 8, "Network", 0xFF000000);
|
||||
|
||||
// Draw Desktop Settings Icon
|
||||
int desk_offset_y = net_offset_y + 35;
|
||||
// Folder icon style
|
||||
draw_rect(offset_x + 5, desk_offset_y + 2, 12, 4, COLOR_LTGRAY);
|
||||
draw_rect(offset_x + 5, desk_offset_y + 2, 12, 1, COLOR_BLACK);
|
||||
draw_rect(offset_x + 5, desk_offset_y + 6, 24, 14, 0xFFE0C060); // Tan folder
|
||||
draw_rect(offset_x + 5, desk_offset_y + 6, 24, 1, COLOR_BLACK);
|
||||
draw_rect(offset_x + 5, desk_offset_y + 6, 1, 14, COLOR_BLACK);
|
||||
draw_string(offset_x + 40, desk_offset_y + 8, "Desktop", 0xFF000000);
|
||||
}
|
||||
|
||||
static void control_panel_paint_wallpaper(Window *win) {
|
||||
|
|
@ -409,6 +420,54 @@ static void control_panel_paint_network(Window *win) {
|
|||
draw_button(offset_x, section_y, 80, 22, "Send", false);
|
||||
}
|
||||
|
||||
static void control_panel_paint_desktop(Window *win) {
|
||||
int offset_x = win->x + 8;
|
||||
int offset_y = win->y + 30;
|
||||
|
||||
// Back button
|
||||
draw_string(offset_x, offset_y, "< Back", 0xFF000080);
|
||||
draw_string(offset_x, offset_y + 25, "Desktop Settings:", 0xFF000000);
|
||||
|
||||
int section_y = offset_y + 50;
|
||||
|
||||
// Snap to Grid
|
||||
draw_rect(offset_x, section_y, 15, 15, 0xFFFFFFFF);
|
||||
draw_rect(offset_x, section_y, 15, 1, COLOR_BLACK);
|
||||
draw_rect(offset_x, section_y, 1, 15, COLOR_BLACK);
|
||||
draw_rect(offset_x + 14, section_y, 1, 15, COLOR_BLACK);
|
||||
draw_rect(offset_x, section_y + 14, 15, 1, COLOR_BLACK);
|
||||
if (desktop_snap_to_grid) draw_string(offset_x + 3, section_y + 3, "X", COLOR_BLACK);
|
||||
draw_string(offset_x + 25, section_y + 3, "Snap to Grid", COLOR_BLACK);
|
||||
|
||||
// Auto Align
|
||||
section_y += 25;
|
||||
draw_rect(offset_x, section_y, 15, 15, 0xFFFFFFFF);
|
||||
draw_rect(offset_x, section_y, 15, 1, COLOR_BLACK);
|
||||
draw_rect(offset_x, section_y, 1, 15, COLOR_BLACK);
|
||||
draw_rect(offset_x + 14, section_y, 1, 15, COLOR_BLACK);
|
||||
draw_rect(offset_x, section_y + 14, 15, 1, COLOR_BLACK);
|
||||
if (desktop_auto_align) draw_string(offset_x + 3, section_y + 3, "X", COLOR_BLACK);
|
||||
draw_string(offset_x + 25, section_y + 3, "Auto Align Icons", COLOR_BLACK);
|
||||
|
||||
// Max Rows
|
||||
section_y += 25;
|
||||
draw_string(offset_x, section_y + 3, "Apps per column:", COLOR_BLACK);
|
||||
draw_button(offset_x + 130, section_y, 20, 20, "-", false);
|
||||
char num[4]; num[0] = '0' + (desktop_max_rows_per_col / 10); num[1] = '0' + (desktop_max_rows_per_col % 10); num[2] = 0;
|
||||
if (num[0] == '0') { num[0] = num[1]; num[1] = 0; }
|
||||
draw_string(offset_x + 160, section_y + 5, num, COLOR_BLACK);
|
||||
draw_button(offset_x + 180, section_y, 20, 20, "+", false);
|
||||
|
||||
// Max Cols
|
||||
section_y += 25;
|
||||
draw_string(offset_x, section_y + 3, "Columns:", COLOR_BLACK);
|
||||
draw_button(offset_x + 130, section_y, 20, 20, "-", false);
|
||||
char num_c[4]; num_c[0] = '0' + (desktop_max_cols / 10); num_c[1] = '0' + (desktop_max_cols % 10); num_c[2] = 0;
|
||||
if (num_c[0] == '0') { num_c[0] = num_c[1]; num_c[1] = 0; }
|
||||
draw_string(offset_x + 160, section_y + 5, num_c, COLOR_BLACK);
|
||||
draw_button(offset_x + 180, section_y, 20, 20, "+", false);
|
||||
}
|
||||
|
||||
static void control_panel_paint(Window *win) {
|
||||
if (current_view == VIEW_MAIN) {
|
||||
control_panel_paint_main(win);
|
||||
|
|
@ -416,6 +475,8 @@ static void control_panel_paint(Window *win) {
|
|||
control_panel_paint_wallpaper(win);
|
||||
} else if (current_view == VIEW_NETWORK) {
|
||||
control_panel_paint_network(win);
|
||||
} else if (current_view == VIEW_DESKTOP) {
|
||||
control_panel_paint_desktop(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -440,6 +501,13 @@ static void control_panel_handle_click(Window *win, int x, int y) {
|
|||
current_view = VIEW_NETWORK;
|
||||
focused_field = -1;
|
||||
}
|
||||
|
||||
// Check desktop button
|
||||
int desk_offset_y = net_offset_y + 35;
|
||||
if (x >= offset_x + 5 && x < offset_x + 120 &&
|
||||
y >= desk_offset_y && y < desk_offset_y + 25) {
|
||||
current_view = VIEW_DESKTOP;
|
||||
}
|
||||
} else if (current_view == VIEW_WALLPAPER) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 30;
|
||||
|
|
@ -727,6 +795,73 @@ static void control_panel_handle_click(Window *win, int x, int y) {
|
|||
}
|
||||
return;
|
||||
}
|
||||
} else if (current_view == VIEW_DESKTOP) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 30;
|
||||
|
||||
// Back button
|
||||
if (x >= offset_x && x < offset_x + 40 && y >= offset_y && y < offset_y + 15) {
|
||||
current_view = VIEW_MAIN;
|
||||
return;
|
||||
}
|
||||
|
||||
int section_y = offset_y + 50;
|
||||
// Snap toggle
|
||||
if (x >= offset_x && x < offset_x + 150 && y >= section_y && y < section_y + 20) {
|
||||
desktop_snap_to_grid = !desktop_snap_to_grid;
|
||||
// If Snap is turned OFF, Auto Align must be OFF
|
||||
if (!desktop_snap_to_grid) {
|
||||
desktop_auto_align = false;
|
||||
}
|
||||
wm_refresh_desktop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto Align toggle
|
||||
section_y += 25;
|
||||
if (x >= offset_x && x < offset_x + 150 && y >= section_y && y < section_y + 20) {
|
||||
desktop_auto_align = !desktop_auto_align;
|
||||
// If Auto Align is turned ON, Snap must be ON
|
||||
if (desktop_auto_align) {
|
||||
desktop_snap_to_grid = true;
|
||||
}
|
||||
wm_refresh_desktop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Rows adjust
|
||||
section_y += 25;
|
||||
if (x >= offset_x + 130 && x < offset_x + 150 && y >= section_y && y < section_y + 20) {
|
||||
if (desktop_max_rows_per_col > 1) {
|
||||
if (desktop_max_cols * (desktop_max_rows_per_col - 1) < wm_get_desktop_icon_count()) {
|
||||
wm_show_message("Error", "Cannot reduce rows: too many files!");
|
||||
} else {
|
||||
desktop_max_rows_per_col--;
|
||||
wm_refresh_desktop();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x >= offset_x + 180 && x < offset_x + 200 && y >= section_y && y < section_y + 20) {
|
||||
if (desktop_max_rows_per_col < 15) desktop_max_rows_per_col++;
|
||||
wm_refresh_desktop();
|
||||
}
|
||||
|
||||
// Cols adjust
|
||||
section_y += 25;
|
||||
if (x >= offset_x + 130 && x < offset_x + 150 && y >= section_y && y < section_y + 20) {
|
||||
if (desktop_max_cols > 1) {
|
||||
if ((desktop_max_cols - 1) * desktop_max_rows_per_col < wm_get_desktop_icon_count()) {
|
||||
wm_show_message("Error", "Cannot reduce cols: too many files!");
|
||||
} else {
|
||||
desktop_max_cols--;
|
||||
wm_refresh_desktop();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x >= offset_x + 180 && x < offset_x + 200 && y >= section_y && y < section_y + 20) {
|
||||
if (desktop_max_cols < 20) desktop_max_cols++;
|
||||
wm_refresh_desktop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,5 +12,25 @@ extern Window win_markdown;
|
|||
|
||||
void explorer_init(void);
|
||||
void explorer_reset(void);
|
||||
void explorer_refresh(void);
|
||||
void explorer_clear_click_state(void);
|
||||
|
||||
// Drag and Drop support
|
||||
bool explorer_get_file_at(int screen_x, int screen_y, char *out_path, bool *is_dir);
|
||||
void explorer_import_file(const char *source_path);
|
||||
void explorer_import_file_to(const char *source_path, const char *dest_dir);
|
||||
|
||||
// Clipboard
|
||||
void explorer_clipboard_copy(const char *path);
|
||||
void explorer_clipboard_cut(const char *path);
|
||||
void explorer_clipboard_paste(const char *dest_dir);
|
||||
bool explorer_clipboard_has_content(void);
|
||||
|
||||
// File Operations
|
||||
bool explorer_delete_permanently(const char *path);
|
||||
bool explorer_delete_recursive(const char *path);
|
||||
void explorer_create_shortcut(const char *target_path);
|
||||
|
||||
void explorer_open_directory(const char *path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ static FileEntry files[MAX_FILES];
|
|||
static uint32_t next_cluster = 3; // Start after reserved clusters 0, 1, 2
|
||||
static FAT32_FileHandle open_handles[MAX_OPEN_HANDLES];
|
||||
static char current_dir[FAT32_MAX_PATH] = "/";
|
||||
static int desktop_file_limit = -1;
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
|
|
@ -208,6 +209,34 @@ static uint32_t allocate_cluster(void) {
|
|||
return cluster;
|
||||
}
|
||||
|
||||
// Check desktop limit
|
||||
static bool check_desktop_limit(const char *normalized_path) {
|
||||
if (desktop_file_limit < 0) return true;
|
||||
|
||||
// Check if path is directly in /Desktop (not subfolder)
|
||||
// Path should start with /Desktop/ and have no other slashes
|
||||
if (fs_strlen(normalized_path) > 9 &&
|
||||
normalized_path[0] == '/' &&
|
||||
normalized_path[1] == 'D' && normalized_path[2] == 'e' &&
|
||||
normalized_path[3] == 's' && normalized_path[4] == 'k' &&
|
||||
normalized_path[5] == 't' && normalized_path[6] == 'o' &&
|
||||
normalized_path[7] == 'p' && normalized_path[8] == '/') {
|
||||
|
||||
// Check for subfolders
|
||||
const char *p = normalized_path + 9;
|
||||
while (*p) {
|
||||
if (*p == '/') return true; // Subfolder, allow
|
||||
p++;
|
||||
}
|
||||
|
||||
// Count files in /Desktop
|
||||
FAT32_FileInfo info[256]; // Temp buffer
|
||||
int count = fat32_list_directory("/Desktop", info, 256);
|
||||
if (count >= desktop_file_limit) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// === Public API ===
|
||||
|
||||
void fat32_init(void) {
|
||||
|
|
@ -235,6 +264,10 @@ void fat32_init(void) {
|
|||
current_dir[1] = 0;
|
||||
}
|
||||
|
||||
void fat32_set_desktop_limit(int limit) {
|
||||
desktop_file_limit = limit;
|
||||
}
|
||||
|
||||
FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
||||
char normalized[FAT32_MAX_PATH];
|
||||
fat32_normalize_path(path, normalized);
|
||||
|
|
@ -249,6 +282,10 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
|||
} else if (mode[0] == 'w' || (mode[0] == 'a')) {
|
||||
// Write/append mode - create if not exists
|
||||
if (!entry) {
|
||||
if (!check_desktop_limit(normalized)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = find_free_entry();
|
||||
if (!entry) return NULL;
|
||||
|
||||
|
|
@ -355,7 +392,7 @@ int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) {
|
|||
int bytes_written = 0;
|
||||
const uint8_t *buf = (const uint8_t *)buffer;
|
||||
|
||||
// Check if we are at a cluster boundary from a previous write
|
||||
// Check for cluster boundary from a previous write
|
||||
if (handle->position > 0 && (handle->position % FAT32_CLUSTER_SIZE) == 0) {
|
||||
uint32_t next = fat_table[handle->cluster];
|
||||
if (next >= 0xFFFFFFF8) {
|
||||
|
|
@ -441,6 +478,10 @@ bool fat32_mkdir(const char *path) {
|
|||
return false; // Already exists
|
||||
}
|
||||
|
||||
if (!check_desktop_limit(normalized)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FileEntry *entry = find_free_entry();
|
||||
if (!entry) return false;
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ typedef struct {
|
|||
uint32_t size; // File size
|
||||
uint32_t mode; // 0=read, 1=write, 2=append
|
||||
bool valid; // Is this handle valid?
|
||||
uint32_t dir_sector; // Sector containing the directory entry
|
||||
uint32_t dir_offset; // Offset within that sector
|
||||
} FAT32_FileHandle;
|
||||
|
||||
// Directory Entry Info (for listing)
|
||||
|
|
@ -124,4 +126,7 @@ void fat32_get_current_dir(char *buffer, int size);
|
|||
// Utilities
|
||||
void fat32_normalize_path(const char *path, char *normalized);
|
||||
|
||||
// Desktop Limit
|
||||
void fat32_set_desktop_limit(int limit);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,12 +14,16 @@ static bool g_use_pattern = false;
|
|||
static DirtyRect g_dirty = {0, 0, 0, 0, false};
|
||||
|
||||
// Double buffering - allocate a back buffer
|
||||
// Max screen size: 2048x2048 @ 32bpp = 16MB, but we'll allocate for common sizes
|
||||
// Max screen size: 2048x2048 @ 32bpp = 16MB, but allocate for common sizes
|
||||
// Using a simple approach: allocate max size buffer
|
||||
#define MAX_FB_WIDTH 2048
|
||||
#define MAX_FB_HEIGHT 2048
|
||||
static uint32_t g_back_buffer[MAX_FB_WIDTH * MAX_FB_HEIGHT] __attribute__((aligned(4096)));
|
||||
|
||||
// Clipping state
|
||||
static int g_clip_x = 0, g_clip_y = 0, g_clip_w = 0, g_clip_h = 0;
|
||||
static bool g_clip_enabled = false;
|
||||
|
||||
void graphics_init(struct limine_framebuffer *fb) {
|
||||
g_fb = fb;
|
||||
g_dirty.active = false;
|
||||
|
|
@ -106,6 +110,13 @@ void put_pixel(int x, int y, uint32_t color) {
|
|||
if (!g_fb) return;
|
||||
if (x < 0 || x >= (int)g_fb->width || y < 0 || y >= (int)g_fb->height) return;
|
||||
|
||||
if (g_clip_enabled) {
|
||||
if (x < g_clip_x || x >= g_clip_x + g_clip_w ||
|
||||
y < g_clip_y || y >= g_clip_y + g_clip_h) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw to back buffer
|
||||
uint32_t pixel_offset = y * g_fb->width + x;
|
||||
g_back_buffer[pixel_offset] = color;
|
||||
|
|
@ -208,3 +219,15 @@ void graphics_flip_buffer(void) {
|
|||
dst += g_fb->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
void graphics_set_clipping(int x, int y, int w, int h) {
|
||||
g_clip_x = x;
|
||||
g_clip_y = y;
|
||||
g_clip_w = w;
|
||||
g_clip_h = h;
|
||||
g_clip_enabled = true;
|
||||
}
|
||||
|
||||
void graphics_clear_clipping(void) {
|
||||
g_clip_enabled = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,4 +34,8 @@ void graphics_clear_dirty(void);
|
|||
void graphics_flip_buffer(void);
|
||||
void graphics_clear_back_buffer(uint32_t color);
|
||||
|
||||
// Clipping
|
||||
void graphics_set_clipping(int x, int y, int w, int h);
|
||||
void graphics_clear_clipping(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,10 +47,6 @@ static void pic_remap(void) {
|
|||
outb(0x21, 0x01); io_wait();
|
||||
outb(0xA1, 0x01); io_wait();
|
||||
|
||||
// Restore masks (but verify we don't mask IRQ 1 and 12)
|
||||
// Actually, simple OSs often just mask everything except what they want.
|
||||
// Let's unmask IRQ 1 (Keyboard) and IRQ 12 (Mouse) explicitly and mask others.
|
||||
// 0xFD = 1111 1101 (IRQ 1 unmasked)
|
||||
// 0xEF = 1110 1111 (IRQ 12 (4 on slave) unmasked)
|
||||
|
||||
outb(0x21, 0xF9); // Unmask Keyboard (IRQ1) and Cascade (IRQ2)
|
||||
|
|
|
|||
|
|
@ -49,9 +49,6 @@ static void hcf(void) {
|
|||
void kmain(void) {
|
||||
platform_init();
|
||||
// 1. Graphics Init
|
||||
if (LIMINE_BASE_REVISION_SUPPORTED == false) {
|
||||
// Warning
|
||||
}
|
||||
|
||||
if (framebuffer_request.response == NULL || framebuffer_request.response->framebuffer_count < 1) {
|
||||
hcf();
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ static int md_strncpy(char *dest, const char *src, int n) {
|
|||
static int md_strcmp(const char *s1, const char *s2) {
|
||||
(void)s1; // Suppress unused warning
|
||||
(void)s2; // Suppress unused warning
|
||||
// Reserved for future use
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +73,6 @@ static int md_strcmp(const char *s1, const char *s2) {
|
|||
static bool md_starts_with(const char *str, const char *pattern) {
|
||||
(void)str; // Suppress unused warning
|
||||
(void)pattern; // Suppress unused warning
|
||||
// Reserved for future use
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ MemStats memory_get_stats(void) {
|
|||
void memory_print_stats(void) {
|
||||
MemStats stats = memory_get_stats();
|
||||
|
||||
// We need to use the CLI write functions - declare them as extern
|
||||
// Use CLI write functions - declare as extern
|
||||
extern void cmd_write(const char *str);
|
||||
extern void cmd_write_int(int n);
|
||||
extern void cmd_putchar(char c);
|
||||
|
|
|
|||
|
|
@ -222,8 +222,6 @@ int ipv4_send_packet(const ipv4_address_t* dest_ip,uint8_t protocol,const void*
|
|||
} else {
|
||||
int ok=arp_lookup(&target_ip,&dest_mac);
|
||||
if(ok!=0){
|
||||
// ARP failed, maybe broadcast? Or fail?
|
||||
// For now, keep existing behavior of broadcasting if ARP fails
|
||||
for(int i=0;i<6;i++) dest_mac.bytes[i]=0xFF;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static void vm_syscall(int id) {
|
|||
break;
|
||||
}
|
||||
case SYS_STRCAT: {
|
||||
// Not implemented in cli_utils, skip
|
||||
// Not implemented in cli_utils
|
||||
pop(); pop(); push(0);
|
||||
break;
|
||||
}
|
||||
|
|
@ -188,8 +188,7 @@ static void vm_syscall(int id) {
|
|||
}
|
||||
// Simplified Heap (using top of memory growing down?)
|
||||
// For now, static allocation or mapped.
|
||||
// Let's implement a dummy malloc that returns an index into memory
|
||||
// Starting at 1024 (reserve first 1K for globals)
|
||||
// Dummy malloc that returns an index into memory starting at 1024
|
||||
case SYS_MALLOC: {
|
||||
int size = pop();
|
||||
int res = vm_heap_ptr;
|
||||
|
|
@ -317,8 +316,8 @@ static void vm_syscall(int id) {
|
|||
push(0);
|
||||
break;
|
||||
}
|
||||
case SYS_EXEC: pop(); push(-1); break; // Not impl
|
||||
case SYS_SYSTEM: pop(); push(-1); break; // Not impl
|
||||
case SYS_EXEC: pop(); push(-1); break;
|
||||
case SYS_SYSTEM: pop(); push(-1); break;
|
||||
|
||||
// --- New Builtins ---
|
||||
case SYS_ISALNUM: {
|
||||
|
|
@ -601,7 +600,6 @@ int vm_exec(const uint8_t *code, int code_size) {
|
|||
break;
|
||||
}
|
||||
case OP_POP:
|
||||
// cmd_write("DEBUG: POP\n");
|
||||
pop();
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
1225
src/kernel/wm.c
1225
src/kernel/wm.c
File diff suppressed because it is too large
Load diff
|
|
@ -51,7 +51,10 @@ void wm_process_input(void);
|
|||
void wm_mark_dirty(int x, int y, int w, int h);
|
||||
void wm_refresh(void);
|
||||
void wm_paint(void);
|
||||
void wm_refresh_desktop(void);
|
||||
void wm_timer_tick(void);
|
||||
int wm_get_desktop_icon_count(void);
|
||||
void wm_show_message(const char *title, const char *message);
|
||||
|
||||
// Hook for external rendering (e.g. VM overlay)
|
||||
extern void (*wm_custom_paint_hook)(void);
|
||||
|
|
@ -59,5 +62,21 @@ extern void (*wm_custom_paint_hook)(void);
|
|||
// Drawing helpers
|
||||
void draw_bevel_rect(int x, int y, int w, int h, bool sunken);
|
||||
void draw_button(int x, int y, int w, int h, const char *text, bool pressed);
|
||||
void draw_icon(int x, int y, const char *label);
|
||||
void draw_folder_icon(int x, int y, const char *label);
|
||||
void draw_document_icon(int x, int y, const char *label);
|
||||
void draw_notepad_icon(int x, int y, const char *label);
|
||||
void draw_calculator_icon(int x, int y, const char *label);
|
||||
void draw_terminal_icon(int x, int y, const char *label);
|
||||
void draw_minesweeper_icon(int x, int y, const char *label);
|
||||
void draw_control_panel_icon(int x, int y, const char *label);
|
||||
void draw_about_icon(int x, int y, const char *label);
|
||||
void draw_recycle_bin_icon(int x, int y, const char *label);
|
||||
|
||||
// Desktop Settings
|
||||
extern bool desktop_snap_to_grid;
|
||||
extern bool desktop_auto_align;
|
||||
extern int desktop_max_rows_per_col;
|
||||
extern int desktop_max_cols;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue