From 3f44d16f5297a0f7d63f98e48eba46c1e2538a3e Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 23 Oct 2023 20:10:01 +0200 Subject: WindowServer/LibGUI: Add a eventloop This can be used by any program does nothing until it gets user input. --- userland/libgui/libgui.c | 27 +++++++++++++++++++++++++-- userland/libgui/libgui.h | 4 ++++ userland/windowserver/ws.c | 23 +++++++++++++++-------- userland/windowserver/ws.h | 3 +++ 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/userland/libgui/libgui.c b/userland/libgui/libgui.c index 5f5526d..a344778 100644 --- a/userland/libgui/libgui.c +++ b/userland/libgui/libgui.c @@ -2,6 +2,7 @@ #include "font.h" #include #include +#include #include #include #include @@ -155,7 +156,6 @@ char *random_string(void) { } close(fd); r[9] = '\0'; - printf("r: %s\n", r); return r; } @@ -230,7 +230,30 @@ typedef struct { void GUI_ClearScreen(GUI_Window *w, uint32_t color) { for (int i = 0; i < w->sx * w->sy; i++) - w->bitmap_ptr[i] =color; + w->bitmap_ptr[i] = color; +} + +void GUI_EventLoop(GUI_Window *w, void (*event_handler)(WS_EVENT ev)) { + struct pollfd fds[1]; + fds[0].fd = w->ws_socket; + fds[0].events = POLLIN; + fds[0].revents = 0; + for (;; fds[0].revents = 0) { + poll(fds, 1, 0); + if (!(fds[0].revents & POLLIN)) + continue; + + int rc; + WS_EVENT e; + if (0 >= (rc = read(w->ws_socket, &e, sizeof(e)))) + continue; + if (event_handler) { + event_handler(e); + continue; + } + if (WINDOWSERVER_EVENT_WINDOW_EXIT == e.type) + exit(0); + } } GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy) { diff --git a/userland/libgui/libgui.h b/userland/libgui/libgui.h index d58c23c..07fd3db 100644 --- a/userland/libgui/libgui.h +++ b/userland/libgui/libgui.h @@ -3,6 +3,9 @@ #include #include +#define WINDOWSERVER_EVENT_KEYPRESS 0 +#define WINDOWSERVER_EVENT_WINDOW_EXIT 1 + typedef struct { int ws_socket; int bitmap_fd; @@ -31,4 +34,5 @@ void GUI_UpdateWindow(GUI_Window *w); void GUI_OverwriteFont(GUI_Window *w, uint32_t px, uint32_t py, const uint32_t color); void GUI_ClearScreen(GUI_Window *w, uint32_t color); +void GUI_EventLoop(GUI_Window *w, void (*event_handler)(WS_EVENT ev)); #endif diff --git a/userland/windowserver/ws.c b/userland/windowserver/ws.c index 2211b00..3d6e10f 100644 --- a/userland/windowserver/ws.c +++ b/userland/windowserver/ws.c @@ -1,13 +1,12 @@ -#include -#include -#include -#include -//#include +#include "ws.h" #include "draw.h" #include "font.h" -#include "ws.h" #include +#include +#include #include +#include +#include #include #include #include @@ -193,7 +192,7 @@ typedef struct { struct KEY_EVENT ev; } WS_EVENT; -void send_to_window(struct KEY_EVENT ev) { +void send_key_event_to_window(struct KEY_EVENT ev) { WS_EVENT e = { .type = 0, .ev = ev, @@ -221,6 +220,13 @@ int windowserver_key_events(struct KEY_EVENT ev, int *redraw) { return 0; if (!(ev.mode & (1 << 1))) return 0; + if ('q' == ev.c) { + WS_EVENT e = { + .type = WINDOWSERVER_EVENT_WINDOW_EXIT, + }; + write(main_display.active_window->fd, &e, sizeof(e)); + return 1; + } if ('n' == ev.c) { // Create a new terminal int pid = fork(); @@ -230,6 +236,7 @@ int windowserver_key_events(struct KEY_EVENT ev, int *redraw) { execv("/term", argv); assert(0); } + return 1; } if (!main_display.active_window) return 0; @@ -344,7 +351,7 @@ void parse_keyboard_event(int fd) { continue; if (!main_display.active_window) continue; - send_to_window(ev[i]); + send_key_event_to_window(ev[i]); } } if (redraw) diff --git a/userland/windowserver/ws.h b/userland/windowserver/ws.h index 9236e01..241c960 100644 --- a/userland/windowserver/ws.h +++ b/userland/windowserver/ws.h @@ -3,6 +3,9 @@ #include #include +#define WINDOWSERVER_EVENT_KEYPRESS 0 +#define WINDOWSERVER_EVENT_WINDOW_EXIT 1 + typedef struct { int fd; int bitmap_fd; -- cgit v1.2.3