aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Anderson <ascent12@hotmail.com>2017-09-28 23:16:35 +1300
committerScott Anderson <ascent12@hotmail.com>2017-09-29 16:15:09 +1300
commit6bf508df816750f41b9b0c362f5bc6f64f737a70 (patch)
tree6530979b7500f64e29961598b3e5e4b0f9d6f5a7
parentce76cfba0f36232256f42907616cb97b2cd38055 (diff)
Add closing with WM button
-rw-r--r--backend/x11/backend.c35
-rw-r--r--include/backend/x11.h11
2 files changed, 37 insertions, 9 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 773e51e6..8b0b3f0d 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -24,7 +24,7 @@ static struct wlr_input_device_impl input_impl;
static struct wlr_keyboard_impl keyboard_impl;
static struct wlr_pointer_impl pointer_impl;
-void handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) {
+static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) {
struct wlr_x11_output *output = &x11->output;
struct timespec ts;
@@ -151,35 +151,44 @@ void handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *event) {
wl_signal_emit(&x11->pointer.events.motion_absolute, &abs);
break;
}
- case XCB_MAP_NOTIFY:
- case XCB_REPARENT_NOTIFY:
- case XCB_GLX_GET_CONVOLUTION_FILTER:
+ case XCB_GLX_DELETE_QUERIES_ARB: {
+ wl_display_terminate(x11->wl_display);
+ return true;
break;
+ }
default:
- wlr_log(L_INFO, "Unknown event: %d", event->response_type);
break;
}
+
+ return false;
}
-int x11_event(int fd, uint32_t mask, void *data) {
+static int x11_event(int fd, uint32_t mask, void *data) {
struct wlr_x11_backend *x11 = data;
xcb_generic_event_t *e;
+ bool quit = false;
- while ((e = xcb_poll_for_event(x11->xcb_conn))) {
- handle_x11_event(x11, e);
+ while (!quit && (e = xcb_poll_for_event(x11->xcb_conn))) {
+ quit = handle_x11_event(x11, e);
free(e);
}
return 0;
}
-int signal_frame(void *data) {
+static int signal_frame(void *data) {
struct wlr_x11_backend *x11 = data;
wl_signal_emit(&x11->output.wlr_output.events.frame, &x11->output);
wl_event_source_timer_update(x11->frame_timer, 16);
return 0;
}
+static void init_atom(struct wlr_x11_backend *x11, struct wlr_x11_atom *atom,
+ uint8_t only_if_exists, const char *name) {
+ atom->cookie = xcb_intern_atom(x11->xcb_conn, only_if_exists, strlen(name), name);
+ atom->reply = xcb_intern_atom_reply(x11->xcb_conn, atom->cookie, NULL);
+}
+
struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
const char *x11_display) {
struct wlr_x11_backend *x11 = calloc(1, sizeof(*x11));
@@ -188,6 +197,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
}
wlr_backend_init(&x11->backend, &backend_impl);
+ x11->wl_display = display;
x11->xlib_conn = XOpenDisplay(x11_display);
if (!x11->xlib_conn) {
@@ -273,6 +283,13 @@ static bool wlr_x11_backend_start(struct wlr_backend *backend) {
return false;
}
+ init_atom(x11, &x11->atoms.wm_protocols, 1, "WM_PROTOCOLS");
+ init_atom(x11, &x11->atoms.wm_delete_window, 0, "WM_DELETE_WINDOW");
+
+ xcb_change_property(x11->xcb_conn, XCB_PROP_MODE_REPLACE, output->win,
+ x11->atoms.wm_protocols.reply->atom, XCB_ATOM_ATOM, 32, 1,
+ &x11->atoms.wm_delete_window.reply->atom);
+
xcb_map_window(x11->xcb_conn, output->win);
xcb_flush(x11->xcb_conn);
diff --git a/include/backend/x11.h b/include/backend/x11.h
index c46c944f..a22005a2 100644
--- a/include/backend/x11.h
+++ b/include/backend/x11.h
@@ -19,8 +19,14 @@ struct wlr_x11_output {
EGLSurface surf;
};
+struct wlr_x11_atom {
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
+};
+
struct wlr_x11_backend {
struct wlr_backend backend;
+ struct wl_display *wl_display;
Display *xlib_conn;
xcb_connection_t *xcb_conn;
@@ -37,6 +43,11 @@ struct wlr_x11_backend {
struct wlr_egl egl;
struct wl_event_source *event_source;
struct wl_event_source *frame_timer;
+
+ struct {
+ struct wlr_x11_atom wm_protocols;
+ struct wlr_x11_atom wm_delete_window;
+ } atoms;
};
#endif