From 0bc77c8c0dbc1737e2909ff5a2d5e5af48b298f7 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Tue, 24 Nov 2020 22:28:40 +0100 Subject: Started HTML rendering --- apps/browser.c | 87 ++--------------------------------- kernel/features/net.c | 15 ------ libtxt/Makefile | 2 +- libtxt/html.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++-- libtxt/inc/html.h | 12 ++++- libtxt/xml.c | 4 -- res/www/index.html | 1 + 7 files changed, 138 insertions(+), 107 deletions(-) diff --git a/apps/browser.c b/apps/browser.c index 83292e9..160b626 100644 --- a/apps/browser.c +++ b/apps/browser.c @@ -53,80 +53,6 @@ void print_indent(char *buf, u32 n) strcat(buf, "\t"); } -void parse(void *data, u32 len, char *out) -{ - struct xml_token tokens[128]; - struct xml parser; - xml_init(&parser); - void *buffer = data; - len = strlen(data); - out[0] = '\0'; - enum xml_error err = xml_parse(&parser, buffer, len, tokens, 128); - - if (err != XML_SUCCESS) { - printf("\nXML parse error: %d\n", err); - return; - } - - u32 indent = 0; - char name[16] = { 0 }; - for (u32 i = 0; i < parser.ntokens; i++) { - const struct xml_token *token = tokens + i; - name[0] = '\0'; - switch (token->type) { - case XML_START_TAG: - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - if (html_self_closing(name)) - print_indent(out, indent); - else - print_indent(out, indent++); - strcat(out, name); - strcat(out, "\n"); - break; - case XML_END_TAG: - print_indent(out, --indent); - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - strcat(out, name); - strcat(out, "/\n"); - break; - case XML_CHARACTER: - if (token->end_pos == token->start_pos + 2) { - const char *ptr = (char *)buffer + token->start_pos; - - if (ptr[0] == '\r' && ptr[1] == '\n') - continue; - } - memcpy(&name, (u8 *)buffer + token->start_pos, - token->end_pos - token->start_pos); - name[token->end_pos - token->start_pos] = '\0'; - char *clean_name = name; - for (u32 j = 0; j < strlen(name); j++) { - if (name[j] == ' ' || name[j] == '\n' || name[j] == '\r' || - name[j] == '\t') { - clean_name++; - } else { - break; - } - } - if (!strlen(clean_name)) - break; - print_indent(out, indent++); - strcat(out, clean_name); - strcat(out, "\n"); - indent--; - break; - default: - break; - } - - i += token->size; - } -} - void on_submit(void *event, struct element *box) { (void)event; @@ -152,22 +78,20 @@ void on_submit(void *event, struct element *box) ip = dns_request(url); } - struct element_text_box *l = output->data; struct element_label *c = code_label->data; struct socket *socket = net_open(S_TCP); if (socket && net_connect(socket, ip, port, NET_TIMEOUT)) { net_send(socket, query, strlen(query)); char buf[4096] = { 0 }; - char parsed[4096] = { 0 }; - if (!net_receive(socket, buf, 4096, NET_TIMEOUT)) + if (!net_receive(socket, buf, 4096, NET_TIMEOUT) || + !html_render(output, http_data(buf), 4096)) return; - parse(http_data(buf), 4096, parsed); - l->text = parsed[0] ? parsed : http_data(buf); + c->text = http_code(buf); c->color_fg = status_color(c->text); } else { - l->text = strdup("Can't connect to server."); + /* l->text = strdup("Can't connect to server."); */ c->text = strdup("000"); c->color_fg = COLOR_RED; } @@ -183,8 +107,7 @@ int main() code_label = gui_add_label(root, 0, 0, FONT_24, "000", COLOR_BLACK, COLOR_WHITE); struct element *text_input = gui_add_text_input(root, LABEL_WIDTH, 0, 100, FONT_24, COLOR_WHITE, COLOR_BLACK); - output = gui_add_text_box(root, 0, FONT_HEIGHT + 2, 100, 100, FONT_16, - "Enter URL and press Enter :)", COLOR_WHITE, COLOR_BLACK); + output = gui_add_container(root, 0, FONT_HEIGHT + 2, 100, 100, COLOR_GREEN); text_input->event.on_submit = on_submit; diff --git a/kernel/features/net.c b/kernel/features/net.c index 3fa28c9..cc46cd4 100644 --- a/kernel/features/net.c +++ b/kernel/features/net.c @@ -863,19 +863,4 @@ void net_install(void) loop(); return; } - - // Request - /* struct socket *socket = net_open(S_TCP); */ - /* if (socket && net_connect(socket, ip(91, 89, 253, 227), 80)) */ - /* net_send(socket, strdup(http_req), strlen(http_req)); */ - /* else */ - /* print("Couldn't connect!\n"); */ - - // Server // TODO: Serve using sockets - /* struct socket *socket2 = net_open(S_TCP); */ - /* socket2->src_port = 8000; */ - /* while (socket2->prot.tcp.state != 3) */ - /* ; */ - /* while (socket2->prot.tcp.state == 3) */ - /* net_send(socket2, strdup(http_res), strlen(http_res)); */ } diff --git a/libtxt/Makefile b/libtxt/Makefile index 3536250..087b54c 100644 --- a/libtxt/Makefile +++ b/libtxt/Makefile @@ -6,7 +6,7 @@ LD = ccache ../cross/opt/bin/i686-elf-ld AR = ccache ../cross/opt/bin/i686-elf-ar WARNINGS = -Wall -Wextra -pedantic-errors -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wno-long-long -CFLAGS = $(WARNINGS) -nostdlib -nostdinc -fno-builtin -mgeneral-regs-only -std=c99 -m32 -Iinc/ -I../libc/inc/ -fPIE -Duserspace -Ofast +CFLAGS = $(WARNINGS) -nostdlib -nostdinc -fno-builtin -mgeneral-regs-only -std=c99 -m32 -Iinc/ -I../libc/inc/ -I../libgui/inc/ -fPIE -Duserspace -Ofast all: libtxt diff --git a/libtxt/html.c b/libtxt/html.c index 0c07323..171de78 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -1,14 +1,19 @@ // MIT License, Copyright (c) 2020 Marvin Borner // HTML parsing is mainly based on the XML parser +#include +#include +#include +#include +#include #include #include +#include -int html_self_closing(const char *tag) +static int is_self_closing(const char *tag) { - // TODO: Add 'meta'? - const char *void_elements[] = { "area", "base", "br", "col", "embed", "hr", "img", - "input", "link", "param", "source", "track", "wbr" }; + const char *void_elements[] = { "area", "base", "br", "col", "embed", "hr", "img", + "input", "link", "meta", "param", "source", "track", "wbr" }; for (u32 i = 0; i < sizeof(void_elements) / sizeof(void_elements[0]); ++i) { if (!strcmp(void_elements[i], tag)) @@ -16,3 +21,114 @@ int html_self_closing(const char *tag) } return 0; } + +static struct dom *new_object(const char *tag, struct dom *parent) +{ + struct dom *object = malloc(sizeof(*object)); + object->tag = strdup(tag); + object->parent = parent; + object->content = NULL; + object->children = list_new(); + return object; +} + +static void print_dom(struct dom *dom, u32 level) +{ + struct node *iterator = dom->children->head; + while (iterator != NULL) { + struct dom *obj = iterator->data; + for (u32 i = 0; i < level; i++) + print("\t"); + printf("'%s': '%s'\n", obj->tag, obj->content ? obj->content : ""); + if (obj->children->head) + print_dom(obj, level + 1); + iterator = iterator->next; + } +} + +static struct dom *generate_dom(char *data, u32 length) +{ + struct xml_token tokens[128]; + struct xml parser; + xml_init(&parser); + void *buffer = data; + enum xml_error err = xml_parse(&parser, buffer, length, tokens, 128); + + if (err != XML_SUCCESS && err != XML_ERROR_BUFFERDRY) { + printf("\nXML parse error: %d\n", err); + return 0; + } + + struct dom *root = new_object("root", NULL); + struct dom *current = root; + + char name[256] = { 0 }; + for (u32 i = 0; i < parser.ntokens; i++) { + const struct xml_token *token = tokens + i; + name[0] = '\0'; + switch (token->type) { + case XML_START_TAG: + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + current = new_object(name, current); + printf("Adding %s to %s\n", current->tag, current->parent->tag); + list_add(current->parent->children, current); + break; + case XML_END_TAG: + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + assert(current && !strcmp(name, current->tag)); + current = current->parent; + break; + case XML_CHARACTER: + if (!current) + continue; + + if (token->end_pos == token->start_pos + 2) { + const char *ptr = (char *)buffer + token->start_pos; + + if (ptr[0] == '\r' && ptr[1] == '\n') + continue; + } + memcpy(&name, (u8 *)buffer + token->start_pos, + token->end_pos - token->start_pos); + name[token->end_pos - token->start_pos] = '\0'; + char *clean_name = name; + for (u32 j = 0; j < strlen(name); j++) { + if (name[j] == ' ' || name[j] == '\n' || name[j] == '\r' || + name[j] == '\t') { + clean_name++; + } else { + break; + } + } + if (!strlen(clean_name)) + break; + current->content = strdup(clean_name); + break; + default: + break; + } + + i += token->size; + } + + print("GENERATED!\n"); + print_dom(root, 0); + return root; +} + +int html_render_dom(struct element *container, struct dom *dom) +{ + (void)container; + (void)dom; + return 1; +} + +int html_render(struct element *container, char *data, u32 length) +{ + struct dom *dom = generate_dom(data, length); + return dom && html_render_dom(container, dom); +} diff --git a/libtxt/inc/html.h b/libtxt/inc/html.h index dd2b59f..4eaca0b 100644 --- a/libtxt/inc/html.h +++ b/libtxt/inc/html.h @@ -4,6 +4,16 @@ #ifndef HTML_H #define HTML_H -int html_self_closing(const char *tag); +#include +#include + +struct dom { + char *tag; + char *content; + struct dom *parent; + struct list *children; +}; + +int html_render(struct element *container, char *data, u32 length); #endif diff --git a/libtxt/xml.c b/libtxt/xml.c index b92181b..f40b289 100644 --- a/libtxt/xml.c +++ b/libtxt/xml.c @@ -485,10 +485,6 @@ enum xml_error xml_parse(struct xml *state, const char *buffer, u32 buffer_lengt state_commit(state, &temp); } - // TODO: Only for self-closing tags - if (end - lt == 0) - break; - if (end - lt < TAG_MINSIZE) return XML_ERROR_BUFFERDRY; diff --git a/res/www/index.html b/res/www/index.html index 49e1b07..59e08fa 100644 --- a/res/www/index.html +++ b/res/www/index.html @@ -8,5 +8,6 @@

This is a test page.

+
-- cgit v1.2.3 From 9559b77afb343998067a7ef269be3b11654d731f Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Wed, 25 Nov 2020 18:31:31 +0100 Subject: More HTML rendering... --- libtxt/html.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- libtxt/inc/html.h | 7 ++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/libtxt/html.c b/libtxt/html.c index 171de78..f92e90f 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -120,15 +120,80 @@ static struct dom *generate_dom(char *data, u32 length) return root; } -int html_render_dom(struct element *container, struct dom *dom) +static struct html_element *new_html_element(struct element *container, struct dom *dom) { - (void)container; - (void)dom; + struct html_element *elem = malloc(sizeof(*elem)); + elem->x_offset = 0; + elem->y_offset = 0; + elem->dom = dom; + elem->obj = container; + return elem; +} + +// TODO: Better structure? +// TODO: Less code duplication (e.g. for headings) +static struct html_element *render_object(struct html_element *container, struct dom *dom) +{ + char *tag = dom->tag; + + if (!strcmp(tag, "html")) { + struct element *obj = + gui_add_container(container->obj, 0, 0, 100, 100, COLOR_WHITE); + return new_html_element(obj, dom); + } else if (!strcmp(tag, "body")) { + struct element *obj = + gui_add_container(container->obj, 0, 0, 100, 100, COLOR_WHITE); + return new_html_element(obj, dom); + } else if (!strcmp(tag, "h1")) { + struct element *obj = + gui_add_label(container->obj, container->x_offset, container->y_offset, + FONT_32, dom->content, COLOR_WHITE, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += obj->ctx->height; + return new_html_element(obj, dom); + } else if (!strcmp(tag, "h2")) { + struct element *obj = + gui_add_label(container->obj, container->x_offset, container->y_offset, + FONT_24, dom->content, COLOR_WHITE, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += obj->ctx->height; + return new_html_element(obj, dom); + } else if (!strcmp(tag, "h3")) { + struct element *obj = + gui_add_label(container->obj, container->x_offset, container->y_offset, + FONT_16, dom->content, COLOR_WHITE, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += obj->ctx->height; + return new_html_element(obj, dom); + } else if (!strcmp(tag, "hr")) { + gfx_draw_rectangle(container->obj->ctx, container->x_offset, container->y_offset, + container->obj->ctx->width - container->x_offset, + container->y_offset + 2, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += 2; + return container; + } else { + printf("UNKNOWN %s\n", tag); + return container; + } +} + +int html_render_dom(struct html_element *container, struct dom *dom) +{ + struct node *iterator = dom->children->head; + while (iterator != NULL) { + struct dom *obj = iterator->data; + struct html_element *rendered = render_object(container, obj); + if (obj->children->head && rendered) + html_render_dom(rendered, obj); + iterator = iterator->next; + } return 1; } int html_render(struct element *container, char *data, u32 length) { struct dom *dom = generate_dom(data, length); - return dom && html_render_dom(container, dom); + struct html_element *obj = new_html_element(container, dom); + return dom && obj && html_render_dom(obj, dom); } diff --git a/libtxt/inc/html.h b/libtxt/inc/html.h index 4eaca0b..c1b29f2 100644 --- a/libtxt/inc/html.h +++ b/libtxt/inc/html.h @@ -14,6 +14,13 @@ struct dom { struct list *children; }; +struct html_element { + u32 x_offset; + u32 y_offset; + struct dom *dom; + struct element *obj; +}; + int html_render(struct element *container, char *data, u32 length); #endif -- cgit v1.2.3 From 05d7a42fa5f848f6ddc1e4018af82cd6a0e31d86 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 26 Nov 2020 14:04:07 +0100 Subject: Some changes --- libtxt/html.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/libtxt/html.c b/libtxt/html.c index f92e90f..1d736b7 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -22,10 +22,17 @@ static int is_self_closing(const char *tag) return 0; } +static char *normalize_tag_name(char *tag) +{ + for (char *p = tag; *p; ++p) + *p = *p > 0x40 && *p < 0x5b ? *p | 0x60 : *p; + return tag; +} + static struct dom *new_object(const char *tag, struct dom *parent) { struct dom *object = malloc(sizeof(*object)); - object->tag = strdup(tag); + object->tag = normalize_tag_name(strdup(tag)); object->parent = parent; object->content = NULL; object->children = list_new(); @@ -132,40 +139,48 @@ static struct html_element *new_html_element(struct element *container, struct d // TODO: Better structure? // TODO: Less code duplication (e.g. for headings) +#define CMP(tag, tag_string) (!strcmp((tag), (tag_string))) static struct html_element *render_object(struct html_element *container, struct dom *dom) { char *tag = dom->tag; - if (!strcmp(tag, "html")) { + if (CMP(tag, "html")) { struct element *obj = gui_add_container(container->obj, 0, 0, 100, 100, COLOR_WHITE); return new_html_element(obj, dom); - } else if (!strcmp(tag, "body")) { + } else if (CMP(tag, "body")) { struct element *obj = gui_add_container(container->obj, 0, 0, 100, 100, COLOR_WHITE); return new_html_element(obj, dom); - } else if (!strcmp(tag, "h1")) { + } else if (CMP(tag, "h1")) { + struct element *obj = + gui_add_label(container->obj, container->x_offset, container->y_offset, + FONT_64, dom->content, COLOR_WHITE, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += obj->ctx->height; + return new_html_element(obj, dom); + } else if (CMP(tag, "h2")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, FONT_32, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); - } else if (!strcmp(tag, "h2")) { + } else if (CMP(tag, "h3")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, FONT_24, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); - } else if (!strcmp(tag, "h3")) { + } else if (CMP(tag, "p")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, FONT_16, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); - } else if (!strcmp(tag, "hr")) { + } else if (CMP(tag, "hr")) { gfx_draw_rectangle(container->obj->ctx, container->x_offset, container->y_offset, container->obj->ctx->width - container->x_offset, container->y_offset + 2, COLOR_BLACK); -- cgit v1.2.3 From cc7b4983c07a00ab721bd5b4a533f3078c871530 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Wed, 25 Nov 2020 12:32:07 +0100 Subject: Fixed file manager Idk how I could miss that... --- apps/files.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files.c b/apps/files.c index c27e39c..e21af5a 100644 --- a/apps/files.c +++ b/apps/files.c @@ -36,7 +36,7 @@ void render_list(const char *path) static struct element *list = NULL; if (list) gui_remove_element(list); - list = gui_add_container(root, 0, 0, 600, 400, COLOR_BLACK); + list = gui_add_container(root, 0, 0, 100, 100, COLOR_BLACK); struct dirent *d = read(path); -- cgit v1.2.3 From dc661fee8168ed46b06b682f80f1dcab9e69e7be Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 26 Nov 2020 14:04:50 +0100 Subject: Added userspace heap --- libc/inc/mem.h | 5 ++--- libc/mem.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/libc/inc/mem.h b/libc/inc/mem.h index 964b24b..15505fd 100644 --- a/libc/inc/mem.h +++ b/libc/inc/mem.h @@ -13,9 +13,8 @@ void heap_init(u32 start); void *malloc(u32 size); void free(void *ptr); #elif defined(userspace) -#include -#define malloc(n) (void *)sys1(SYS_MALLOC, n) -#define free(ptr) (void)(sys1(SYS_FREE, (int)ptr)) +void *malloc(u32 size); +void free(void *ptr); #else #error "No lib target specified. Please use -Dkernel or -Duserspace" #endif diff --git a/libc/mem.c b/libc/mem.c index c81a13f..fab91f8 100644 --- a/libc/mem.c +++ b/libc/mem.c @@ -68,8 +68,6 @@ int memcmp(const void *s1, const void *s2, u32 n) return 0; } -#ifdef kernel - #define ALIGNMENT 16ul #define ALIGN_TYPE char #define ALIGN_INFO sizeof(ALIGN_TYPE) * 16 @@ -94,6 +92,8 @@ int memcmp(const void *s1, const void *s2, u32 n) } \ } +#ifdef kernel + static u32 *heap; static u32 index; @@ -117,6 +117,7 @@ int count() return i; } +// TODO: Identify by pid (for freeing) void *malloc(u32 size) { if (size < 1) @@ -146,4 +147,44 @@ void *realloc(void *ptr, u32 size) return ptr; } +#elif defined(userspace) + +#define HEAP_SIZE 100000 + +#define kmalloc(n) (void *)sys1(SYS_MALLOC, n) +#define kfree(ptr) (void)(sys1(SYS_FREE, (int)ptr)) + +static u32 *heap = NULL; +static u32 index = 0; +static u32 malloced = 0; + +void *malloc(u32 size) +{ + if (size < 1) + return NULL; + + size = size + ALIGNMENT + ALIGN_INFO; + + if (!malloced || size > malloced) { + heap = kmalloc(HEAP_SIZE); + malloced = HEAP_SIZE; + } + malloced -= size; + + heap[index] = size; + index += size + 1; + + void *p = (void *)(heap + index - size); + ALIGN(p); + + return p; +} + +// TODO: Implement free, realloc and find_smallest_hole +void free(void *ptr) +{ + (void)ptr; + /* UNALIGN(ptr); */ +} + #endif -- cgit v1.2.3 From 72502ccae6c52a094ae918e27bb73243689dcf34 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 27 Nov 2020 12:46:45 +0100 Subject: Started window resize support --- apps/wm.c | 27 ++++++++++++++++++++++++--- libgui/gui.c | 23 ++++++++++++++--------- libgui/inc/gui.h | 6 +++++- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/wm.c b/apps/wm.c index 322955a..a6d2567 100644 --- a/apps/wm.c +++ b/apps/wm.c @@ -51,6 +51,17 @@ static struct context *new_context(struct context *ctx, u32 pid, int x, int y, u return ctx; } +static void remove_context(struct context *ctx) +{ + assert(list_remove(contexts, list_first_data(contexts, ctx))); + free(ctx->fb); + ctx->fb = NULL; + free(ctx); + ctx = NULL; + free(ctx); + ctx = NULL; +} + static struct context *context_at(int x, int y) { if (!contexts->head || !contexts->head->data) @@ -186,14 +197,24 @@ static void handle_mouse(struct event_mouse *event) focused->width = mouse_x - focused->x; if (mouse_y - focused->y > 0) { focused->height = mouse_y - focused->y; - focused->pitch = focused->height * (focused->bpp >> 3); } - redraw_all(); // TODO: Function to redraw one context + /* redraw_all(); // TODO: Function to redraw one context */ } mouse_pressed[1] = 1; } else if (mod_pressed && mouse_pressed[1]) { mouse_pressed[1] = 0; - redraw_all(); + if (focused) { + struct context *resized = malloc(sizeof(*resized)); + new_context(resized, focused->pid, focused->x, focused->y, focused->width, + focused->height, focused->flags); + remove_context(focused); + list_add(contexts, resized); + focused = resized; + struct gui_event_resize *msg = malloc(sizeof(*msg)); + msg->new_ctx = resized; + msg_send(resized->pid, GUI_RESIZE, msg); + redraw_all(); + } } cursor.x = mouse_x; diff --git a/libgui/gui.c b/libgui/gui.c index 943c5d7..4b28114 100644 --- a/libgui/gui.c +++ b/libgui/gui.c @@ -406,14 +406,10 @@ void gui_event_loop(struct element *container) continue; s[l] = event->ch; s[l + 1] = '\0'; - gui_sync_text_input(focused); - merge_elements(get_root(focused->window_id)); - gfx_redraw_focused(); + gui_sync(get_root(focused->window_id), focused); } else if (event->scancode == KEY_BACKSPACE && l > 0) { s[l - 1] = '\0'; - gui_sync_text_input(focused); - merge_elements(get_root(focused->window_id)); - gfx_redraw_focused(); + gui_sync(get_root(focused->window_id), focused); } } @@ -423,9 +419,7 @@ void gui_event_loop(struct element *container) // Clear! char *t = ((struct element_text_input *)focused->data)->text; memset(t, 0, strlen(t)); - gui_sync_text_input(focused); - merge_elements(get_root(focused->window_id)); - gfx_redraw_focused(); + gui_sync(get_root(focused->window_id), focused); } if (focused && focused->event.on_key && event->press && event->ch) @@ -433,6 +427,17 @@ void gui_event_loop(struct element *container) break; } + case GUI_RESIZE: { + struct gui_event_resize *event = msg->data; + struct element *root = get_root(container->window_id); + printf("RESIZE: %d->%d %d->%d\n", root->ctx->width, event->new_ctx->width, + root->ctx->height, event->new_ctx->height); + root->ctx = event->new_ctx; + gui_sync_container(root); + merge_elements(root); + gfx_redraw_focused(); + break; + } } } } diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h index 8e925d6..cf0020d 100644 --- a/libgui/inc/gui.h +++ b/libgui/inc/gui.h @@ -13,7 +13,7 @@ #define MAX_INPUT_LENGTH 100 // TODO: Improve event types (maybe as struct header) -enum window_event_type { GUI_KEYBOARD = GFX_MAX + 1, GUI_MOUSE, GUI_MAX }; +enum window_event_type { GUI_KEYBOARD = GFX_MAX + 1, GUI_MOUSE, GUI_RESIZE, GUI_MAX }; enum element_type { GUI_TYPE_ROOT, GUI_TYPE_CONTAINER, @@ -101,6 +101,10 @@ struct gui_event_mouse { int but3; }; +struct gui_event_resize { + struct context *new_ctx; +}; + struct element *gui_init(const char *title, u32 width, u32 height, u32 color_bg); void gui_event_loop(struct element *container); struct element *gui_add_button(struct element *container, int x, int y, enum font_type font_type, -- cgit v1.2.3 From 344d077a56ac21f4e63bcf0ff4eff234a4ac19e1 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 28 Nov 2020 12:33:52 +0100 Subject: Made relative window registring local --- libgui/gui.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libgui/gui.c b/libgui/gui.c index 4b28114..1e22e8c 100644 --- a/libgui/gui.c +++ b/libgui/gui.c @@ -36,7 +36,16 @@ static struct window *new_window(const char *title, int x, int y, u32 width, u32 win->id = window_count + 1; win->title = title; win->childs = list_new(); - gfx_new_ctx(win->ctx); + + if (win->ctx->flags & WF_RELATIVE) { + win->ctx->pid = getpid(); + win->ctx->bpp = 32; // TODO: Dynamic bpp + win->ctx->pitch = win->ctx->width * (win->ctx->bpp >> 3); + win->ctx->fb = malloc(win->ctx->height * win->ctx->pitch); + memset(win->ctx->fb, 0, win->ctx->height * win->ctx->pitch); + } else { + gfx_new_ctx(win->ctx); + } if (!win->ctx->fb) return NULL; -- cgit v1.2.3 From c2306a5b346abc4b1d778f0071f90caec3c264ac Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 28 Nov 2020 16:15:19 +0100 Subject: Fixed tag case normalizing --- libtxt/html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libtxt/html.c b/libtxt/html.c index 1d736b7..ae50ed2 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -86,7 +86,7 @@ static struct dom *generate_dom(char *data, u32 length) memcpy(&name, (u8 *)buffer + token->start_pos, token->end_pos - token->start_pos); name[token->end_pos - token->start_pos] = '\0'; - assert(current && !strcmp(name, current->tag)); + assert(current && !strcmp(normalize_tag_name(name), current->tag)); current = current->parent; break; case XML_CHARACTER: -- cgit v1.2.3 From e983cfa7f8580e39a181184fb2ae3a990597c02a Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 28 Nov 2020 19:13:32 +0100 Subject: Kinda-working renderer --- apps/browser.c | 6 +++++- libtxt/html.c | 27 +++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/apps/browser.c b/apps/browser.c index 160b626..0c2a430 100644 --- a/apps/browser.c +++ b/apps/browser.c @@ -92,6 +92,8 @@ void on_submit(void *event, struct element *box) c->color_fg = status_color(c->text); } else { /* l->text = strdup("Can't connect to server."); */ + gui_add_label(output, 0, 0, FONT_16, "Can't connect to server.", COLOR_WHITE, + COLOR_BLACK); c->text = strdup("000"); c->color_fg = COLOR_RED; } @@ -107,7 +109,9 @@ int main() code_label = gui_add_label(root, 0, 0, FONT_24, "000", COLOR_BLACK, COLOR_WHITE); struct element *text_input = gui_add_text_input(root, LABEL_WIDTH, 0, 100, FONT_24, COLOR_WHITE, COLOR_BLACK); - output = gui_add_container(root, 0, FONT_HEIGHT + 2, 100, 100, COLOR_GREEN); + output = gui_add_container(root, 0, FONT_HEIGHT + 2, 100, 100, COLOR_WHITE); + gui_add_label(output, 0, 0, FONT_16, "Enter URL and press Enter :)", COLOR_WHITE, + COLOR_BLACK); text_input->event.on_submit = on_submit; diff --git a/libtxt/html.c b/libtxt/html.c index ae50ed2..b54577f 100644 --- a/libtxt/html.c +++ b/libtxt/html.c @@ -32,7 +32,7 @@ static char *normalize_tag_name(char *tag) static struct dom *new_object(const char *tag, struct dom *parent) { struct dom *object = malloc(sizeof(*object)); - object->tag = normalize_tag_name(strdup(tag)); + object->tag = strdup(tag); object->parent = parent; object->content = NULL; object->children = list_new(); @@ -69,7 +69,7 @@ static struct dom *generate_dom(char *data, u32 length) struct dom *root = new_object("root", NULL); struct dom *current = root; - char name[256] = { 0 }; + static char name[256] = { 0 }; for (u32 i = 0; i < parser.ntokens; i++) { const struct xml_token *token = tokens + i; name[0] = '\0'; @@ -78,15 +78,20 @@ static struct dom *generate_dom(char *data, u32 length) memcpy(&name, (u8 *)buffer + token->start_pos, token->end_pos - token->start_pos); name[token->end_pos - token->start_pos] = '\0'; + normalize_tag_name(name); current = new_object(name, current); printf("Adding %s to %s\n", current->tag, current->parent->tag); list_add(current->parent->children, current); + if (is_self_closing(name)) + current = current->parent; break; case XML_END_TAG: memcpy(&name, (u8 *)buffer + token->start_pos, token->end_pos - token->start_pos); name[token->end_pos - token->start_pos] = '\0'; - assert(current && !strcmp(normalize_tag_name(name), current->tag)); + normalize_tag_name(name); + if (!current || !current->parent || strcmp(name, current->tag)) + return NULL; current = current->parent; break; case XML_CHARACTER: @@ -122,6 +127,7 @@ static struct dom *generate_dom(char *data, u32 length) i += token->size; } + assert(root); print("GENERATED!\n"); print_dom(root, 0); return root; @@ -144,6 +150,7 @@ static struct html_element *render_object(struct html_element *container, struct { char *tag = dom->tag; + assert(container); if (CMP(tag, "html")) { struct element *obj = gui_add_container(container->obj, 0, 0, 100, 100, COLOR_WHITE); @@ -155,21 +162,21 @@ static struct html_element *render_object(struct html_element *container, struct } else if (CMP(tag, "h1")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, - FONT_64, dom->content, COLOR_WHITE, COLOR_BLACK); + FONT_32, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); } else if (CMP(tag, "h2")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, - FONT_32, dom->content, COLOR_WHITE, COLOR_BLACK); + FONT_24, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); } else if (CMP(tag, "h3")) { struct element *obj = gui_add_label(container->obj, container->x_offset, container->y_offset, - FONT_24, dom->content, COLOR_WHITE, COLOR_BLACK); + FONT_16, dom->content, COLOR_WHITE, COLOR_BLACK); container->x_offset = 0; container->y_offset += obj->ctx->height; return new_html_element(obj, dom); @@ -189,6 +196,14 @@ static struct html_element *render_object(struct html_element *container, struct return container; } else { printf("UNKNOWN %s\n", tag); + if (dom->content && strlen(dom->content) > 0) { + struct element *obj = gui_add_label(container->obj, container->x_offset, + container->y_offset, FONT_16, + dom->content, COLOR_WHITE, COLOR_BLACK); + container->x_offset = 0; + container->y_offset += obj->ctx->height; + return new_html_element(obj, dom); + } return container; } } -- cgit v1.2.3