diff options
author | Harry Jeffery <harry@exec64.co.uk> | 2019-07-16 00:25:20 +0100 |
---|---|---|
committer | Harry Jeffery <harry@exec64.co.uk> | 2019-07-16 00:26:49 +0100 |
commit | 364d14b3bd2e9d474a6e38bdce612d69a1286c9a (patch) | |
tree | e464eb08c70e041e7c830a652b58cfbbfcc30735 /src | |
parent | 2f79eb8965bfacfb438dde9ddd503eb2cb841443 (diff) | |
download | imv-364d14b3bd2e9d474a6e38bdce612d69a1286c9a.tar.gz |
x11: Use pipe for custom event notification
Diffstat (limited to 'src')
-rw-r--r-- | src/wl_window.c | 3 | ||||
-rw-r--r-- | src/x11_window.c | 76 |
2 files changed, 55 insertions, 24 deletions
diff --git a/src/wl_window.c b/src/wl_window.c index 4a2f134..c3dcb88 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -3,7 +3,6 @@ #include <assert.h> #include <poll.h> #include <pthread.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -640,7 +639,7 @@ void imv_window_wait_for_event(struct imv_window *window, double timeout) wl_display_cancel_read(window->wl_display); } - /* Clear the eventfd if hit */ + /* Clear the pipe if hit */ if (fds[1].revents & POLLIN) { char out[32]; read(window->pipe_fds[0], &out, sizeof out); diff --git a/src/x11_window.c b/src/x11_window.c index 19c7601..2388654 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1,13 +1,16 @@ #include "window.h" -#include <GL/gl.h> -#include <GL/glx.h> -#include <X11/Xlib.h> -#include <X11/Xatom.h> #include <assert.h> #include <poll.h> +#include <pthread.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> + +#include <GL/gl.h> +#include <GL/glx.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> struct imv_window { Display *x_display; @@ -26,6 +29,15 @@ struct imv_window { } current; bool mouse1; } pointer; + + int pipe_fds[2]; + + struct { + struct imv_event *queue; + size_t len; + size_t cap; + pthread_mutex_t mutex; + } events; }; struct imv_window *imv_window_create(int w, int h, const char *title) @@ -33,6 +45,10 @@ struct imv_window *imv_window_create(int w, int h, const char *title) struct imv_window *window = calloc(1, sizeof *window); window->pointer.last.x = -1; window->pointer.last.y = -1; + pipe(window->pipe_fds); + window->events.cap = 128; + window->events.queue = malloc(window->events.cap * sizeof *window->events.queue); + pthread_mutex_init(&window->events.mutex, NULL); window->x_display = XOpenDisplay(NULL); assert(window->x_display); @@ -77,6 +93,10 @@ struct imv_window *imv_window_create(int w, int h, const char *title) void imv_window_free(struct imv_window *window) { + close(window->pipe_fds[0]); + close(window->pipe_fds[1]); + pthread_mutex_destroy(&window->events.mutex); + free(window->events.queue); glXDestroyContext(window->x_display, window->x_glc); XCloseDisplay(window->x_display); free(window); @@ -186,22 +206,36 @@ void imv_window_wait_for_event(struct imv_window *window, double timeout) { struct pollfd fds[] = { {.fd = ConnectionNumber(window->x_display), .events = POLLIN}, + {.fd = window->pipe_fds[0], .events = POLLIN} }; nfds_t nfds = sizeof fds / sizeof *fds; poll(fds, nfds, timeout * 1000); + + /* Clear the pipe if hit */ + if (fds[1].revents & POLLIN) { + char out[32]; + read(window->pipe_fds[0], &out, sizeof out); + } } void imv_window_push_event(struct imv_window *window, struct imv_event *e) { - XEvent xe = { - .xclient = { - .type = ClientMessage, - .format = 8 - } - }; - memcpy(&xe.xclient.data.l[0], &e->data.custom, sizeof(void*)); - XSendEvent(window->x_display, window->x_window, True, 0xfff, &xe); + pthread_mutex_lock(&window->events.mutex); + if (window->events.len == window->events.cap) { + size_t new_cap = window->events.cap * 2; + struct imv_event *new_queue = + realloc(window->events.queue, new_cap * sizeof *window->events.queue); + assert(new_queue); + window->events.queue = new_queue; + } + + window->events.queue[window->events.len++] = *e; + pthread_mutex_unlock(&window->events.mutex); + + /* Wake up wait_events */ + char in = 1; + write(window->pipe_fds[1], &in, sizeof in); } void imv_window_pump_events(struct imv_window *window, imv_event_handler handler, void *data) @@ -301,18 +335,16 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler if (handler) { handler(data, &e); } - } else if (xev.type == ClientMessage) { - struct imv_event e = { - .type = IMV_EVENT_CUSTOM, - .data = { - .custom = (void*)*((void**)&xev.xclient.data.l[0]) - } - }; - if (handler) { - handler(data, &e); - } } } + pthread_mutex_lock(&window->events.mutex); + if (handler) { + for (size_t i = 0; i < window->events.len; ++i) { + handler(data, &window->events.queue[i]); + } + } + window->events.len = 0; + pthread_mutex_unlock(&window->events.mutex); } |