aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-07-16 00:25:20 +0100
committerHarry Jeffery <harry@exec64.co.uk>2019-07-16 00:26:49 +0100
commit364d14b3bd2e9d474a6e38bdce612d69a1286c9a (patch)
treee464eb08c70e041e7c830a652b58cfbbfcc30735 /src
parent2f79eb8965bfacfb438dde9ddd503eb2cb841443 (diff)
downloadimv-364d14b3bd2e9d474a6e38bdce612d69a1286c9a.tar.gz
x11: Use pipe for custom event notification
Diffstat (limited to 'src')
-rw-r--r--src/wl_window.c3
-rw-r--r--src/x11_window.c76
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);
}