mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
1.44 Beta
[BUG FIX UPDATE] Updates until 1.50 will be bug fix updates as 1.50 will be a full release. Bug fixes for 1.44: -Stopped the crashing when moving stuff onto the desktop -Fixed codeblock formatting in the markdown viewer.
This commit is contained in:
parent
9a4b7b05ff
commit
e939d50be6
34 changed files with 247 additions and 103 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
# Brew OS 1.43 Beta
|
# Brew OS 1.44 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.
|
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 is now BrewOS!
|
||||||
|
|
|
||||||
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.
BIN
build/cmd.o
BIN
build/cmd.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/markdown.o
BIN
build/markdown.o
Binary file not shown.
Binary file not shown.
BIN
build/tcp.o
BIN
build/tcp.o
Binary file not shown.
BIN
build/wm.o
BIN
build/wm.o
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
# Brew OS 1.43 Beta
|
# Brew OS 1.44 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.
|
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 is now BrewOS!
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,12 +1,8 @@
|
||||||
# Timeout in seconds that Limine will wait before automatically booting.
|
|
||||||
TIMEOUT=3
|
TIMEOUT=3
|
||||||
|
|
||||||
# The entry name that will be displayed in the boot menu.
|
|
||||||
:BrewOS
|
:BrewOS
|
||||||
# We use the Limine boot protocol.
|
|
||||||
PROTOCOL=limine
|
PROTOCOL=limine
|
||||||
|
|
||||||
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
|
|
||||||
KERNEL_PATH=boot:///brewos.elf
|
KERNEL_PATH=boot:///brewos.elf
|
||||||
|
|
||||||
#FRAMEBUFFER_WIDTH=1280
|
#FRAMEBUFFER_WIDTH=1280
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
# Timeout in seconds that Limine will wait before automatically booting.
|
|
||||||
TIMEOUT=3
|
TIMEOUT=3
|
||||||
|
|
||||||
# The entry name that will be displayed in the boot menu.
|
|
||||||
:BrewOS
|
:BrewOS
|
||||||
# We use the Limine boot protocol.
|
|
||||||
PROTOCOL=limine
|
PROTOCOL=limine
|
||||||
|
|
||||||
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
|
|
||||||
KERNEL_PATH=boot:///brewos.elf
|
KERNEL_PATH=boot:///brewos.elf
|
||||||
|
|
||||||
#FRAMEBUFFER_WIDTH=1280
|
#FRAMEBUFFER_WIDTH=1280
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
/* Tell the linker that we want an x86_64 ELF64 output file */
|
|
||||||
OUTPUT_FORMAT(elf64-x86-64)
|
OUTPUT_FORMAT(elf64-x86-64)
|
||||||
OUTPUT_ARCH(i386:x86-64)
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
|
|
||||||
/* We want the symbol _start to be our entry point */
|
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
/* Define the memory layout for the kernel */
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
/* We want to be loaded in the upper half of memory */
|
|
||||||
. = 0xffffffff80000000;
|
. = 0xffffffff80000000;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ static void about_paint(Window *win) {
|
||||||
|
|
||||||
// Version info
|
// Version info
|
||||||
draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 105, "BrewOS", COLOR_BLACK);
|
||||||
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.43", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 120, "BrewOS Version 1.44", COLOR_BLACK);
|
||||||
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
|
draw_string(offset_x, offset_y + 135, "Kernel Version 2.3.1", COLOR_BLACK);
|
||||||
|
|
||||||
// Copyright
|
// Copyright
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ _start:
|
||||||
; Ensure interrupts are disabled
|
; Ensure interrupts are disabled
|
||||||
cli
|
cli
|
||||||
|
|
||||||
; Setup stack is handled by Limine, but we can re-align if paranoid
|
|
||||||
; (Limine guarantees 16-byte alignment)
|
; (Limine guarantees 16-byte alignment)
|
||||||
|
|
||||||
; Call the C kernel entry point
|
; Call the C kernel entry point
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ static void fixed_to_str(long long n, char *buf) {
|
||||||
}
|
}
|
||||||
frac_buf[f_idx] = 0;
|
frac_buf[f_idx] = 0;
|
||||||
|
|
||||||
// If we have a fraction, add it to buffer (reversed first)
|
|
||||||
if (f_idx > 0) {
|
if (f_idx > 0) {
|
||||||
for (int i = f_idx - 1; i >= 0; i--) {
|
for (int i = f_idx - 1; i >= 0; i--) {
|
||||||
temp[pos++] = frac_buf[i];
|
temp[pos++] = frac_buf[i];
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
void cli_cmd_brewver(char *args) {
|
void cli_cmd_brewver(char *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
cli_write("BrewOS v1.43 Beta\n");
|
cli_write("BrewOS v1.44 Beta\n");
|
||||||
cli_write("BrewOS Kernel V2.3.1 Beta\n");
|
cli_write("BrewOS Kernel V2.3.1 Beta\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,6 @@ void cli_cmd_udptest(char *args){
|
||||||
|
|
||||||
void cli_cmd_msgrc(char *args) {
|
void cli_cmd_msgrc(char *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
// Reset message count since we are viewing them
|
|
||||||
cmd_reset_msg_count();
|
cmd_reset_msg_count();
|
||||||
|
|
||||||
FAT32_FileHandle *fh = fat32_open("messages", "r");
|
FAT32_FileHandle *fh = fat32_open("messages", "r");
|
||||||
|
|
|
||||||
|
|
@ -957,7 +957,7 @@ static void create_test_files(void) {
|
||||||
fh = fat32_open("README.md", "w");
|
fh = fat32_open("README.md", "w");
|
||||||
if (fh) {
|
if (fh) {
|
||||||
const char *content =
|
const char *content =
|
||||||
"# Brew OS 1.40 Beta\n\n"
|
"# Brew OS 1.44 Beta\n\n"
|
||||||
"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.\n"
|
"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.\n"
|
||||||
"## Brewkernel is now BrewOS!\n"
|
"## Brewkernel is now BrewOS!\n"
|
||||||
"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).\n\n"
|
"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).\n\n"
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ static void explorer_handle_right_click(Window *win, int x, int y);
|
||||||
static void explorer_handle_file_context_menu_click(Window *win, int x, int y);
|
static void explorer_handle_file_context_menu_click(Window *win, int x, int y);
|
||||||
static void explorer_perform_paste(Window *win, const char *dest_dir);
|
static void explorer_perform_paste(Window *win, const char *dest_dir);
|
||||||
static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir);
|
static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir);
|
||||||
static void explorer_copy_recursive(const char *src_path, const char *dest_path);
|
static bool explorer_copy_recursive(const char *src_path, const char *dest_path);
|
||||||
Window* explorer_create_window(const char *path);
|
Window* explorer_create_window(const char *path);
|
||||||
|
|
||||||
extern bool is_dragging_file;
|
extern bool is_dragging_file;
|
||||||
|
|
@ -433,11 +433,11 @@ bool explorer_clipboard_has_content(void) {
|
||||||
return clipboard_action != 0 && clipboard_path[0] != 0;
|
return clipboard_action != 0 && clipboard_path[0] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void explorer_copy_recursive(const char *src_path, const char *dest_path) {
|
static bool explorer_copy_recursive(const char *src_path, const char *dest_path) {
|
||||||
if (fat32_is_directory(src_path)) {
|
if (fat32_is_directory(src_path)) {
|
||||||
fat32_mkdir(dest_path);
|
if (!fat32_mkdir(dest_path)) return false;
|
||||||
FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(64 * sizeof(FAT32_FileInfo));
|
FAT32_FileInfo *files = (FAT32_FileInfo*)kmalloc(64 * sizeof(FAT32_FileInfo));
|
||||||
if (!files) return;
|
if (!files) return false;
|
||||||
|
|
||||||
int count = fat32_list_directory(src_path, files, 64);
|
int count = fat32_list_directory(src_path, files, 64);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
@ -452,23 +452,29 @@ static void explorer_copy_recursive(const char *src_path, const char *dest_path)
|
||||||
if (d_sub[explorer_strlen(d_sub)-1] != '/') explorer_strcat(d_sub, "/");
|
if (d_sub[explorer_strlen(d_sub)-1] != '/') explorer_strcat(d_sub, "/");
|
||||||
explorer_strcat(d_sub, files[i].name);
|
explorer_strcat(d_sub, files[i].name);
|
||||||
|
|
||||||
explorer_copy_recursive(s_sub, d_sub);
|
if (!explorer_copy_recursive(s_sub, d_sub)) { kfree(files); return false; }
|
||||||
}
|
}
|
||||||
kfree(files);
|
kfree(files);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Copy file
|
// Copy file
|
||||||
FAT32_FileHandle *src = fat32_open(src_path, "r");
|
FAT32_FileHandle *src = fat32_open(src_path, "r");
|
||||||
FAT32_FileHandle *dst = fat32_open(dest_path, "w");
|
FAT32_FileHandle *dst = fat32_open(dest_path, "w");
|
||||||
|
bool success = false;
|
||||||
if (src && dst) {
|
if (src && dst) {
|
||||||
uint8_t *buf = (uint8_t*)kmalloc(4096);
|
uint8_t *buf = (uint8_t*)kmalloc(4096);
|
||||||
if (buf) {
|
if (buf) {
|
||||||
int bytes;
|
int bytes;
|
||||||
while ((bytes = fat32_read(src, buf, 4096)) > 0) fat32_write(dst, buf, bytes);
|
success = true;
|
||||||
|
while ((bytes = fat32_read(src, buf, 4096)) > 0) {
|
||||||
|
if (fat32_write(dst, buf, bytes) != bytes) { success = false; break; }
|
||||||
|
}
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (src) fat32_close(src);
|
if (src) fat32_close(src);
|
||||||
if (dst) fat32_close(dst);
|
if (dst) fat32_close(dst);
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,8 +519,16 @@ void explorer_clipboard_paste(Window *win, const char *dest_dir) {
|
||||||
ExplorerState *state = (ExplorerState*)win->data;
|
ExplorerState *state = (ExplorerState*)win->data;
|
||||||
if (!explorer_clipboard_has_content()) return;
|
if (!explorer_clipboard_has_content()) return;
|
||||||
|
|
||||||
|
// Prevent pasting a directory into itself or its subdirectories
|
||||||
|
if (explorer_str_starts_with(dest_dir, clipboard_path)) {
|
||||||
|
int src_len = explorer_strlen(clipboard_path);
|
||||||
|
if (dest_dir[src_len] == '\0' || dest_dir[src_len] == '/') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for collision
|
// Check for collision
|
||||||
char filename[256];
|
char filename[FAT32_MAX_FILENAME];
|
||||||
int len = explorer_strlen(clipboard_path);
|
int len = explorer_strlen(clipboard_path);
|
||||||
int i = len - 1;
|
int i = len - 1;
|
||||||
while (i >= 0 && clipboard_path[i] != '/') i--;
|
while (i >= 0 && clipboard_path[i] != '/') i--;
|
||||||
|
|
@ -522,7 +536,7 @@ void explorer_clipboard_paste(Window *win, const char *dest_dir) {
|
||||||
for (int k = i + 1; k < len; k++) filename[j++] = clipboard_path[k];
|
for (int k = i + 1; k < len; k++) filename[j++] = clipboard_path[k];
|
||||||
filename[j] = 0;
|
filename[j] = 0;
|
||||||
|
|
||||||
char dest_path[256];
|
char dest_path[FAT32_MAX_PATH];
|
||||||
explorer_strcpy(dest_path, dest_dir);
|
explorer_strcpy(dest_path, dest_dir);
|
||||||
if (dest_path[explorer_strlen(dest_path) - 1] != '/') {
|
if (dest_path[explorer_strlen(dest_path) - 1] != '/') {
|
||||||
explorer_strcat(dest_path, "/");
|
explorer_strcat(dest_path, "/");
|
||||||
|
|
@ -1760,7 +1774,7 @@ void explorer_refresh_all(void) {
|
||||||
static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir) {
|
static void explorer_perform_move_internal(Window *win, const char *source_path, const char *dest_dir) {
|
||||||
(void)win;
|
(void)win;
|
||||||
// 1. Extract filename
|
// 1. Extract filename
|
||||||
char filename[256];
|
char filename[FAT32_MAX_FILENAME];
|
||||||
int len = explorer_strlen(source_path);
|
int len = explorer_strlen(source_path);
|
||||||
int i = len - 1;
|
int i = len - 1;
|
||||||
while (i >= 0 && source_path[i] != '/') i--;
|
while (i >= 0 && source_path[i] != '/') i--;
|
||||||
|
|
@ -1769,7 +1783,7 @@ static void explorer_perform_move_internal(Window *win, const char *source_path,
|
||||||
filename[j] = 0;
|
filename[j] = 0;
|
||||||
|
|
||||||
// 2. Build dest path
|
// 2. Build dest path
|
||||||
char dest_path[256];
|
char dest_path[FAT32_MAX_PATH];
|
||||||
explorer_strcpy(dest_path, dest_dir);
|
explorer_strcpy(dest_path, dest_dir);
|
||||||
if (dest_path[explorer_strlen(dest_path) - 1] != '/') {
|
if (dest_path[explorer_strlen(dest_path) - 1] != '/') {
|
||||||
explorer_strcat(dest_path, "/");
|
explorer_strcat(dest_path, "/");
|
||||||
|
|
@ -1782,7 +1796,7 @@ static void explorer_perform_move_internal(Window *win, const char *source_path,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (explorer_str_starts_with(dest_path, "/RecycleBin") && !explorer_str_starts_with(source_path, "/RecycleBin")) {
|
if (explorer_str_starts_with(dest_path, "/RecycleBin") && !explorer_str_starts_with(source_path, "/RecycleBin")) {
|
||||||
char origin_path[256];
|
char origin_path[FAT32_MAX_PATH];
|
||||||
explorer_strcpy(origin_path, dest_path);
|
explorer_strcpy(origin_path, dest_path);
|
||||||
explorer_strcat(origin_path, ".origin");
|
explorer_strcat(origin_path, ".origin");
|
||||||
FAT32_FileHandle *fh = fat32_open(origin_path, "w");
|
FAT32_FileHandle *fh = fat32_open(origin_path, "w");
|
||||||
|
|
@ -1793,16 +1807,16 @@ static void explorer_perform_move_internal(Window *win, const char *source_path,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!explorer_str_starts_with(dest_path, "/RecycleBin") && explorer_str_starts_with(source_path, "/RecycleBin")) {
|
if (!explorer_str_starts_with(dest_path, "/RecycleBin") && explorer_str_starts_with(source_path, "/RecycleBin")) {
|
||||||
char origin_path[256];
|
char origin_path[FAT32_MAX_PATH];
|
||||||
explorer_strcpy(origin_path, source_path);
|
explorer_strcpy(origin_path, source_path);
|
||||||
explorer_strcat(origin_path, ".origin");
|
explorer_strcat(origin_path, ".origin");
|
||||||
fat32_delete(origin_path);
|
fat32_delete(origin_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
explorer_copy_recursive(source_path, dest_path);
|
if (explorer_copy_recursive(source_path, dest_path)) {
|
||||||
|
// 4. Delete source (Move operation)
|
||||||
// 4. Delete source (Move operation)
|
explorer_delete_permanently(source_path);
|
||||||
explorer_delete_permanently(source_path);
|
}
|
||||||
|
|
||||||
// Refresh
|
// Refresh
|
||||||
explorer_refresh_all();
|
explorer_refresh_all();
|
||||||
|
|
@ -1810,8 +1824,17 @@ static void explorer_perform_move_internal(Window *win, const char *source_path,
|
||||||
|
|
||||||
void explorer_import_file_to(Window *win, const char *source_path, const char *dest_dir) {
|
void explorer_import_file_to(Window *win, const char *source_path, const char *dest_dir) {
|
||||||
ExplorerState *state = (ExplorerState*)win->data;
|
ExplorerState *state = (ExplorerState*)win->data;
|
||||||
|
|
||||||
|
// Prevent moving a directory into itself or its subdirectories
|
||||||
|
if (explorer_str_starts_with(dest_dir, source_path)) {
|
||||||
|
int src_len = explorer_strlen(source_path);
|
||||||
|
if (dest_dir[src_len] == '\0' || dest_dir[src_len] == '/') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for collision
|
// Check for collision
|
||||||
char filename[256];
|
char filename[FAT32_MAX_FILENAME];
|
||||||
int len = explorer_strlen(source_path);
|
int len = explorer_strlen(source_path);
|
||||||
int i = len - 1;
|
int i = len - 1;
|
||||||
while (i >= 0 && source_path[i] != '/') i--;
|
while (i >= 0 && source_path[i] != '/') i--;
|
||||||
|
|
@ -1819,7 +1842,7 @@ void explorer_import_file_to(Window *win, const char *source_path, const char *d
|
||||||
for (int k = i + 1; k < len; k++) filename[j++] = source_path[k];
|
for (int k = i + 1; k < len; k++) filename[j++] = source_path[k];
|
||||||
filename[j] = 0;
|
filename[j] = 0;
|
||||||
|
|
||||||
char dest_path[256];
|
char dest_path[FAT32_MAX_PATH];
|
||||||
explorer_strcpy(dest_path, dest_dir);
|
explorer_strcpy(dest_path, dest_dir);
|
||||||
if (dest_path[explorer_strlen(dest_path) - 1] != '/') explorer_strcat(dest_path, "/");
|
if (dest_path[explorer_strlen(dest_path) - 1] != '/') explorer_strcat(dest_path, "/");
|
||||||
explorer_strcat(dest_path, filename);
|
explorer_strcat(dest_path, filename);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#include "fat32.h"
|
#include "fat32.h"
|
||||||
|
#include "memory_manager.h"
|
||||||
|
#include "io.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
@ -116,6 +118,9 @@ static void extract_parent_path(const char *path, char *parent) {
|
||||||
|
|
||||||
// Normalize path (remove .., ., etc)
|
// Normalize path (remove .., ., etc)
|
||||||
void fat32_normalize_path(const char *path, char *normalized) {
|
void fat32_normalize_path(const char *path, char *normalized) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
|
||||||
char temp[FAT32_MAX_PATH];
|
char temp[FAT32_MAX_PATH];
|
||||||
int temp_len = 0;
|
int temp_len = 0;
|
||||||
|
|
||||||
|
|
@ -173,6 +178,7 @@ void fat32_normalize_path(const char *path, char *normalized) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_strcpy(normalized, temp);
|
fs_strcpy(normalized, temp);
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find file entry by path
|
// Find file entry by path
|
||||||
|
|
@ -237,8 +243,10 @@ static bool check_desktop_limit(const char *normalized_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count files in /Desktop
|
// Count files in /Desktop
|
||||||
FAT32_FileInfo info[256]; // Temp buffer
|
FAT32_FileInfo *info = (FAT32_FileInfo*)kmalloc(256 * sizeof(FAT32_FileInfo));
|
||||||
|
if (!info) return true;
|
||||||
int count = fat32_list_directory("/Desktop", info, 256);
|
int count = fat32_list_directory("/Desktop", info, 256);
|
||||||
|
kfree(info);
|
||||||
if (count >= desktop_file_limit) return false;
|
if (count >= desktop_file_limit) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -276,6 +284,9 @@ void fat32_set_desktop_limit(int limit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
|
|
@ -284,24 +295,32 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
||||||
if (mode[0] == 'r') {
|
if (mode[0] == 'r') {
|
||||||
// Read mode
|
// Read mode
|
||||||
if (!entry || (entry->attributes & ATTR_DIRECTORY)) {
|
if (!entry || (entry->attributes & ATTR_DIRECTORY)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL; // File not found or is directory
|
return NULL; // File not found or is directory
|
||||||
}
|
}
|
||||||
} else if (mode[0] == 'w' || (mode[0] == 'a')) {
|
} else if (mode[0] == 'w' || (mode[0] == 'a')) {
|
||||||
// Write/append mode - create if not exists
|
// Write/append mode - create if not exists
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
if (!check_desktop_limit(normalized)) {
|
if (!check_desktop_limit(normalized)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = find_free_entry();
|
entry = find_free_entry();
|
||||||
if (!entry) return NULL;
|
if (!entry) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
entry->used = true;
|
entry->used = true;
|
||||||
fs_strcpy(entry->full_path, normalized);
|
fs_strcpy(entry->full_path, normalized);
|
||||||
extract_filename(normalized, entry->filename);
|
extract_filename(normalized, entry->filename);
|
||||||
extract_parent_path(normalized, entry->parent_path);
|
extract_parent_path(normalized, entry->parent_path);
|
||||||
entry->start_cluster = allocate_cluster();
|
entry->start_cluster = allocate_cluster();
|
||||||
if (!entry->start_cluster) return NULL;
|
if (!entry->start_cluster) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
entry->size = 0;
|
entry->size = 0;
|
||||||
entry->attributes = 0; // Regular file
|
entry->attributes = 0; // Regular file
|
||||||
}
|
}
|
||||||
|
|
@ -313,7 +332,10 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
||||||
|
|
||||||
// Find free handle
|
// Find free handle
|
||||||
FAT32_FileHandle *handle = find_free_handle();
|
FAT32_FileHandle *handle = find_free_handle();
|
||||||
if (!handle) return NULL;
|
if (!handle) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
handle->valid = true;
|
handle->valid = true;
|
||||||
handle->cluster = entry->start_cluster;
|
handle->cluster = entry->start_cluster;
|
||||||
|
|
@ -341,17 +363,24 @@ FAT32_FileHandle* fat32_open(const char *path, const char *mode) {
|
||||||
handle->cluster = current_cluster;
|
handle->cluster = current_cluster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fat32_close(FAT32_FileHandle *handle) {
|
void fat32_close(FAT32_FileHandle *handle) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
if (handle) {
|
if (handle) {
|
||||||
handle->valid = false;
|
handle->valid = false;
|
||||||
}
|
}
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fat32_read(FAT32_FileHandle *handle, void *buffer, int size) {
|
int fat32_read(FAT32_FileHandle *handle, void *buffer, int size) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
if (!handle || !handle->valid || handle->mode != 0) {
|
if (!handle || !handle->valid || handle->mode != 0) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,11 +417,15 @@ int fat32_read(FAT32_FileHandle *handle, void *buffer, int size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) {
|
int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
if (!handle || !handle->valid || (handle->mode != 1 && handle->mode != 2)) {
|
if (!handle || !handle->valid || (handle->mode != 1 && handle->mode != 2)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,7 +437,10 @@ int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) {
|
||||||
uint32_t next = fat_table[handle->cluster];
|
uint32_t next = fat_table[handle->cluster];
|
||||||
if (next >= 0xFFFFFFF8) {
|
if (next >= 0xFFFFFFF8) {
|
||||||
next = allocate_cluster();
|
next = allocate_cluster();
|
||||||
if (!next) return 0;
|
if (!next) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
fat_table[handle->cluster] = next;
|
fat_table[handle->cluster] = next;
|
||||||
}
|
}
|
||||||
handle->cluster = next;
|
handle->cluster = next;
|
||||||
|
|
@ -451,11 +487,15 @@ int fat32_write(FAT32_FileHandle *handle, const void *buffer, int size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fat32_seek(FAT32_FileHandle *handle, int offset, int whence) {
|
int fat32_seek(FAT32_FileHandle *handle, int offset, int whence) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
if (!handle || !handle->valid) {
|
if (!handle || !handle->valid) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,23 +514,31 @@ int fat32_seek(FAT32_FileHandle *handle, int offset, int whence) {
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->position = new_position;
|
handle->position = new_position;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return new_position;
|
return new_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_mkdir(const char *path) {
|
bool fat32_mkdir(const char *path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
if (find_file(normalized)) {
|
if (find_file(normalized)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return false; // Already exists
|
return false; // Already exists
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_desktop_limit(normalized)) {
|
if (!check_desktop_limit(normalized)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileEntry *entry = find_free_entry();
|
FileEntry *entry = find_free_entry();
|
||||||
if (!entry) return false;
|
if (!entry) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
entry->used = true;
|
entry->used = true;
|
||||||
fs_strcpy(entry->full_path, normalized);
|
fs_strcpy(entry->full_path, normalized);
|
||||||
|
|
@ -500,43 +548,58 @@ bool fat32_mkdir(const char *path) {
|
||||||
entry->size = 0;
|
entry->size = 0;
|
||||||
entry->attributes = ATTR_DIRECTORY;
|
entry->attributes = ATTR_DIRECTORY;
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_rmdir(const char *path) {
|
bool fat32_rmdir(const char *path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
FileEntry *entry = find_file(normalized);
|
FileEntry *entry = find_file(normalized);
|
||||||
if (!entry || !(entry->attributes & ATTR_DIRECTORY)) {
|
if (!entry || !(entry->attributes & ATTR_DIRECTORY)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->used = false;
|
entry->used = false;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_delete(const char *path) {
|
bool fat32_delete(const char *path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
FileEntry *entry = find_file(normalized);
|
FileEntry *entry = find_file(normalized);
|
||||||
if (!entry || (entry->attributes & ATTR_DIRECTORY)) {
|
if (!entry || (entry->attributes & ATTR_DIRECTORY)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->used = false;
|
entry->used = false;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_exists(const char *path) {
|
bool fat32_exists(const char *path) {
|
||||||
return find_file(path) != NULL;
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
bool res = find_file(path) != NULL;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_rename(const char *old_path, const char *new_path) {
|
bool fat32_rename(const char *old_path, const char *new_path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
FileEntry *entry = find_file(old_path);
|
FileEntry *entry = find_file(old_path);
|
||||||
if (!entry) return false;
|
if (!entry) { asm volatile("push %0; popfq" : : "r"(rflags)); return false; }
|
||||||
if (find_file(new_path)) return false; // Destination exists
|
if (find_file(new_path)) { asm volatile("push %0; popfq" : : "r"(rflags)); return false; } // Destination exists
|
||||||
|
|
||||||
int old_len = fs_strlen(old_path);
|
int old_len = fs_strlen(old_path);
|
||||||
|
|
||||||
|
|
@ -572,20 +635,28 @@ bool fat32_rename(const char *old_path, const char *new_path) {
|
||||||
fs_strcat(files[i].parent_path, suffix);
|
fs_strcat(files[i].parent_path, suffix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_is_directory(const char *path) {
|
bool fat32_is_directory(const char *path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
FileEntry *entry = find_file(path);
|
FileEntry *entry = find_file(path);
|
||||||
return entry && (entry->attributes & ATTR_DIRECTORY);
|
bool res = entry && (entry->attributes & ATTR_DIRECTORY);
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fat32_list_directory(const char *path, FAT32_FileInfo *entries, int max_entries) {
|
int fat32_list_directory(const char *path, FAT32_FileInfo *entries, int max_entries) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
FileEntry *dir = find_file(normalized);
|
FileEntry *dir = find_file(normalized);
|
||||||
if (!dir || !(dir->attributes & ATTR_DIRECTORY)) {
|
if (!dir || !(dir->attributes & ATTR_DIRECTORY)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return 0; // Not a directory
|
return 0; // Not a directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -600,23 +671,30 @@ int fat32_list_directory(const char *path, FAT32_FileInfo *entries, int max_entr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fat32_chdir(const char *path) {
|
bool fat32_chdir(const char *path) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
char normalized[FAT32_MAX_PATH];
|
char normalized[FAT32_MAX_PATH];
|
||||||
fat32_normalize_path(path, normalized);
|
fat32_normalize_path(path, normalized);
|
||||||
|
|
||||||
FileEntry *entry = find_file(normalized);
|
FileEntry *entry = find_file(normalized);
|
||||||
if (!entry || !(entry->attributes & ATTR_DIRECTORY)) {
|
if (!entry || !(entry->attributes & ATTR_DIRECTORY)) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_strcpy(current_dir, normalized);
|
fs_strcpy(current_dir, normalized);
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fat32_get_current_dir(char *buffer, int size) {
|
void fat32_get_current_dir(char *buffer, int size) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
int len = fs_strlen(current_dir);
|
int len = fs_strlen(current_dir);
|
||||||
if (len >= size) len = size - 1;
|
if (len >= size) len = size - 1;
|
||||||
|
|
||||||
|
|
@ -624,4 +702,5 @@ void fat32_get_current_dir(char *buffer, int size) {
|
||||||
buffer[i] = current_dir[i];
|
buffer[i] = current_dir[i];
|
||||||
}
|
}
|
||||||
buffer[len] = 0;
|
buffer[len] = 0;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
static struct limine_framebuffer *g_fb = NULL;
|
static struct limine_framebuffer *g_fb = NULL;
|
||||||
static uint32_t g_bg_color = 0xFF696969; // Dark gray background
|
static uint32_t g_bg_color = 0xFF696969; // Dark gray background
|
||||||
|
|
@ -69,6 +70,9 @@ static void merge_dirty_rect(int x, int y, int w, int h) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void graphics_mark_dirty(int x, int y, int w, int h) {
|
void graphics_mark_dirty(int x, int y, int w, int h) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
|
||||||
// Clamp to screen bounds
|
// Clamp to screen bounds
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
w += x;
|
w += x;
|
||||||
|
|
@ -85,9 +89,13 @@ void graphics_mark_dirty(int x, int y, int w, int h) {
|
||||||
h = get_screen_height() - y;
|
h = get_screen_height() - y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w <= 0 || h <= 0) return;
|
if (w <= 0 || h <= 0) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
merge_dirty_rect(x, y, w, h);
|
merge_dirty_rect(x, y, w, h);
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void graphics_mark_screen_dirty(void) {
|
void graphics_mark_screen_dirty(void) {
|
||||||
|
|
@ -103,7 +111,10 @@ DirtyRect graphics_get_dirty_rect(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void graphics_clear_dirty(void) {
|
void graphics_clear_dirty(void) {
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
g_dirty.active = false;
|
g_dirty.active = false;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void put_pixel(int x, int y, uint32_t color) {
|
void put_pixel(int x, int y, uint32_t color) {
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@ send_eoi:
|
||||||
push rax
|
push rax
|
||||||
mov al, 0x20
|
mov al, 0x20
|
||||||
out 0x20, al ; Master PIC
|
out 0x20, al ; Master PIC
|
||||||
; If IRQ > 7, send to Slave too (Mouse is IRQ 12)
|
|
||||||
; We'll handle this in the specific wrappers or C code.
|
|
||||||
; Actually, simpler to do EOI in C or here.
|
|
||||||
; Let's just do it in C.
|
|
||||||
pop rax
|
pop rax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,6 @@ static void md_parse_line(const char *raw_line, char *output, MDLineType *type,
|
||||||
*type = MD_LINE_BLOCKQUOTE;
|
*type = MD_LINE_BLOCKQUOTE;
|
||||||
i++;
|
i++;
|
||||||
if (raw_line[i] == ' ') i++;
|
if (raw_line[i] == ' ') i++;
|
||||||
} else if (raw_line[i] == '`') {
|
|
||||||
// Code block
|
|
||||||
*type = MD_LINE_CODE;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse inline formatting and copy content
|
// Parse inline formatting and copy content
|
||||||
|
|
@ -215,26 +211,36 @@ void markdown_open_file(const char *filename) {
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
char raw_line[256] = "";
|
char raw_line[256] = "";
|
||||||
|
bool in_code_block = false;
|
||||||
|
|
||||||
for (int i = 0; i < bytes_read && line < MD_MAX_LINES; i++) {
|
for (int i = 0; i < bytes_read && line < MD_MAX_LINES; i++) {
|
||||||
char ch = buffer[i];
|
char ch = buffer[i];
|
||||||
|
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
raw_line[col] = 0;
|
raw_line[col] = 0;
|
||||||
|
|
||||||
// Parse the raw line
|
if (raw_line[0] == '`' && raw_line[1] == '`' && raw_line[2] == '`') {
|
||||||
char parsed_content[256];
|
in_code_block = !in_code_block;
|
||||||
MDLineType type;
|
} else {
|
||||||
int indent;
|
if (in_code_block) {
|
||||||
md_parse_line(raw_line, parsed_content, &type, &indent);
|
md_strcpy(lines[line].content, raw_line);
|
||||||
|
lines[line].length = md_strlen(raw_line);
|
||||||
// Store parsed line
|
lines[line].type = MD_LINE_CODE;
|
||||||
md_strcpy(lines[line].content, parsed_content);
|
lines[line].indent_level = 0;
|
||||||
lines[line].length = md_strlen(parsed_content);
|
line++;
|
||||||
lines[line].type = type;
|
} else {
|
||||||
lines[line].indent_level = indent;
|
char parsed_content[256];
|
||||||
|
MDLineType type;
|
||||||
line++;
|
int indent;
|
||||||
|
md_parse_line(raw_line, parsed_content, &type, &indent);
|
||||||
|
md_strcpy(lines[line].content, parsed_content);
|
||||||
|
lines[line].length = md_strlen(parsed_content);
|
||||||
|
lines[line].type = type;
|
||||||
|
lines[line].indent_level = indent;
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
col = 0;
|
col = 0;
|
||||||
raw_line[0] = 0;
|
raw_line[0] = 0;
|
||||||
} else if (col < 255) {
|
} else if (col < 255) {
|
||||||
|
|
@ -245,16 +251,24 @@ void markdown_open_file(const char *filename) {
|
||||||
// Handle last line if no trailing newline
|
// Handle last line if no trailing newline
|
||||||
if (col > 0 && line < MD_MAX_LINES) {
|
if (col > 0 && line < MD_MAX_LINES) {
|
||||||
raw_line[col] = 0;
|
raw_line[col] = 0;
|
||||||
char parsed_content[256];
|
if (raw_line[0] == '`' && raw_line[1] == '`' && raw_line[2] == '`') {
|
||||||
MDLineType type;
|
} else if (in_code_block) {
|
||||||
int indent;
|
md_strcpy(lines[line].content, raw_line);
|
||||||
md_parse_line(raw_line, parsed_content, &type, &indent);
|
lines[line].length = md_strlen(raw_line);
|
||||||
|
lines[line].type = MD_LINE_CODE;
|
||||||
md_strcpy(lines[line].content, parsed_content);
|
lines[line].indent_level = 0;
|
||||||
lines[line].length = md_strlen(parsed_content);
|
line++;
|
||||||
lines[line].type = type;
|
} else {
|
||||||
lines[line].indent_level = indent;
|
char parsed_content[256];
|
||||||
line++;
|
MDLineType type;
|
||||||
|
int indent;
|
||||||
|
md_parse_line(raw_line, parsed_content, &type, &indent);
|
||||||
|
md_strcpy(lines[line].content, parsed_content);
|
||||||
|
lines[line].length = md_strlen(parsed_content);
|
||||||
|
lines[line].type = type;
|
||||||
|
lines[line].indent_level = indent;
|
||||||
|
line++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
line_count = line;
|
line_count = line;
|
||||||
|
|
@ -331,7 +345,7 @@ static void md_paint(Window *win) {
|
||||||
text_color = 0xFF808080; // Gray
|
text_color = 0xFF808080; // Gray
|
||||||
break;
|
break;
|
||||||
case MD_LINE_CODE:
|
case MD_LINE_CODE:
|
||||||
text_color = 0xFF800000; // Dark red
|
text_color = COLOR_WHITE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
text_color = COLOR_BLACK;
|
text_color = COLOR_BLACK;
|
||||||
|
|
@ -371,7 +385,6 @@ static void md_paint(Window *win) {
|
||||||
}
|
}
|
||||||
line_segment[segment_len] = 0;
|
line_segment[segment_len] = 0;
|
||||||
|
|
||||||
// Word-based wrapping: if we didn't reach end of string, find last space
|
|
||||||
if (char_idx < text_len && segment_len > 0) {
|
if (char_idx < text_len && segment_len > 0) {
|
||||||
// Look for the last space in the segment
|
// Look for the last space in the segment
|
||||||
int last_space = -1;
|
int last_space = -1;
|
||||||
|
|
@ -382,7 +395,6 @@ static void md_paint(Window *win) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found a space, break there
|
|
||||||
if (last_space > 0) {
|
if (last_space > 0) {
|
||||||
segment_len = last_space;
|
segment_len = last_space;
|
||||||
line_segment[segment_len] = 0;
|
line_segment[segment_len] = 0;
|
||||||
|
|
@ -395,6 +407,10 @@ static void md_paint(Window *win) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (line->type == MD_LINE_CODE && segment_len > 0) {
|
||||||
|
draw_rect(x_offset - 2, line_y - 2, (segment_len * MD_CHAR_WIDTH) + 4, 12, COLOR_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
// Draw special elements for first wrapped line of this markdown line
|
// Draw special elements for first wrapped line of this markdown line
|
||||||
if (local_display_line == 0) {
|
if (local_display_line == 0) {
|
||||||
switch (line->type) {
|
switch (line->type) {
|
||||||
|
|
@ -414,10 +430,6 @@ static void md_paint(Window *win) {
|
||||||
// Draw left border
|
// Draw left border
|
||||||
draw_rect(x_offset - 4, line_y, 2, line_height, 0xFF404080);
|
draw_rect(x_offset - 4, line_y, 2, line_height, 0xFF404080);
|
||||||
break;
|
break;
|
||||||
case MD_LINE_CODE:
|
|
||||||
// Draw background for code
|
|
||||||
draw_rect(x_offset - 2, line_y, (max_chars_per_line * MD_CHAR_WIDTH) + 4, line_height, 0xFFF0F0F0);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -438,8 +450,7 @@ static void md_paint(Window *win) {
|
||||||
if (char_idx >= text_len) break;
|
if (char_idx >= text_len) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move display line forward by the actual number of wrapped lines created
|
|
||||||
// Each wrapped line uses one MD_LINE_HEIGHT worth of space
|
|
||||||
display_line += wrapped_line_count;
|
display_line += wrapped_line_count;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
@ -451,8 +462,7 @@ static void md_paint(Window *win) {
|
||||||
static void md_handle_key(Window *win, char c) {
|
static void md_handle_key(Window *win, char c) {
|
||||||
(void)win; // Suppress unused warning
|
(void)win; // Suppress unused warning
|
||||||
|
|
||||||
// Handle scrolling with arrow keys and W/S
|
|
||||||
// 17 = UP arrow, 18 = DOWN arrow (from ps2 keyboard mapping)
|
|
||||||
if (c == 'w' || c == 'W' || c == 17) { // Page up or UP arrow
|
if (c == 'w' || c == 'W' || c == 17) { // Page up or UP arrow
|
||||||
scroll_top -= 3;
|
scroll_top -= 3;
|
||||||
if (scroll_top < 0) scroll_top = 0;
|
if (scroll_top < 0) scroll_top = 0;
|
||||||
|
|
|
||||||
|
|
@ -148,23 +148,30 @@ void* kmalloc(size_t size) {
|
||||||
memory_manager_init();
|
memory_manager_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
|
||||||
if (size == 0 || size > memory_pool_size) {
|
if (size == 0 || size > memory_pool_size) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can allocate
|
// Check if we can allocate
|
||||||
if (total_allocated + size > memory_pool_size) {
|
if (total_allocated + size > memory_pool_size) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find free space
|
// Find free space
|
||||||
void *ptr = find_free_space(size);
|
void *ptr = find_free_space(size);
|
||||||
if (ptr == NULL) {
|
if (ptr == NULL) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add block entry
|
// Add block entry
|
||||||
if (block_count >= MAX_ALLOCATIONS) {
|
if (block_count >= MAX_ALLOCATIONS) {
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,6 +192,7 @@ void* kmalloc(size_t size) {
|
||||||
// Clear memory
|
// Clear memory
|
||||||
mem_memset(ptr, 0, size);
|
mem_memset(ptr, 0, size);
|
||||||
|
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,6 +201,9 @@ void kfree(void *ptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t rflags;
|
||||||
|
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||||
|
|
||||||
// Find and free the block
|
// Find and free the block
|
||||||
for (int i = 0; i < block_count; i++) {
|
for (int i = 0; i < block_count; i++) {
|
||||||
if (block_list[i].allocated && block_list[i].address == ptr) {
|
if (block_list[i].allocated && block_list[i].address == ptr) {
|
||||||
|
|
@ -204,9 +215,11 @@ void kfree(void *ptr) {
|
||||||
block_list[j] = block_list[j + 1];
|
block_list[j] = block_list[j + 1];
|
||||||
}
|
}
|
||||||
block_count--;
|
block_count--;
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void* krealloc(void *ptr, size_t new_size) {
|
void* krealloc(void *ptr, size_t new_size) {
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,6 @@ void tcp_close(tcp_socket_t *sock) {
|
||||||
|
|
||||||
int tcp_read(tcp_socket_t *sock, char *buffer, int max_len) {
|
int tcp_read(tcp_socket_t *sock, char *buffer, int max_len) {
|
||||||
if (!sock) return 0;
|
if (!sock) return 0;
|
||||||
// Simple copy of what we have
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < sock->rx_pos && i < max_len; i++) {
|
for (int i = 0; i < sock->rx_pos && i < max_len; i++) {
|
||||||
buffer[i] = sock->rx_buffer[i];
|
buffer[i] = sock->rx_buffer[i];
|
||||||
|
|
|
||||||
|
|
@ -976,6 +976,7 @@ void wm_handle_click(int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_paste) {
|
if (can_paste) {
|
||||||
|
int old_count = desktop_icon_count;
|
||||||
if (desktop_menu_target_icon != -1 && desktop_icons[desktop_menu_target_icon].type == 1) {
|
if (desktop_menu_target_icon != -1 && desktop_icons[desktop_menu_target_icon].type == 1) {
|
||||||
// Paste into folder
|
// Paste into folder
|
||||||
char path[128] = "/Desktop/";
|
char path[128] = "/Desktop/";
|
||||||
|
|
@ -987,6 +988,20 @@ void wm_handle_click(int x, int y) {
|
||||||
explorer_clipboard_paste(&win_explorer, "/Desktop");
|
explorer_clipboard_paste(&win_explorer, "/Desktop");
|
||||||
}
|
}
|
||||||
refresh_desktop_icons();
|
refresh_desktop_icons();
|
||||||
|
|
||||||
|
// If auto-align is OFF and we pasted to the background, place at click location
|
||||||
|
if (!desktop_auto_align && desktop_icon_count > old_count && desktop_menu_target_icon == -1) {
|
||||||
|
int new_idx = desktop_icon_count - 1;
|
||||||
|
desktop_icons[new_idx].x = desktop_menu_x - 20;
|
||||||
|
desktop_icons[new_idx].y = desktop_menu_y - 20;
|
||||||
|
if (desktop_snap_to_grid) {
|
||||||
|
int col = (desktop_icons[new_idx].x - 20 + 40) / 80;
|
||||||
|
int row = (desktop_icons[new_idx].y - 20 + 40) / 80;
|
||||||
|
if (col < 0) col = 0; if (row < 0) row = 0;
|
||||||
|
desktop_icons[new_idx].x = 20 + col * 80;
|
||||||
|
desktop_icons[new_idx].y = 20 + row * 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item == 3 && desktop_menu_target_icon != -1) { // Delete
|
else if (item == 3 && desktop_menu_target_icon != -1) { // Delete
|
||||||
|
|
@ -1496,20 +1511,17 @@ void wm_handle_right_click(int x, int y) {
|
||||||
wm_show_message("Error", "Desktop is full!");
|
wm_show_message("Error", "Desktop is full!");
|
||||||
} else {
|
} else {
|
||||||
explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop");
|
explorer_import_file_to(&win_explorer, drag_file_path, "/Desktop");
|
||||||
refresh_desktop_icons();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle insertion at specific position
|
// Handle insertion at specific position
|
||||||
|
char filename[64];
|
||||||
|
int len = 0; while(drag_file_path[len]) len++;
|
||||||
|
int s = len - 1; while(s >= 0 && drag_file_path[s] != '/') s--;
|
||||||
|
s++;
|
||||||
|
int d = 0; while(drag_file_path[s] && d < 63) filename[d++] = drag_file_path[s++];
|
||||||
|
filename[d] = 0;
|
||||||
|
|
||||||
if (desktop_auto_align && !msg_box_visible) {
|
if (desktop_auto_align && !msg_box_visible) {
|
||||||
// Find the newly added icon (it will be at the end)
|
|
||||||
// Extract filename from drag_file_path
|
|
||||||
char filename[64];
|
|
||||||
int len = 0; while(drag_file_path[len]) len++;
|
|
||||||
int s = len - 1; while(s >= 0 && drag_file_path[s] != '/') s--;
|
|
||||||
s++;
|
|
||||||
int d = 0; while(drag_file_path[s] && d < 63) filename[d++] = drag_file_path[s++];
|
|
||||||
filename[d] = 0;
|
|
||||||
|
|
||||||
int new_idx = -1;
|
int new_idx = -1;
|
||||||
for(int i=0; i<desktop_icon_count; i++) {
|
for(int i=0; i<desktop_icon_count; i++) {
|
||||||
if (str_eq(desktop_icons[i].name, filename) == 0) {
|
if (str_eq(desktop_icons[i].name, filename) == 0) {
|
||||||
|
|
@ -1534,6 +1546,21 @@ void wm_handle_right_click(int x, int y) {
|
||||||
|
|
||||||
refresh_desktop_icons(); // Re-apply layout
|
refresh_desktop_icons(); // Re-apply layout
|
||||||
}
|
}
|
||||||
|
} else if (!desktop_auto_align && !msg_box_visible) {
|
||||||
|
for(int i=0; i<desktop_icon_count; i++) {
|
||||||
|
if (str_eq(desktop_icons[i].name, filename) == 0) {
|
||||||
|
desktop_icons[i].x = mx - 20;
|
||||||
|
desktop_icons[i].y = my - 20;
|
||||||
|
if (desktop_snap_to_grid) {
|
||||||
|
int col = (desktop_icons[i].x - 20 + 40) / 80;
|
||||||
|
int row = (desktop_icons[i].y - 20 + 40) / 80;
|
||||||
|
if (col < 0) col = 0; if (row < 0) row = 0;
|
||||||
|
desktop_icons[i].x = 20 + col * 80;
|
||||||
|
desktop_icons[i].y = 20 + row * 80;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (!dropped_on_target) {
|
} else if (!dropped_on_target) {
|
||||||
// Moved within desktop
|
// Moved within desktop
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue