aboutsummaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/libc/list.c3
-rw-r--r--libs/libgui/gfx.c2
-rw-r--r--libs/libgui/gui.c53
-rw-r--r--libs/libgui/gui.h5
4 files changed, 35 insertions, 28 deletions
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);