mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
Improve site loading
This commit is contained in:
parent
36219f5828
commit
8b3ca448ed
8 changed files with 192 additions and 123 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
Binary file not shown.
|
|
@ -80,47 +80,38 @@ uint64_t elf_load(const char *path, uint64_t user_pml4) {
|
|||
|
||||
if (p_memsz == 0) continue;
|
||||
|
||||
// Calculate page-aligned boundaries
|
||||
uint64_t align_offset = p_vaddr & 0xFFF;
|
||||
uint64_t start_page = p_vaddr & ~0xFFF;
|
||||
uint64_t num_pages = (p_memsz + align_offset + 0xFFF) / 4096;
|
||||
// Calculate boundaries for bulk allocation
|
||||
uintptr_t align_offset = p_vaddr & 0xFFF;
|
||||
uintptr_t start_page = p_vaddr & ~0xFFFFFFFFFFFFF000ULL; // Wait, mask should be ~0xFFF
|
||||
start_page = p_vaddr & ~0xFFFULL;
|
||||
size_t total_needed = (p_memsz + align_offset + 4095) & ~4095ULL;
|
||||
size_t num_pages = total_needed / 4096;
|
||||
|
||||
// Allocate and Map Pages
|
||||
for (uint64_t p = 0; p < num_pages; p++) {
|
||||
uint64_t vaddr = start_page + (p * 4096);
|
||||
void* phys = kmalloc_aligned(4096, 4096);
|
||||
if (!phys) {
|
||||
serial_write("[ELF] Error: Out of memory mapping PT_LOAD\n");
|
||||
// Bulk allocate physical memory for the entire segment
|
||||
// Note: We allocate page by page but map them sequentially.
|
||||
// A better way is to allocate a large contiguous block if possible,
|
||||
// but our kmalloc_aligned handles arbitrary sizes.
|
||||
void* bulk_phys = kmalloc_aligned(total_needed, 4096);
|
||||
if (!bulk_phys) {
|
||||
serial_write("[ELF] Error: Out of memory bulk allocating segment\n");
|
||||
fat32_close(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Map page to user space (Present, RW, User)
|
||||
paging_map_page(user_pml4, vaddr, v2p((uint64_t)phys), 0x07);
|
||||
// Zero out entire segment (BSS and padding) in one go
|
||||
mem_memset(bulk_phys, 0, total_needed);
|
||||
|
||||
// Zero out the entire page (handles BSS and padding)
|
||||
uint8_t* dest = (uint8_t*)phys;
|
||||
for (int j=0; j<4096; j++) dest[j] = 0;
|
||||
|
||||
// Copy data from file if available for this page
|
||||
uint64_t page_vaddr_start = vaddr;
|
||||
uint64_t page_vaddr_end = vaddr + 4096;
|
||||
|
||||
// What part of the segment (p_vaddr to p_vaddr + p_filesz) overlaps this page?
|
||||
uint64_t overlap_vaddr_start = p_vaddr;
|
||||
if (page_vaddr_start > overlap_vaddr_start) overlap_vaddr_start = page_vaddr_start;
|
||||
|
||||
uint64_t overlap_vaddr_end = p_vaddr + p_filesz;
|
||||
if (page_vaddr_end < overlap_vaddr_end) overlap_vaddr_end = page_vaddr_end;
|
||||
|
||||
if (overlap_vaddr_start < overlap_vaddr_end) {
|
||||
uint64_t copy_size = overlap_vaddr_end - overlap_vaddr_start;
|
||||
uint64_t dest_offset = overlap_vaddr_start - page_vaddr_start;
|
||||
uint64_t file_offset = p_offset + (overlap_vaddr_start - p_vaddr);
|
||||
|
||||
fat32_seek(file, file_offset, 0);
|
||||
fat32_read(file, dest + dest_offset, (uint32_t)copy_size);
|
||||
// Bulk read from disk for the entire filesz part
|
||||
if (p_filesz > 0) {
|
||||
fat32_seek(file, p_offset, 0);
|
||||
fat32_read(file, (uint8_t*)bulk_phys + align_offset, (uint32_t)p_filesz);
|
||||
}
|
||||
|
||||
// Map all pages
|
||||
for (uint64_t p = 0; p < num_pages; p++) {
|
||||
uint64_t vaddr = start_page + (p * 4096);
|
||||
uint64_t phys_addr = v2p((uint64_t)bulk_phys + (p * 4096));
|
||||
paging_map_page(user_pml4, vaddr, phys_addr, 0x07);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@
|
|||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
|
||||
#define TCP_MSS 1460
|
||||
#define TCP_WND (4 * TCP_MSS)
|
||||
#define TCP_SND_BUF (4 * TCP_MSS)
|
||||
#define TCP_WND (32 * TCP_MSS)
|
||||
#define TCP_SND_BUF (32 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF/TCP_MSS))
|
||||
|
||||
#define MEM_ALIGNMENT 8
|
||||
#define MEM_SIZE (256 * 1024)
|
||||
|
||||
#define LWIP_CHKSUM_ALGORITHM 3
|
||||
|
||||
|
|
@ -34,6 +34,9 @@
|
|||
// Memory management
|
||||
#define MEMP_MEM_MALLOC 0
|
||||
#define MEM_LIBC_MALLOC 0
|
||||
#define MEM_SIZE (2 * 1024 * 1024)
|
||||
#define MEM_SIZE (16 * 1024 * 1024)
|
||||
#define PBUF_POOL_SIZE 256
|
||||
#define MEMP_NUM_TCP_SEG 128
|
||||
#define MEMP_NUM_PBUF 256
|
||||
|
||||
#endif /* LWIPOPTS_H */
|
||||
|
|
|
|||
|
|
@ -148,6 +148,29 @@ void memory_manager_init_from_memmap(struct limine_memmap_response *memmap) {
|
|||
serial_write(" MB\n");
|
||||
}
|
||||
|
||||
// Internal helper to insert a block at a specific index
|
||||
static void insert_block_at(int idx, void* addr, size_t size, bool allocated, uint32_t id) {
|
||||
if (block_count >= MAX_ALLOCATIONS) return;
|
||||
for (int j = block_count; j > idx; j--) {
|
||||
block_list[j] = block_list[j - 1];
|
||||
}
|
||||
block_list[idx].address = addr;
|
||||
block_list[idx].size = size;
|
||||
block_list[idx].allocated = allocated;
|
||||
block_list[idx].allocation_id = id;
|
||||
block_list[idx].timestamp = (allocated) ? get_timestamp() : 0;
|
||||
block_count++;
|
||||
}
|
||||
|
||||
// Internal helper to remove a block at a specific index
|
||||
static void remove_block_at(int idx) {
|
||||
if (idx < 0 || idx >= block_count) return;
|
||||
for (int j = idx; j < block_count - 1; j++) {
|
||||
block_list[j] = block_list[j + 1];
|
||||
}
|
||||
block_count--;
|
||||
}
|
||||
|
||||
void* kmalloc_aligned(size_t size, size_t alignment) {
|
||||
if (!initialized || size == 0) return NULL;
|
||||
|
||||
|
|
@ -171,52 +194,53 @@ void* kmalloc_aligned(size_t size, size_t alignment) {
|
|||
size_t padding = aligned_addr - block_start;
|
||||
|
||||
if (block_size >= size + padding) {
|
||||
int needed_slots = 0;
|
||||
if (padding > 0) needed_slots++;
|
||||
// Check if we have enough slots for potential splits
|
||||
int extra_needed = 0;
|
||||
if (padding > 0) extra_needed++;
|
||||
size_t remaining_size = block_size - (size + padding);
|
||||
if (remaining_size > 0) {
|
||||
needed_slots++;
|
||||
} else {
|
||||
// The current slot will be reused for the allocation.
|
||||
}
|
||||
if (remaining_size > 0) extra_needed++;
|
||||
|
||||
if (block_count + needed_slots > MAX_ALLOCATIONS) {
|
||||
continue; // Cannot fit metadata for this split
|
||||
if (block_count + extra_needed > MAX_ALLOCATIONS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
void* ptr = (void*)aligned_addr;
|
||||
uint32_t alloc_id = ++allocation_counter;
|
||||
|
||||
// Perform the split
|
||||
if (remaining_size > 0) {
|
||||
// We are splitting block_list[i].
|
||||
// Possible outcomes:
|
||||
// 1. [Padding (Free)] [Allocated] [Remaining (Free)]
|
||||
// 2. [Padding (Free)] [Allocated]
|
||||
// 3. [Allocated] [Remaining (Free)]
|
||||
// 4. [Allocated]
|
||||
|
||||
block_list[block_count].address = ptr;
|
||||
block_list[block_count].size = size;
|
||||
block_list[block_count].allocated = true;
|
||||
block_list[block_count].allocation_id = ++allocation_counter;
|
||||
block_list[block_count].timestamp = get_timestamp();
|
||||
block_count++;
|
||||
// We'll modify block_list[i] and insert others as needed.
|
||||
// To keep things simple and maintain sorted order, we update from right to left or carefully.
|
||||
|
||||
block_list[i].address = (void*)(aligned_addr + size);
|
||||
block_list[i].size = remaining_size;
|
||||
block_list[i].allocated = false;
|
||||
} else {
|
||||
if (padding > 0 && remaining_size > 0) {
|
||||
// Case 1: Split into 3
|
||||
block_list[i].size = padding; // Padding stays at i
|
||||
insert_block_at(i + 1, ptr, size, true, alloc_id);
|
||||
insert_block_at(i + 2, (void*)(aligned_addr + size), remaining_size, false, 0);
|
||||
} else if (padding > 0) {
|
||||
// Case 2: Split into 2
|
||||
block_list[i].size = padding;
|
||||
insert_block_at(i + 1, ptr, size, true, alloc_id);
|
||||
} else if (remaining_size > 0) {
|
||||
// Case 3: Split into 2
|
||||
block_list[i].address = ptr;
|
||||
block_list[i].size = size;
|
||||
block_list[i].allocated = true;
|
||||
block_list[i].allocation_id = ++allocation_counter;
|
||||
block_list[i].allocation_id = alloc_id;
|
||||
block_list[i].timestamp = get_timestamp();
|
||||
insert_block_at(i + 1, (void*)(aligned_addr + size), remaining_size, false, 0);
|
||||
} else {
|
||||
// Case 4: Perfect fit
|
||||
block_list[i].allocated = true;
|
||||
block_list[i].allocation_id = alloc_id;
|
||||
block_list[i].timestamp = get_timestamp();
|
||||
}
|
||||
|
||||
if (padding > 0) {
|
||||
block_list[block_count].address = (void*)block_start;
|
||||
block_list[block_count].size = padding;
|
||||
block_list[block_count].allocated = false;
|
||||
block_list[block_count].allocation_id = 0;
|
||||
block_count++;
|
||||
}
|
||||
|
||||
sort_block_list();
|
||||
|
||||
total_allocated += size;
|
||||
if (total_allocated > peak_allocated) peak_allocated = total_allocated;
|
||||
|
||||
|
|
@ -257,25 +281,13 @@ void kfree(void *ptr) {
|
|||
block_list[block_idx].allocated = false;
|
||||
block_list[block_idx].allocation_id = 0;
|
||||
|
||||
// Merge adjacent blocks. We sort first to make adjacency checking trivial.
|
||||
sort_block_list();
|
||||
|
||||
// Re-find the block (it might have moved during sort)
|
||||
for (int i = 0; i < block_count; i++) {
|
||||
if (block_list[i].address == ptr) {
|
||||
block_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge with next block if possible
|
||||
if (block_idx + 1 < block_count && !block_list[block_idx + 1].allocated) {
|
||||
uintptr_t current_end = (uintptr_t)block_list[block_idx].address + block_list[block_idx].size;
|
||||
uintptr_t next_start = (uintptr_t)block_list[block_idx + 1].address;
|
||||
if (current_end == next_start) {
|
||||
block_list[block_idx].size += block_list[block_idx + 1].size;
|
||||
for (int i = block_idx + 1; i < block_count - 1; i++) block_list[i] = block_list[i + 1];
|
||||
block_count--;
|
||||
remove_block_at(block_idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -285,8 +297,7 @@ void kfree(void *ptr) {
|
|||
uintptr_t current_start = (uintptr_t)block_list[block_idx].address;
|
||||
if (prev_end == current_start) {
|
||||
block_list[block_idx - 1].size += block_list[block_idx].size;
|
||||
for (int i = block_idx; i < block_count - 1; i++) block_list[i] = block_list[i + 1];
|
||||
block_count--;
|
||||
remove_block_at(block_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
// Memory Manager Configuration
|
||||
#define DEFAULT_POOL_SIZE (128 * 1024 * 1024) // 128MB default
|
||||
#define MAX_ALLOCATIONS 16384 // Increased for larger pools
|
||||
#define MAX_ALLOCATIONS 262144 // Increased for larger pools
|
||||
#define MAX_FRAGMENTATION_SLOTS 2048
|
||||
|
||||
// Allocation block metadata
|
||||
|
|
|
|||
|
|
@ -260,7 +260,11 @@ int network_tcp_recv(void *buf, size_t max_len) {
|
|||
}
|
||||
|
||||
// We already have data or we timed out (return 0 handled above)
|
||||
size_t copied = pbuf_copy_partial(tcp_recv_queue, buf, (u16_t)max_len, 0);
|
||||
size_t to_copy = max_len;
|
||||
if (to_copy > tcp_recv_queue->tot_len) to_copy = tcp_recv_queue->tot_len;
|
||||
if (to_copy > 0xFFFF) to_copy = 0xFFFF; // pbuf_copy_partial limit
|
||||
|
||||
size_t copied = pbuf_copy_partial(tcp_recv_queue, buf, (u16_t)to_copy, 0);
|
||||
struct pbuf *remainder = pbuf_free_header(tcp_recv_queue, (u16_t)copied);
|
||||
if (current_tcp_pcb) tcp_recved(current_tcp_pcb, (u16_t)copied);
|
||||
tcp_recv_queue = remainder;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#define WIN_H 960
|
||||
#define URL_BAR_H 30
|
||||
#define SCROLL_BAR_W 16
|
||||
#define RESP_BUF_SIZE (1024 * 1024)
|
||||
#define RESP_BUF_SIZE (32 * 1024 * 1024)
|
||||
|
||||
#define COLOR_URL_BAR 0xFF303030
|
||||
#define COLOR_URL_TEXT 0xFFF0F0F0
|
||||
|
|
@ -88,9 +88,11 @@ typedef struct {
|
|||
char form_action[256];
|
||||
char input_name[64];
|
||||
int form_id;
|
||||
int input_cursor;
|
||||
int input_scroll;
|
||||
} RenderElement;
|
||||
|
||||
#define MAX_ELEMENTS 8192
|
||||
#define MAX_ELEMENTS 65536
|
||||
static RenderElement elements[MAX_ELEMENTS];
|
||||
static int element_count = 0;
|
||||
|
||||
|
|
@ -103,7 +105,10 @@ static int next_form_id = 1;
|
|||
static ui_window_t win_browser;
|
||||
static int scroll_y = 0;
|
||||
static int total_content_height = 0;
|
||||
static int focused_element = -1; // -1 for URL bar, >= 0 for page elements
|
||||
static int focused_element = -1;
|
||||
|
||||
static void parse_html(const char *html);
|
||||
static void browser_paint(void);
|
||||
|
||||
static void browser_clear(void) {
|
||||
for (int i = 0; i < element_count; i++) {
|
||||
|
|
@ -146,7 +151,7 @@ static int parse_ip(const char* str, net_ipv4_address_t* ip) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fetch_content(const char *url, char *dest_buf, int max_len) {
|
||||
static int fetch_content(const char *url, char *dest_buf, int max_len, bool progressive) {
|
||||
const char* host_start = url;
|
||||
if (url[0] == 'h' && url[1] == 't' && url[2] == 't' && url[3] == 'p') {
|
||||
if (url[4] == 's' && url[5] == ':') host_start = url + 8;
|
||||
|
|
@ -205,11 +210,25 @@ static int fetch_content(const char *url, char *dest_buf, int max_len) {
|
|||
sys_tcp_send(request, r - request);
|
||||
|
||||
int total = 0;
|
||||
int last_render = 0;
|
||||
while (1) {
|
||||
int len = sys_tcp_recv(dest_buf + total, max_len - 1 - total);
|
||||
if (len <= 0) break;
|
||||
total += len;
|
||||
if (total >= max_len - 1) break;
|
||||
|
||||
if (progressive && total - last_render > 16384) {
|
||||
dest_buf[total] = 0;
|
||||
char *body = strstr(dest_buf, "\r\n\r\n");
|
||||
if (body) {
|
||||
body += 4;
|
||||
if (!strstr(dest_buf, "Transfer-Encoding: chunked")) {
|
||||
parse_html(body);
|
||||
browser_paint();
|
||||
last_render = total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dest_buf[total] = 0;
|
||||
sys_tcp_close();
|
||||
|
|
@ -280,7 +299,7 @@ static void load_image(RenderElement *el) {
|
|||
*u = 0;
|
||||
}
|
||||
static char img_resp[RESP_BUF_SIZE];
|
||||
int resp_len = fetch_content(url, img_resp, sizeof(img_resp));
|
||||
int resp_len = fetch_content(url, img_resp, sizeof(img_resp), false);
|
||||
char *body = strstr(img_resp, "\r\n\r\n");
|
||||
if (body) {
|
||||
body += 4;
|
||||
|
|
@ -312,7 +331,7 @@ static void flush_line(bool centered) {
|
|||
el->y = cur_line_y;
|
||||
offset_x += el->w;
|
||||
if (el->tag == TAG_IMG && el->img_h + 10 > max_h) max_h = el->img_h + 10;
|
||||
if ((el->tag == TAG_INPUT || el->tag == TAG_BUTTON) && 24 + 10 > max_h) max_h = 24 + 10;
|
||||
if ((el->tag == TAG_INPUT || el->tag == TAG_BUTTON) && 20 + 10 > max_h) max_h = 20 + 10;
|
||||
}
|
||||
cur_line_y += max_h;
|
||||
cur_line_x = 10;
|
||||
|
|
@ -402,13 +421,15 @@ static void parse_html(const char *html) {
|
|||
RenderElement *el = &elements[element_count++];
|
||||
int idx = element_count - 1;
|
||||
for (int k=0; k<(int)sizeof(RenderElement); k++) ((char*)el)[k] = 0;
|
||||
el->tag = TAG_INPUT; el->w = 160; el->h = 24; el->centered = is_centered;
|
||||
el->tag = TAG_INPUT; el->w = 160; el->h = 20; el->centered = is_centered;
|
||||
char *val = str_istrstr(attr_buf, "value=\"");
|
||||
char *ph = str_istrstr(attr_buf, "placeholder=\"");
|
||||
char *type = str_istrstr(attr_buf, "type=\"");
|
||||
char *name = str_istrstr(attr_buf, "name=\"");
|
||||
|
||||
el->form_id = current_form_id;
|
||||
el->input_cursor = 0;
|
||||
el->input_scroll = 0;
|
||||
int l;
|
||||
l = 0; while(current_form_action[l]) { el->form_action[l] = current_form_action[l]; l++; } el->form_action[l] = 0;
|
||||
|
||||
|
|
@ -476,23 +497,11 @@ static void parse_html(const char *html) {
|
|||
|
||||
static void browser_paint(void) {
|
||||
ui_draw_rect(win_browser, 0, 0, WIN_W, WIN_H, COLOR_BG);
|
||||
ui_draw_rect(win_browser, 0, 0, WIN_W, URL_BAR_H, COLOR_URL_BAR);
|
||||
ui_draw_string(win_browser, 10, 8, url_input_buffer, COLOR_URL_TEXT);
|
||||
if (focused_element == -1) {
|
||||
ui_draw_rect(win_browser, 10 + url_cursor * 8, 22, 8, 2, COLOR_URL_TEXT);
|
||||
}
|
||||
|
||||
// Scroll bar
|
||||
ui_draw_rect(win_browser, WIN_W - SCROLL_BAR_W, URL_BAR_H, SCROLL_BAR_W, WIN_H - URL_BAR_H, COLOR_SCROLL_BG);
|
||||
int thumb_h = (WIN_H - URL_BAR_H) * (WIN_H - URL_BAR_H) / (total_content_height > WIN_H ? total_content_height : WIN_H);
|
||||
if (thumb_h < 20) thumb_h = 20;
|
||||
int thumb_y = URL_BAR_H + (scroll_y * (WIN_H - URL_BAR_H - thumb_h)) / (total_content_height > WIN_H - URL_BAR_H ? total_content_height - (WIN_H - URL_BAR_H) : 1);
|
||||
ui_draw_rect(win_browser, WIN_W - SCROLL_BAR_W + 2, thumb_y, SCROLL_BAR_W - 4, thumb_h, COLOR_SCROLL_BTN);
|
||||
|
||||
for (int i = 0; i < element_count; i++) {
|
||||
RenderElement *el = &elements[i];
|
||||
int draw_y = el->y - scroll_y + URL_BAR_H;
|
||||
if (draw_y < URL_BAR_H - 1000 || draw_y > WIN_H) continue;
|
||||
if (draw_y < URL_BAR_H - 400 || draw_y > WIN_H) continue;
|
||||
if (el->tag == TAG_IMG) {
|
||||
if (el->img_pixels) ui_draw_image(win_browser, el->x, draw_y, el->img_w, el->img_h, el->img_pixels);
|
||||
else ui_draw_rect(win_browser, el->x, draw_y, 100, 80, 0xFFCCCCCC);
|
||||
|
|
@ -503,10 +512,22 @@ static void browser_paint(void) {
|
|||
ui_draw_rect(win_browser, el->x, draw_y + el->h - 1, el->w, 1, border);
|
||||
ui_draw_rect(win_browser, el->x, draw_y, 1, el->h, border);
|
||||
ui_draw_rect(win_browser, el->x + el->w - 1, draw_y, 1, el->h, border);
|
||||
ui_draw_string(win_browser, el->x + 5, draw_y + 4, el->attr_value, (focused_element == i) ? 0xFF000000 : 0xFF808080);
|
||||
|
||||
char visible[64];
|
||||
int v_len = 0;
|
||||
int max_v = (el->w - 10) / 8;
|
||||
if (max_v > 63) max_v = 63;
|
||||
for (int k = el->input_scroll; el->attr_value[k] && v_len < max_v; k++) {
|
||||
visible[v_len++] = el->attr_value[k];
|
||||
}
|
||||
visible[v_len] = 0;
|
||||
ui_draw_string(win_browser, el->x + 5, draw_y + 2, visible, (focused_element == i) ? 0xFF000000 : 0xFF808080);
|
||||
|
||||
if (focused_element == i) {
|
||||
int ilen = 0; while(el->attr_value[ilen]) ilen++;
|
||||
ui_draw_rect(win_browser, el->x + 5 + ilen * 8, draw_y + 18, 8, 2, 0xFF000000);
|
||||
int cursor_pos = el->input_cursor - el->input_scroll;
|
||||
if (cursor_pos >= 0 && cursor_pos < max_v) {
|
||||
ui_draw_rect(win_browser, el->x + 5 + cursor_pos * 8, draw_y + 16, 8, 2, 0xFF000000);
|
||||
}
|
||||
}
|
||||
} else if (el->tag == TAG_BUTTON) {
|
||||
ui_draw_rect(win_browser, el->x, draw_y, el->w, el->h, 0xFFDDDDDD);
|
||||
|
|
@ -520,11 +541,24 @@ static void browser_paint(void) {
|
|||
if (el->bold) ui_draw_string(win_browser, el->x + 1, draw_y, el->content, el->color);
|
||||
}
|
||||
}
|
||||
|
||||
ui_draw_rect(win_browser, 0, 0, WIN_W, URL_BAR_H, COLOR_URL_BAR);
|
||||
ui_draw_string(win_browser, 10, 8, url_input_buffer, COLOR_URL_TEXT);
|
||||
if (focused_element == -1) {
|
||||
ui_draw_rect(win_browser, 10 + url_cursor * 8, 22, 8, 2, COLOR_URL_TEXT);
|
||||
}
|
||||
|
||||
// Scroll bar
|
||||
ui_draw_rect(win_browser, WIN_W - SCROLL_BAR_W, URL_BAR_H, SCROLL_BAR_W, WIN_H - URL_BAR_H, COLOR_SCROLL_BG);
|
||||
int thumb_h = (WIN_H - URL_BAR_H) * (WIN_H - URL_BAR_H) / (total_content_height > WIN_H ? total_content_height : WIN_H);
|
||||
if (thumb_h < 20) thumb_h = 20;
|
||||
int thumb_y = URL_BAR_H + (scroll_y * (WIN_H - URL_BAR_H - thumb_h)) / (total_content_height > WIN_H - URL_BAR_H ? total_content_height - (WIN_H - URL_BAR_H) : 1);
|
||||
ui_draw_rect(win_browser, WIN_W - SCROLL_BAR_W + 2, thumb_y, SCROLL_BAR_W - 4, thumb_h, COLOR_SCROLL_BTN);
|
||||
}
|
||||
|
||||
static void navigate(const char *url) {
|
||||
static char main_resp[RESP_BUF_SIZE];
|
||||
int resp_len = fetch_content(url, main_resp, sizeof(main_resp));
|
||||
int resp_len = fetch_content(url, main_resp, sizeof(main_resp), true);
|
||||
if (resp_len <= 0) return;
|
||||
char *body = strstr(main_resp, "\r\n\r\n");
|
||||
if (body) {
|
||||
|
|
@ -544,7 +578,7 @@ static void net_init_if_needed(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
win_browser = ui_window_create("Boredweb", 50, 50, WIN_W, WIN_H);
|
||||
win_browser = ui_window_create("Bored Web", 50, 50, WIN_W, WIN_H);
|
||||
net_init_if_needed();
|
||||
if (argc > 1) { int k=0; while(argv[1][k]) { url_input_buffer[k] = argv[1][k]; k++; } url_input_buffer[k] = 0; url_cursor = k; }
|
||||
navigate(url_input_buffer);
|
||||
|
|
@ -655,8 +689,20 @@ int main(int argc, char **argv) {
|
|||
char c = (char)ev.arg1;
|
||||
if (focused_element == -1) {
|
||||
if (c == 13 || c == 10) { navigate(url_input_buffer); scroll_y = 0; }
|
||||
else if (c == 127 || c == 8) { if (url_cursor > 0) url_input_buffer[--url_cursor] = 0; }
|
||||
else if (c >= 32 && c <= 126 && url_cursor < 511) { url_input_buffer[url_cursor++] = c; url_input_buffer[url_cursor] = 0; }
|
||||
else if (c == 19) { if (url_cursor > 0) url_cursor--; }
|
||||
else if (c == 20) { int len = 0; while(url_input_buffer[len]) len++; if (url_cursor < len) url_cursor++; }
|
||||
else if (c == 127 || c == 8) {
|
||||
if (url_cursor > 0) {
|
||||
int len = 0; while(url_input_buffer[len]) len++;
|
||||
for (int k=url_cursor-1; k<len; k++) url_input_buffer[k] = url_input_buffer[k+1];
|
||||
url_cursor--;
|
||||
}
|
||||
}
|
||||
else if (c >= 32 && c <= 126 && url_cursor < 511) {
|
||||
int len = 0; while(url_input_buffer[len]) len++;
|
||||
for (int k=len; k>=url_cursor; k--) url_input_buffer[k+1] = url_input_buffer[k];
|
||||
url_input_buffer[url_cursor++] = c;
|
||||
}
|
||||
} else {
|
||||
RenderElement *el = &elements[focused_element];
|
||||
int len = 0; while(el->attr_value[len]) len++;
|
||||
|
|
@ -701,8 +747,22 @@ int main(int argc, char **argv) {
|
|||
int j=0; while(search_url[j]) { url_input_buffer[j] = search_url[j]; j++; } url_input_buffer[j] = 0; url_cursor = j;
|
||||
navigate(url_input_buffer); scroll_y = 0; focused_element = -1;
|
||||
}
|
||||
else if (c == 127 || c == 8) { if (len > 0) el->attr_value[--len] = 0; }
|
||||
else if (c >= 32 && c <= 126 && len < 255) { el->attr_value[len++] = c; el->attr_value[len] = 0; }
|
||||
else if (c == 19) { if (el->input_cursor > 0) el->input_cursor--; }
|
||||
else if (c == 20) { if (el->input_cursor < len) el->input_cursor++; }
|
||||
else if (c == 127 || c == 8) {
|
||||
if (el->input_cursor > 0) {
|
||||
for (int k=el->input_cursor-1; k<len; k++) el->attr_value[k] = el->attr_value[k+1];
|
||||
el->input_cursor--;
|
||||
}
|
||||
}
|
||||
else if (c >= 32 && c <= 126 && len < 255) {
|
||||
for (int k=len; k>=el->input_cursor; k--) el->attr_value[k+1] = el->attr_value[k];
|
||||
el->attr_value[el->input_cursor++] = c;
|
||||
}
|
||||
|
||||
int max_v = (el->w - 10) / 8;
|
||||
if (el->input_cursor < el->input_scroll) el->input_scroll = el->input_cursor;
|
||||
if (el->input_cursor >= el->input_scroll + max_v) el->input_scroll = el->input_cursor - max_v + 1;
|
||||
}
|
||||
|
||||
if (c == 17) { scroll_y -= 40; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue