mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
task manager fix
This commit is contained in:
parent
569adabf10
commit
95c465ca39
13 changed files with 171 additions and 64 deletions
BIN
boredos.iso
BIN
boredos.iso
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/idt.o
BIN
build/idt.o
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
BIN
build/ps2.o
BIN
build/ps2.o
Binary file not shown.
|
|
@ -9,15 +9,9 @@
|
||||||
|
|
||||||
extern void serial_print(const char *s);
|
extern void serial_print(const char *s);
|
||||||
extern void serial_write(const char *str);
|
extern void serial_write(const char *str);
|
||||||
static void print_hex(uint64_t n) {
|
|
||||||
char buf[17];
|
|
||||||
char* x = "0123456789ABCDEF";
|
|
||||||
buf[16] = 0;
|
|
||||||
for (int i=15; i>=0; i--) { buf[i] = x[n & 0xF]; n >>= 4; }
|
|
||||||
serial_write(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t elf_load(const char *path, uint64_t user_pml4) {
|
uint64_t elf_load(const char *path, uint64_t user_pml4, size_t *out_load_size) {
|
||||||
|
if (out_load_size) *out_load_size = 0;
|
||||||
FAT32_FileHandle *file = fat32_open(path, "r");
|
FAT32_FileHandle *file = fat32_open(path, "r");
|
||||||
if (!file || !file->valid) {
|
if (!file || !file->valid) {
|
||||||
serial_write("[ELF] Error: Failed to open file ");
|
serial_write("[ELF] Error: Failed to open file ");
|
||||||
|
|
@ -113,6 +107,7 @@ uint64_t elf_load(const char *path, uint64_t user_pml4) {
|
||||||
uint64_t phys_addr = v2p((uint64_t)bulk_phys + (p * 4096));
|
uint64_t phys_addr = v2p((uint64_t)bulk_phys + (p * 4096));
|
||||||
paging_map_page(user_pml4, vaddr, phys_addr, 0x07);
|
paging_map_page(user_pml4, vaddr, phys_addr, 0x07);
|
||||||
}
|
}
|
||||||
|
if (out_load_size) *out_load_size += total_needed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,10 @@ typedef struct {
|
||||||
#define PF_R 4
|
#define PF_R 4
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
// Loads the ELF executable at 'path' using fat32 into the pagemap given by user_pml4.
|
// Loads the ELF executable at 'path' using fat32 into the pagemap given by user_pml4.
|
||||||
// Returns entry point address on success, or 0 on failure.
|
// Returns entry point address on success, or 0 on failure.
|
||||||
uint64_t elf_load(const char *path, uint64_t user_pml4);
|
uint64_t elf_load(const char *path, uint64_t user_pml4, size_t *out_load_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ void process_init(void) {
|
||||||
extern void mem_memcpy(void *dest, const void *src, size_t len);
|
extern void mem_memcpy(void *dest, const void *src, size_t len);
|
||||||
mem_memcpy(kernel_proc->name, "kernel", 7);
|
mem_memcpy(kernel_proc->name, "kernel", 7);
|
||||||
kernel_proc->ticks = 0;
|
kernel_proc->ticks = 0;
|
||||||
|
kernel_proc->used_memory = 32768; // Kernel stack
|
||||||
|
|
||||||
kernel_proc->next = kernel_proc; // Circular linked list
|
kernel_proc->next = kernel_proc; // Circular linked list
|
||||||
current_process = kernel_proc;
|
current_process = kernel_proc;
|
||||||
|
|
@ -168,7 +169,8 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
||||||
new_proc->is_terminal_proc = false;
|
new_proc->is_terminal_proc = false;
|
||||||
|
|
||||||
// 2. Load ELF executable
|
// 2. Load ELF executable
|
||||||
uint64_t entry_point = elf_load(filepath, new_proc->pml4_phys);
|
size_t elf_load_size = 0;
|
||||||
|
uint64_t entry_point = elf_load(filepath, new_proc->pml4_phys, &elf_load_size);
|
||||||
if (entry_point == 0) {
|
if (entry_point == 0) {
|
||||||
serial_write("[PROCESS] Failed to load ELF: ");
|
serial_write("[PROCESS] Failed to load ELF: ");
|
||||||
serial_write(filepath);
|
serial_write(filepath);
|
||||||
|
|
@ -307,6 +309,7 @@ process_t* process_create_elf(const char* filepath, const char* args_str) {
|
||||||
new_proc->kernel_stack_alloc = kernel_stack;
|
new_proc->kernel_stack_alloc = kernel_stack;
|
||||||
new_proc->user_stack_alloc = stack;
|
new_proc->user_stack_alloc = stack;
|
||||||
new_proc->rsp = (uint64_t)stack_ptr;
|
new_proc->rsp = (uint64_t)stack_ptr;
|
||||||
|
new_proc->used_memory = elf_load_size + user_stack_size + 65536;
|
||||||
|
|
||||||
// Initialize FPU state for new process
|
// Initialize FPU state for new process
|
||||||
asm volatile("fninit");
|
asm volatile("fninit");
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ typedef struct process {
|
||||||
char name[64];
|
char name[64];
|
||||||
uint64_t ticks;
|
uint64_t ticks;
|
||||||
uint64_t sleep_until;
|
uint64_t sleep_until;
|
||||||
|
size_t used_memory;
|
||||||
} __attribute__((aligned(16))) process_t;
|
} __attribute__((aligned(16))) process_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -45,18 +45,12 @@ void syscall_init(void) {
|
||||||
efer |= 1; // SCE bit is bit 0
|
efer |= 1; // SCE bit is bit 0
|
||||||
wrmsr(MSR_EFER, efer);
|
wrmsr(MSR_EFER, efer);
|
||||||
|
|
||||||
// STAR MSR setup:
|
|
||||||
// Bits 32-47: Syscall CS and SS. CS = STAR[47:32], SS = STAR[47:32] + 8 (Kernel CS = 0x08)
|
|
||||||
// Bits 48-63: Sysret CS and SS. CS = STAR[63:48] + 16, SS = STAR[63:48] + 8.
|
|
||||||
// User Data must be Base+8, User Code must be Base+16.
|
|
||||||
// Our GDT: User Data = 0x1B, User Code = 0x23.
|
|
||||||
// Therefore Base = 0x13.
|
|
||||||
uint64_t star = ((uint64_t)0x08 << 32) | ((uint64_t)0x13 << 48);
|
uint64_t star = ((uint64_t)0x08 << 32) | ((uint64_t)0x13 << 48);
|
||||||
wrmsr(MSR_STAR, star);
|
wrmsr(MSR_STAR, star);
|
||||||
|
|
||||||
wrmsr(MSR_LSTAR, (uint64_t)syscall_entry);
|
wrmsr(MSR_LSTAR, (uint64_t)syscall_entry);
|
||||||
|
|
||||||
// Mask Interrupts on SYSCALL (Clear IF bit in RFLAGS during syscall execution)
|
|
||||||
wrmsr(MSR_FMASK, 0x200);
|
wrmsr(MSR_FMASK, 0x200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -849,6 +843,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
||||||
paging_map_page(proc->pml4_phys, page, v2p(phys_addr), 0x07); // PT_PRESENT | PT_RW | PT_USER
|
paging_map_page(proc->pml4_phys, page, v2p(phys_addr), 0x07); // PT_PRESENT | PT_RW | PT_USER
|
||||||
phys_addr += 4096;
|
phys_addr += 4096;
|
||||||
}
|
}
|
||||||
|
proc->used_memory += (end_page - start_page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1120,7 +1115,19 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
||||||
if (!out) return 0;
|
if (!out) return 0;
|
||||||
|
|
||||||
extern process_t processes[];
|
extern process_t processes[];
|
||||||
extern int process_count;
|
|
||||||
|
// Dynamically calculate kernel usage as: Total System Used - User Process Sum
|
||||||
|
MemStats stats = memory_get_stats();
|
||||||
|
size_t total_used = stats.used_memory;
|
||||||
|
size_t user_used = 0;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if (processes[i].pid != 0xFFFFFFFF && processes[i].pid != 0) {
|
||||||
|
user_used += processes[i].used_memory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (total_used > user_used) processes[0].used_memory = total_used - user_used;
|
||||||
|
else processes[0].used_memory = 0;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 16; i++) { // MAX_PROCESSES is 16
|
for (int i = 0; i < 16; i++) { // MAX_PROCESSES is 16
|
||||||
if (processes[i].pid != 0xFFFFFFFF) {
|
if (processes[i].pid != 0xFFFFFFFF) {
|
||||||
|
|
@ -1129,19 +1136,7 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
||||||
mem_memcpy(out[count].name, processes[i].name, 64);
|
mem_memcpy(out[count].name, processes[i].name, 64);
|
||||||
out[count].ticks = processes[i].ticks;
|
out[count].ticks = processes[i].ticks;
|
||||||
|
|
||||||
// Memory estimation: heap + stacks
|
out[count].used_memory = processes[i].used_memory;
|
||||||
size_t mem = 0;
|
|
||||||
if (processes[i].heap_end > processes[i].heap_start)
|
|
||||||
mem += (processes[i].heap_end - processes[i].heap_start);
|
|
||||||
|
|
||||||
if (processes[i].pid == 0) {
|
|
||||||
mem = 32768;
|
|
||||||
} else {
|
|
||||||
if (processes[i].is_user) mem += 262144; // User stack
|
|
||||||
mem += 32768; // Kernel stack
|
|
||||||
}
|
|
||||||
|
|
||||||
out[count].used_memory = mem;
|
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
if (count >= max_procs) break;
|
if (count >= max_procs) break;
|
||||||
|
|
|
||||||
|
|
@ -601,6 +601,11 @@ static uint32_t parse_html_color(const char *str) {
|
||||||
if (str_istarts_with(str, "yellow")) return 0xFFFFFF00;
|
if (str_istarts_with(str, "yellow")) return 0xFFFFFF00;
|
||||||
if (str_istarts_with(str, "gray")) return 0xFF808080;
|
if (str_istarts_with(str, "gray")) return 0xFF808080;
|
||||||
if (str_istarts_with(str, "purple")) return 0xFF800080;
|
if (str_istarts_with(str, "purple")) return 0xFF800080;
|
||||||
|
if (str_istarts_with(str, "silver")) return 0xFFC0C0C0;
|
||||||
|
if (str_istarts_with(str, "maroon")) return 0xFF800000;
|
||||||
|
if (str_istarts_with(str, "navy")) return 0xFF000080;
|
||||||
|
if (str_istarts_with(str, "teal")) return 0xFF008080;
|
||||||
|
if (str_istarts_with(str, "olive")) return 0xFF808000;
|
||||||
return COLOR_TEXT;
|
return COLOR_TEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -650,6 +655,27 @@ static void decode_html_entities(char *str) {
|
||||||
if (str_istarts_with(src, "Á")) { *dst++ = (char)193; src += 8; continue; }
|
if (str_istarts_with(src, "Á")) { *dst++ = (char)193; src += 8; continue; }
|
||||||
if (str_istarts_with(src, "×")) { *dst++ = (char)215; src += 7; continue; }
|
if (str_istarts_with(src, "×")) { *dst++ = (char)215; src += 7; continue; }
|
||||||
if (str_istarts_with(src, "÷")) { *dst++ = (char)247; src += 8; continue; }
|
if (str_istarts_with(src, "÷")) { *dst++ = (char)247; src += 8; continue; }
|
||||||
|
if (str_istarts_with(src, "±")) { *dst++ = (char)177; src += 8; continue; }
|
||||||
|
if (str_istarts_with(src, "µ")) { *dst++ = (char)181; src += 7; continue; }
|
||||||
|
if (str_istarts_with(src, "¶")) { *dst++ = (char)182; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "¦")) { *dst++ = (char)166; src += 8; continue; }
|
||||||
|
if (str_istarts_with(src, "§")) { *dst++ = (char)167; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "¨")) { *dst++ = (char)168; src += 5; continue; }
|
||||||
|
if (str_istarts_with(src, "ª")) { *dst++ = (char)170; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "«")) { *dst++ = (char)171; src += 7; continue; }
|
||||||
|
if (str_istarts_with(src, "¬")) { *dst++ = (char)172; src += 5; continue; }
|
||||||
|
if (str_istarts_with(src, "­")) { src += 5; continue; } // Soft hyphen, ignore
|
||||||
|
if (str_istarts_with(src, "¯")) { *dst++ = (char)175; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "²")) { *dst++ = (char)178; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "³")) { *dst++ = (char)179; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "´")) { *dst++ = (char)180; src += 7; continue; }
|
||||||
|
if (str_istarts_with(src, "¸")) { *dst++ = (char)184; src += 7; continue; }
|
||||||
|
if (str_istarts_with(src, "¹")) { *dst++ = (char)185; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "º")) { *dst++ = (char)186; src += 6; continue; }
|
||||||
|
if (str_istarts_with(src, "»")) { *dst++ = (char)187; src += 7; continue; }
|
||||||
|
if (str_istarts_with(src, "¼")) { *dst++ = (char)188; src += 8; continue; }
|
||||||
|
if (str_istarts_with(src, "½")) { *dst++ = (char)189; src += 8; continue; }
|
||||||
|
if (str_istarts_with(src, "¾")) { *dst++ = (char)190; src += 8; continue; }
|
||||||
|
|
||||||
if (src[1] == '#') {
|
if (src[1] == '#') {
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
|
@ -704,12 +730,14 @@ static void parse_html(const char *html) {
|
||||||
int list_type[16] = {0}; int list_index[16] = {0};
|
int list_type[16] = {0}; int list_index[16] = {0};
|
||||||
|
|
||||||
bool is_pre = false;
|
bool is_pre = false;
|
||||||
|
bool is_plaintext = false;
|
||||||
|
int table_col = 0;
|
||||||
next_form_id = 1;
|
next_form_id = 1;
|
||||||
bool inside_title = false;
|
bool inside_title = false;
|
||||||
char page_title[256] = "";
|
char page_title[256] = "";
|
||||||
|
|
||||||
while (html[i] && element_count < MAX_ELEMENTS) {
|
while (html[i] && element_count < MAX_ELEMENTS) {
|
||||||
if (html[i] == '<') {
|
if (html[i] == '<' && !is_plaintext) {
|
||||||
if (html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
|
if (html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
|
||||||
i += 4;
|
i += 4;
|
||||||
while (html[i] && !(html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
|
while (html[i] && !(html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
|
||||||
|
|
@ -730,7 +758,28 @@ static void parse_html(const char *html) {
|
||||||
|
|
||||||
if (tag_name[0] == '/') {
|
if (tag_name[0] == '/') {
|
||||||
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
|
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; }
|
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name+1, "tr")) { emit_br(); table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name+1, "td") || str_iequals(tag_name+1, "th")) {
|
||||||
|
table_col++;
|
||||||
|
if (table_col == 1) {
|
||||||
|
// Add spacer to align second column
|
||||||
|
RenderElement *el = &elements[element_count++];
|
||||||
|
memset(el, 0, sizeof(RenderElement));
|
||||||
|
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0;
|
||||||
|
int current_x = cur_line_x;
|
||||||
|
for (int k=0; k<line_element_count; k++) current_x += elements[line_elements[k]].w;
|
||||||
|
int target_x = 160 + (blockquote_depth * 20) + (list_depth * 20);
|
||||||
|
if (current_x < target_x) {
|
||||||
|
el->w = target_x - current_x;
|
||||||
|
} else {
|
||||||
|
el->w = 10;
|
||||||
|
}
|
||||||
|
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
||||||
|
}
|
||||||
|
if (str_iequals(tag_name+1, "th")) is_bold = false;
|
||||||
|
}
|
||||||
|
else if (str_iequals(tag_name+1, "caption")) { emit_br(); is_bold = false; if (center_depth > 0) center_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
|
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
|
||||||
|
|
||||||
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
|
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
|
||||||
|
|
@ -748,7 +797,7 @@ static void parse_html(const char *html) {
|
||||||
}
|
}
|
||||||
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
|
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
|
||||||
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div") || str_iequals(tag_name+1, "address")) emit_br();
|
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div") || str_iequals(tag_name+1, "address")) emit_br();
|
||||||
else if (str_iequals(tag_name+1, "pre")) { emit_br(); is_pre = false; }
|
else if (str_iequals(tag_name+1, "pre") || str_iequals(tag_name+1, "xmp") || str_iequals(tag_name+1, "listing")) { emit_br(); is_pre = false; }
|
||||||
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
|
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
|
||||||
if (font_ptr > 0) {
|
if (font_ptr > 0) {
|
||||||
font_ptr--;
|
font_ptr--;
|
||||||
|
|
@ -767,7 +816,19 @@ static void parse_html(const char *html) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
|
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
|
||||||
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; }
|
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name, "tr")) { emit_br(); table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name, "td") || str_iequals(tag_name, "th")) {
|
||||||
|
if (table_col > 0) {
|
||||||
|
RenderElement *el = &elements[element_count++];
|
||||||
|
memset(el, 0, sizeof(RenderElement));
|
||||||
|
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0; el->w = 10;
|
||||||
|
el->h = ui_get_font_height_scaled(current_scale);
|
||||||
|
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
||||||
|
}
|
||||||
|
if (str_iequals(tag_name, "th")) is_bold = true;
|
||||||
|
}
|
||||||
|
else if (str_iequals(tag_name, "caption")) { emit_br(); center_depth++; is_bold = true; }
|
||||||
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; } // Handle blockquote start
|
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; } // Handle blockquote start
|
||||||
|
|
||||||
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
|
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
|
||||||
|
|
@ -787,16 +848,18 @@ static void parse_html(const char *html) {
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
|
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
|
||||||
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var")) is_italic = true;
|
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var") || str_iequals(tag_name, "dfn")) is_italic = true;
|
||||||
else if (str_iequals(tag_name, "u")) is_underline = true;
|
else if (str_iequals(tag_name, "u") || str_iequals(tag_name, "s") || str_iequals(tag_name, "strike")) is_underline = true;
|
||||||
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd")) {
|
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd") || str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) {
|
||||||
if (font_ptr < MAX_FONT_STACK) {
|
if (font_ptr < MAX_FONT_STACK) {
|
||||||
font_stack[font_ptr].color = current_color;
|
font_stack[font_ptr].color = current_color;
|
||||||
font_stack[font_ptr].scale = current_scale;
|
font_stack[font_ptr].scale = current_scale;
|
||||||
font_ptr++;
|
font_ptr++;
|
||||||
}
|
}
|
||||||
current_scale = 14.0f;
|
current_scale = 14.0f;
|
||||||
|
if (str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) { emit_br(); is_pre = true; }
|
||||||
}
|
}
|
||||||
|
else if (str_iequals(tag_name, "plaintext")) { emit_br(); is_plaintext = true; is_pre = true; current_scale = 14.0f; }
|
||||||
else if (str_iequals(tag_name, "address")) { emit_br(); }
|
else if (str_iequals(tag_name, "address")) { emit_br(); }
|
||||||
else if (str_iequals(tag_name, "html") || str_iequals(tag_name, "body")) skip_content = false;
|
else if (str_iequals(tag_name, "html") || str_iequals(tag_name, "body")) skip_content = false;
|
||||||
else if (str_iequals(tag_name, "head")) skip_content = true;
|
else if (str_iequals(tag_name, "head")) skip_content = true;
|
||||||
|
|
@ -1114,6 +1177,8 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
int current_form_id = inc_form_id;
|
int current_form_id = inc_form_id;
|
||||||
bool skip_content = inc_skip_content;
|
bool skip_content = inc_skip_content;
|
||||||
bool is_pre = inc_is_pre;
|
bool is_pre = inc_is_pre;
|
||||||
|
bool is_plaintext = false; // We don't persist plaintext across incremental chunks easily
|
||||||
|
int table_col = 0;
|
||||||
bool inside_title = inc_inside_title;
|
bool inside_title = inc_inside_title;
|
||||||
char page_title[256]; { int k=0; while(current_page_title[k]) { page_title[k] = current_page_title[k]; k++; } page_title[k] = 0; }
|
char page_title[256]; { int k=0; while(current_page_title[k]) { page_title[k] = current_page_title[k]; k++; } page_title[k] = 0; }
|
||||||
|
|
||||||
|
|
@ -1121,7 +1186,7 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
#define EFF_CENTER ((center_depth > 0) && (table_depth == 0))
|
#define EFF_CENTER ((center_depth > 0) && (table_depth == 0))
|
||||||
|
|
||||||
while (i < safe_len && html[i] && element_count < MAX_ELEMENTS) {
|
while (i < safe_len && html[i] && element_count < MAX_ELEMENTS) {
|
||||||
if (html[i] == '<') {
|
if (html[i] == '<' && !is_plaintext) {
|
||||||
if (i + 3 < safe_len && html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
|
if (i + 3 < safe_len && html[i+1] == '!' && html[i+2] == '-' && html[i+3] == '-') {
|
||||||
i += 4;
|
i += 4;
|
||||||
while (i < safe_len && html[i] && !(i + 2 < safe_len && html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
|
while (i < safe_len && html[i] && !(i + 2 < safe_len && html[i] == '-' && html[i+1] == '-' && html[i+2] == '>')) i++;
|
||||||
|
|
@ -1142,7 +1207,23 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
|
|
||||||
if (tag_name[0] == '/') {
|
if (tag_name[0] == '/') {
|
||||||
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
|
if (str_iequals(tag_name+1, "center")) { emit_br(); if (center_depth > 0) center_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; }
|
else if (str_iequals(tag_name+1, "table")) { emit_br(); if (table_depth > 0) table_depth--; table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name+1, "tr")) { emit_br(); table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name+1, "td") || str_iequals(tag_name+1, "th")) {
|
||||||
|
table_col++;
|
||||||
|
if (table_col == 1) {
|
||||||
|
RenderElement *el = &elements[element_count++];
|
||||||
|
memset(el, 0, sizeof(RenderElement));
|
||||||
|
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0;
|
||||||
|
int current_x = cur_line_x;
|
||||||
|
for (int k=0; k<line_element_count; k++) current_x += elements[line_elements[k]].w;
|
||||||
|
int target_x = 160 + (blockquote_depth * 20) + (list_depth * 20);
|
||||||
|
if (current_x < target_x) el->w = target_x - current_x; else el->w = 10;
|
||||||
|
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
||||||
|
}
|
||||||
|
if (str_iequals(tag_name+1, "th")) is_bold = false;
|
||||||
|
}
|
||||||
|
else if (str_iequals(tag_name+1, "caption")) { emit_br(); is_bold = false; if (center_depth > 0) center_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
|
else if (str_iequals(tag_name+1, "blockquote")) { emit_br(); if (blockquote_depth > 0) blockquote_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
|
else if (str_iequals(tag_name+1, "ul") || str_iequals(tag_name+1, "ol") || str_iequals(tag_name+1, "dl") || str_iequals(tag_name+1, "dir") || str_iequals(tag_name+1, "menu")) { emit_br(); if (list_depth > 0) list_depth--; }
|
||||||
else if (str_iequals(tag_name+1, "dt")) { emit_br(); is_bold = false; }
|
else if (str_iequals(tag_name+1, "dt")) { emit_br(); is_bold = false; }
|
||||||
|
|
@ -1155,7 +1236,7 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
else if (str_iequals(tag_name+1, "form")) { emit_br(); current_form_id = 0; current_form_action[0] = 0; }
|
else if (str_iequals(tag_name+1, "form")) { emit_br(); current_form_id = 0; current_form_action[0] = 0; }
|
||||||
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
|
else if (str_iequals(tag_name+1, "a")) current_link[0] = 0;
|
||||||
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div")) emit_br();
|
else if (str_iequals(tag_name+1, "p") || str_iequals(tag_name+1, "li") || str_iequals(tag_name+1, "div")) emit_br();
|
||||||
else if (str_iequals(tag_name+1, "pre")) { emit_br(); is_pre = false; }
|
else if (str_iequals(tag_name+1, "pre") || str_iequals(tag_name+1, "xmp") || str_iequals(tag_name+1, "listing")) { emit_br(); is_pre = false; }
|
||||||
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
|
else if (str_iequals(tag_name+1, "font") || str_iequals(tag_name+1, "tt") || str_iequals(tag_name+1, "code") || str_iequals(tag_name+1, "samp") || str_iequals(tag_name+1, "kbd")) {
|
||||||
if (inc_font_ptr > 0) {
|
if (inc_font_ptr > 0) {
|
||||||
inc_font_ptr--;
|
inc_font_ptr--;
|
||||||
|
|
@ -1174,7 +1255,19 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
|
if (str_iequals(tag_name, "center")) { emit_br(); center_depth++; }
|
||||||
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; }
|
else if (str_iequals(tag_name, "table")) { emit_br(); table_depth++; table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name, "tr")) { emit_br(); table_col = 0; }
|
||||||
|
else if (str_iequals(tag_name, "td") || str_iequals(tag_name, "th")) {
|
||||||
|
if (table_col > 0) {
|
||||||
|
RenderElement *el = &elements[element_count++];
|
||||||
|
memset(el, 0, sizeof(RenderElement));
|
||||||
|
el->tag = TAG_NONE; el->content[0] = ' '; el->content[1] = 0; el->w = 10;
|
||||||
|
el->h = ui_get_font_height_scaled(current_scale);
|
||||||
|
el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
||||||
|
}
|
||||||
|
if (str_iequals(tag_name, "th")) is_bold = true;
|
||||||
|
}
|
||||||
|
else if (str_iequals(tag_name, "caption")) { emit_br(); center_depth++; is_bold = true; }
|
||||||
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; }
|
else if (str_iequals(tag_name, "blockquote")) { emit_br(); blockquote_depth++; }
|
||||||
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
|
else if (str_iequals(tag_name, "ul") || str_iequals(tag_name, "dir") || str_iequals(tag_name, "menu")) { emit_br(); list_type[list_depth] = 0; list_depth++; }
|
||||||
else if (str_iequals(tag_name, "ol")) { emit_br(); list_type[list_depth] = 1; list_index[list_depth] = 1; list_depth++; }
|
else if (str_iequals(tag_name, "ol")) { emit_br(); list_type[list_depth] = 1; list_index[list_depth] = 1; list_depth++; }
|
||||||
|
|
@ -1186,17 +1279,19 @@ static void parse_html_incremental(const char *html, int safe_len) {
|
||||||
el->w = ui_get_string_width_scaled(el->content, current_scale); el->h = ui_get_font_height_scaled(current_scale); el->color = current_color; el->centered = EFF_CENTER; el->bold = is_bold; el->italic = is_italic; el->underline = is_underline; el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
el->w = ui_get_string_width_scaled(el->content, current_scale); el->h = ui_get_font_height_scaled(current_scale); el->color = current_color; el->centered = EFF_CENTER; el->bold = is_bold; el->italic = is_italic; el->underline = is_underline; el->scale = current_scale; el->list_depth = list_depth; el->blockquote_depth = blockquote_depth;
|
||||||
}
|
}
|
||||||
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
|
else if (str_iequals(tag_name, "b") || str_iequals(tag_name, "strong")) is_bold = true;
|
||||||
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var")) is_italic = true;
|
else if (str_iequals(tag_name, "i") || str_iequals(tag_name, "em") || str_iequals(tag_name, "cite") || str_iequals(tag_name, "var") || str_iequals(tag_name, "dfn")) is_italic = true;
|
||||||
else if (str_iequals(tag_name, "u")) is_underline = true;
|
else if (str_iequals(tag_name, "u") || str_iequals(tag_name, "s") || str_iequals(tag_name, "strike")) is_underline = true;
|
||||||
else if (str_iequals(tag_name, "address")) emit_br();
|
else if (str_iequals(tag_name, "address")) emit_br();
|
||||||
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd")) {
|
else if (str_iequals(tag_name, "tt") || str_iequals(tag_name, "code") || str_iequals(tag_name, "samp") || str_iequals(tag_name, "kbd") || str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) {
|
||||||
if (inc_font_ptr < MAX_FONT_STACK) {
|
if (inc_font_ptr < MAX_FONT_STACK) {
|
||||||
inc_font_stack[inc_font_ptr].color = current_color;
|
inc_font_stack[inc_font_ptr].color = current_color;
|
||||||
inc_font_stack[inc_font_ptr].scale = current_scale;
|
inc_font_stack[inc_font_ptr].scale = current_scale;
|
||||||
inc_font_ptr++;
|
inc_font_ptr++;
|
||||||
}
|
}
|
||||||
current_scale = 14.0f;
|
current_scale = 14.0f;
|
||||||
|
if (str_iequals(tag_name, "xmp") || str_iequals(tag_name, "listing")) { emit_br(); is_pre = true; }
|
||||||
}
|
}
|
||||||
|
else if (str_iequals(tag_name, "plaintext")) { emit_br(); is_plaintext = true; is_pre = true; current_scale = 14.0f; }
|
||||||
else if (tag_name[0] == 'h' && tag_name[1] >= '1' && tag_name[1] <= '6') {
|
else if (tag_name[0] == 'h' && tag_name[1] >= '1' && tag_name[1] <= '6') {
|
||||||
emit_br(); emit_br(); is_bold = true;
|
emit_br(); emit_br(); is_bold = true;
|
||||||
if (tag_name[1] == '1') base_scale = 32.0f; else if (tag_name[1] == '2') base_scale = 24.0f; else if (tag_name[1] == '3') base_scale = 20.0f; else base_scale = 18.0f;
|
if (tag_name[1] == '1') base_scale = 32.0f; else if (tag_name[1] == '2') base_scale = 24.0f; else if (tag_name[1] == '3') base_scale = 20.0f; else base_scale = 18.0f;
|
||||||
|
|
|
||||||
|
|
@ -106,20 +106,38 @@ static void draw_graph(int x, int y, int w, int h, int *data, uint32_t color, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void format_gib(uint64_t bytes, char *out) {
|
static void format_mem_smart(uint64_t bytes, char *out) {
|
||||||
uint64_t gib_int = bytes / (1024 * 1024 * 1024);
|
if (bytes < 1024) {
|
||||||
uint64_t gib_frac = ((bytes % (1024 * 1024 * 1024)) * 100) / (1024 * 1024 * 1024);
|
itoa((int)bytes, out);
|
||||||
|
strcat(out, " B");
|
||||||
char s_int[16], s_frac[16];
|
} else if (bytes < 1024 * 1024) {
|
||||||
itoa((int)gib_int, s_int);
|
itoa((int)(bytes / 1024), out);
|
||||||
itoa((int)gib_frac, s_frac);
|
strcat(out, " KB");
|
||||||
|
} else if (bytes < 1024 * 1024 * 1024) {
|
||||||
out[0] = 0;
|
// Show MiB with two decimal places
|
||||||
strcat(out, s_int);
|
uint64_t mib_int = bytes / (1024 * 1024);
|
||||||
strcat(out, ".");
|
uint64_t mib_frac = ((bytes % (1024 * 1024)) * 100) / (1024 * 1024);
|
||||||
if (gib_frac < 10) strcat(out, "0");
|
char s_int[16], s_frac[16];
|
||||||
strcat(out, s_frac);
|
itoa((int)mib_int, s_int);
|
||||||
strcat(out, " GiB");
|
itoa((int)mib_frac, s_frac);
|
||||||
|
strcpy(out, s_int);
|
||||||
|
strcat(out, ".");
|
||||||
|
if (mib_frac < 10) strcat(out, "0");
|
||||||
|
strcat(out, s_frac);
|
||||||
|
strcat(out, " MiB");
|
||||||
|
} else {
|
||||||
|
// Show GiB with two decimal places
|
||||||
|
uint64_t gib_int = bytes / (1024 * 1024 * 1024);
|
||||||
|
uint64_t gib_frac = ((bytes % (1024 * 1024 * 1024)) * 100) / (1024 * 1024 * 1024);
|
||||||
|
char s_int[16], s_frac[16];
|
||||||
|
itoa((int)gib_int, s_int);
|
||||||
|
itoa((int)gib_frac, s_frac);
|
||||||
|
strcpy(out, s_int);
|
||||||
|
strcat(out, ".");
|
||||||
|
if (gib_frac < 10) strcat(out, "0");
|
||||||
|
strcat(out, s_frac);
|
||||||
|
strcat(out, " GiB");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_taskman(void) {
|
static void draw_taskman(void) {
|
||||||
|
|
@ -161,9 +179,9 @@ static void draw_taskman(void) {
|
||||||
draw_graph(205, 25, 185, 60, mem_history, COLOR_MEM, max_mem_kb);
|
draw_graph(205, 25, 185, 60, mem_history, COLOR_MEM, max_mem_kb);
|
||||||
|
|
||||||
// Memory GiB usage
|
// Memory GiB usage
|
||||||
char s_used[24], s_total[24], mem_text[64];
|
char s_used[32], s_total[32], mem_text[64];
|
||||||
format_gib(used_mem_system, s_used);
|
format_mem_smart(used_mem_system, s_used);
|
||||||
format_gib(total_mem_system, s_total);
|
format_mem_smart(total_mem_system, s_total);
|
||||||
mem_text[0] = 0;
|
mem_text[0] = 0;
|
||||||
strcat(mem_text, s_used);
|
strcat(mem_text, s_used);
|
||||||
strcat(mem_text, " / ");
|
strcat(mem_text, " / ");
|
||||||
|
|
@ -200,8 +218,7 @@ static void draw_taskman(void) {
|
||||||
ui_draw_string(win_taskman, 65, ry + 6, name_disp, COLOR_DARK_TEXT);
|
ui_draw_string(win_taskman, 65, ry + 6, name_disp, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
char m_str[32];
|
char m_str[32];
|
||||||
itoa((int)(proc_list[i].used_memory / 1024), m_str);
|
format_mem_smart(proc_list[i].used_memory, m_str);
|
||||||
strcat(m_str, " KB");
|
|
||||||
ui_draw_string(win_taskman, 255, ry + 6, m_str, COLOR_DARK_TEXT);
|
ui_draw_string(win_taskman, 255, ry + 6, m_str, COLOR_DARK_TEXT);
|
||||||
|
|
||||||
row++;
|
row++;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue