diff options
-rw-r--r-- | apps/chess/main.c | 4 | ||||
-rw-r--r-- | apps/paint/main.c | 13 | ||||
-rw-r--r-- | apps/wm/main.c | 12 | ||||
-rw-r--r-- | libs/libc/list.c | 3 | ||||
-rw-r--r-- | libs/libgui/gfx.c | 2 | ||||
-rw-r--r-- | libs/libgui/gui.c | 53 | ||||
-rw-r--r-- | libs/libgui/gui.h | 5 |
7 files changed, 53 insertions, 39 deletions
diff --git a/apps/chess/main.c b/apps/chess/main.c index b0da8d1..8e1d470 100644 --- a/apps/chess/main.c +++ b/apps/chess/main.c @@ -214,8 +214,8 @@ static void draw_board(void) { for (u8 x = 0; x < 8; x++) { for (u8 y = 0; y < 8; y++) { - u32 widget; - gui_new_widget(&widget, win, vec2(TILE * x, TILE * y), vec2(TILE, TILE)); + u32 widget = gui_new_widget(win, GUI_MAIN, vec2(TILE * x, TILE * y), + vec2(TILE, TILE)); assert((signed)widget > 0); u8 colored = (x + y + 1) % 2 == 0; diff --git a/apps/paint/main.c b/apps/paint/main.c index 50234af..e537004 100644 --- a/apps/paint/main.c +++ b/apps/paint/main.c @@ -36,23 +36,20 @@ int main(void) gui_new_window(&win); vec2 win_size = gui_window_size(win); - u32 toolbar; - gui_new_widget(&toolbar, win, vec2(0, 0), vec2(win_size.x, COLOR_SIZE)); + u32 toolbar = gui_new_widget(win, GUI_MAIN, vec2(0, 0), vec2(win_size.x, COLOR_SIZE)); gui_fill(win, toolbar, GUI_LAYER_BG, COLOR_WHITE); u32 color_count = COUNT(colors); for (u32 i = 0; i < color_count; i++) { - u32 color; - gui_add_widget(&color, win, toolbar, vec2(i * (COLOR_SIZE + TOOLBAR_MARGIN), 0), - vec2(COLOR_SIZE, COLOR_SIZE)); + u32 color = gui_new_widget(win, toolbar, vec2(i * (COLOR_SIZE + TOOLBAR_MARGIN), 0), + vec2(COLOR_SIZE, COLOR_SIZE)); gui_fill(win, color, GUI_LAYER_FG, colors[i]); gui_draw_border(win, color, GUI_LAYER_FG, 2, COLOR_BLACK); gui_listen_widget(win, color, GUI_LISTEN_MOUSECLICK, (u32)color_click); } - u32 canvas; - gui_new_widget(&canvas, win, vec2(0, COLOR_SIZE), - vec2(win_size.x, win_size.y - COLOR_SIZE)); + u32 canvas = gui_new_widget(win, GUI_MAIN, vec2(0, COLOR_SIZE), + vec2(win_size.x, win_size.y - COLOR_SIZE)); gui_fill(win, canvas, GUI_LAYER_BG, COLOR_WHITE); gui_listen_widget(win, canvas, GUI_LISTEN_MOUSEMOVE, (u32)mousemove); diff --git a/apps/wm/main.c b/apps/wm/main.c index a4727ea..698d0cb 100644 --- a/apps/wm/main.c +++ b/apps/wm/main.c @@ -364,6 +364,16 @@ static void window_destroy(struct window *win) free(win); } +static void window_request_destroy(struct window *win) +{ + struct message_mouse msg = { 0 }; + msg.header.state = MSG_NEED_ANSWER; + msg.id = win->id; + + if (msg_connect_conn(win->client.conn) == EOK) + msg_send(GUI_DESTROY_WINDOW, &msg, sizeof(msg)); +} + /** * Window bar */ @@ -380,7 +390,7 @@ static void window_bar_mousemove(struct window *win, struct event_mouse *event, return; if (pos.x >= win->ctx.size.x - BAR_BUTTONS_WIDTH && event->but.left) - window_destroy(win); + window_request_destroy(win); else if (event->but.left) window_move(win, vec2_sub(mouse_pos, vec2(win->ctx.size.x / 2, BAR_HEIGHT / 2))); } diff --git a/libs/libc/list.c b/libs/libc/list.c index bda9e20..3f37478 100644 --- a/libs/libc/list.c +++ b/libs/libc/list.c @@ -110,7 +110,6 @@ struct node *list_add(struct list *list, void *data) } // Maybe list_remove_node? -// TODO: Free node on destroy struct list *list_remove(struct list *list, struct node *node) { if (!list->head) @@ -118,6 +117,7 @@ struct list *list_remove(struct list *list, struct node *node) if (list->head == node) { list->head = list->head->next; + free(node); return list; } @@ -131,5 +131,6 @@ struct list *list_remove(struct list *list, struct node *node) iterator->prev->next = iterator->next; if (iterator->next) iterator->next->prev = iterator->prev; + free(node); return list; } diff --git a/libs/libgui/gfx.c b/libs/libgui/gfx.c index fe8cf1e..12c0e44 100644 --- a/libs/libgui/gfx.c +++ b/libs/libgui/gfx.c @@ -310,6 +310,7 @@ void gfx_draw_border(struct context *ctx, u32 width, u32 c) } // Using Bresenham's algorithm +// TODO: Better line scaling void gfx_draw_line(struct context *ctx, vec2 pos1, vec2 pos2, u32 scale, u32 c) { int dx = ABS(pos2.x - pos1.x), sx = pos1.x < pos2.x ? 1 : -1; @@ -318,7 +319,6 @@ void gfx_draw_line(struct context *ctx, vec2 pos1, vec2 pos2, u32 scale, u32 c) while (1) { gfx_draw_rectangle(ctx, pos1, vec2_add(pos1, vec2(scale, scale)), c); - /* gfx_draw_pixel(ctx, pos1, c); */ if (pos1.x == pos2.x && pos1.y == pos2.y) break; e2 = err; diff --git a/libs/libgui/gui.c b/libs/libgui/gui.c index 859fb5a..dab00a6 100644 --- a/libs/libgui/gui.c +++ b/libs/libgui/gui.c @@ -405,7 +405,7 @@ static struct gui_widget *gui_new_plain_widget(vec2 pos, vec2 size, u8 bpp) return widget; } -void gui_add_widget(u32 *widget, u32 win_id, u32 widget_id, vec2 pos, vec2 size) +u32 gui_new_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size) { struct gui_widget *parent = gui_widget_by_id(win_id, widget_id); if (!parent) @@ -414,7 +414,7 @@ void gui_add_widget(u32 *widget, u32 win_id, u32 widget_id, vec2 pos, vec2 size) struct gui_widget *child = gui_new_plain_widget(pos, size, parent->bg.bpp); list_add(parent->children, child); - *widget = child->id; + return child->id; } static void gui_destroy_widget(u32 win_id, u32 widget_id) @@ -452,15 +452,6 @@ static void gui_destroy_widgets(u32 win_id) list_destroy(win->widgets); } -void gui_new_widget(u32 *widget, u32 win_id, vec2 pos, vec2 size) -{ - struct gui_window *win = gui_window_by_id(win_id); - if (!win) - gui_error(ENOENT); - - gui_add_widget(widget, win->id, gui_main_widget(win)->id, pos, size); -} - void gui_listen_widget(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func) { if (!func) @@ -504,8 +495,7 @@ void gui_popup(const char *text) struct gui_window *win = gui_window_by_id(popup); gui_fill(popup, gui_main_widget_id(win), GUI_LAYER_BG, COLOR_WHITE); - u32 widget; - gui_new_widget(&widget, popup, vec2(0, 0), vec2(POPUP_WIDTH, 32)); + u32 widget = gui_new_widget(popup, GUI_MAIN, vec2(0, 0), vec2(POPUP_WIDTH, 32)); gui_fill(popup, widget, GUI_LAYER_BG, COLOR_WHITE); gui_write(popup, widget, GUI_LAYER_FG, vec2(0, 0), FONT_32, COLOR_BLACK, text); @@ -564,6 +554,7 @@ void gui_new_custom_window(u32 *id, vec2 pos, vec2 size) list_add(windows, win); win->widgets = list_new(); + // Initialize GUI_MAIN widget list_add(win->widgets, gui_new_plain_widget(vec2(0, 0), win->ctx.size, win->ctx.bpp)); @@ -604,19 +595,22 @@ static void gui_destroy_window(u32 id) struct gui_window *win = gui_window_by_id(id); u8 *fb = win->ctx.fb - (win->off.y * win->ctx.pitch); assert(sys_free(fb) == EOK); + + struct message_destroy_window msg = { .id = id }; + gui_connect_wm(); + msg_send(GUI_DESTROY_WINDOW, &msg, sizeof(msg)); + + list_remove(windows, list_first_data(windows, win)); free(win); } -static void gui_destroy_all(void) +static void gui_destroy_windows(void) { struct node *iterator = windows->head; while (iterator) { struct gui_window *win = iterator->data; - struct message_destroy_window msg = { .id = win->id }; - gui_destroy_window(win->id); - gui_connect_wm(); - msg_send(GUI_DESTROY_WINDOW, &msg, sizeof(msg)); iterator = iterator->next; + gui_destroy_window(win->id); } list_destroy(windows); @@ -672,12 +666,21 @@ static void gui_handle_mouse(struct message_mouse *msg) widget.event.mouseclick(&event); } +static void gui_handle_destroy_window(struct message_destroy_window *msg) +{ + gui_destroy_window(msg->id); + if (!windows || !windows->head || !windows->head->data) { + log("No more windows, exiting\n"); + exit(0); + } +} + static void gui_handle_exit(void) { if (!windows) return; - gui_destroy_all(); + gui_destroy_windows(); } /** @@ -691,15 +694,18 @@ void gui_loop(void) if (!windows) err(1, "Create some windows first\n"); - void *msg = zalloc(4096); + u8 msg[4096] = { 0 }; while (gui_connect_wm(), msg_receive(msg, 4096) > 0) { - struct message_header *head = msg; + struct message_header *head = (void *)msg; switch (head->type) { case GUI_PING: - gui_handle_ping(msg); + gui_handle_ping((void *)msg); break; case GUI_MOUSE: - gui_handle_mouse(msg); + gui_handle_mouse((void *)msg); + break; + case GUI_DESTROY_WINDOW: + gui_handle_destroy_window((void *)msg); break; default: // TODO: Fix random unknown msg types @@ -707,6 +713,5 @@ void gui_loop(void) } } - free(msg); err(1, "Gui loop failed\n"); } diff --git a/libs/libgui/gui.h b/libs/libgui/gui.h index 66c6733..d9087f1 100644 --- a/libs/libgui/gui.h +++ b/libs/libgui/gui.h @@ -8,6 +8,8 @@ #include <libgui/gfx.h> #include <vec.h> +#define GUI_MAIN 0 // First widget is the main widget + enum gui_listener { GUI_LISTEN_MOUSEMOVE, GUI_LISTEN_MOUSECLICK, @@ -61,8 +63,7 @@ void gui_draw_line(u32 win_id, u32 widget_id, enum gui_layer layer, vec2 pos1, v * Widget operations */ -void gui_add_widget(u32 *widget, u32 win_id, u32 widget_id, vec2 pos, vec2 size); -void gui_new_widget(u32 *widget, u32 win_id, vec2 pos, vec2 size); +u32 gui_new_widget(u32 win_id, u32 widget_id, vec2 pos, vec2 size); void gui_listen_widget(u32 win_id, u32 widget_id, enum gui_listener listener, u32 func); void gui_redraw_widget(u32 win_id, u32 widget_id); |