aboutsummaryrefslogtreecommitdiff
path: root/backend/x11/backend.c
diff options
context:
space:
mode:
authorScott Anderson <scott@anderso.nz>2019-11-02 23:25:45 +1300
committerSimon Ser <contact@emersion.fr>2019-11-02 12:43:33 +0100
commita3c3b928a3814f1a44babf487b1508415958c721 (patch)
tree18a06e25133b18b508d5613c038bacc10c5f5da0 /backend/x11/backend.c
parentb81bb2ef3040e5cf3dcffbddcb5389775c879d85 (diff)
backend/x11: Give X11 a real rendering loop
Makes use of the present extension to get notified of vsync, and not require any stupid timer hacks. Also make use of the present version of ConfigureNotify, because why not?
Diffstat (limited to 'backend/x11/backend.c')
-rw-r--r--backend/x11/backend.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 26c56cab..9a7387ce 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -12,6 +12,7 @@
#include <X11/Xlib-xcb.h>
#include <wayland-server-core.h>
#include <xcb/xcb.h>
+#include <xcb/present.h>
#include <xcb/xfixes.h>
#include <xcb/xinput.h>
@@ -50,16 +51,6 @@ static void handle_x11_event(struct wlr_x11_backend *x11,
}
break;
}
- case XCB_CONFIGURE_NOTIFY: {
- xcb_configure_notify_event_t *ev =
- (xcb_configure_notify_event_t *)event;
- struct wlr_x11_output *output =
- get_x11_output_from_window_id(x11, ev->window);
- if (output != NULL) {
- handle_x11_configure_notify(output, ev);
- }
- break;
- }
case XCB_CLIENT_MESSAGE: {
xcb_client_message_event_t *ev = (xcb_client_message_event_t *)event;
if (ev->data.data32[0] == x11->atoms.wm_delete_window) {
@@ -73,7 +64,10 @@ static void handle_x11_event(struct wlr_x11_backend *x11,
}
case XCB_GE_GENERIC: {
xcb_ge_generic_event_t *ev = (xcb_ge_generic_event_t *)event;
- if (ev->extension == x11->xinput_opcode) {
+ if (ev->extension == x11->present_opcode) {
+ handle_x11_present_event(x11,
+ (xcb_present_generic_event_t *)ev);
+ } else if (ev->extension == x11->xinput_opcode) {
handle_x11_xinput_event(x11, ev);
}
}
@@ -224,6 +218,30 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
const xcb_query_extension_reply_t *ext;
+ /* Present extension */
+
+ ext = xcb_get_extension_data(x11->xcb, &xcb_present_id);
+ if (!ext || !ext->present) {
+ wlr_log(WLR_ERROR, "X11 does not support Present extension");
+ goto error_display;
+ }
+ x11->present_opcode = ext->major_opcode;
+
+ xcb_present_query_version_cookie_t present_cookie =
+ xcb_present_query_version(x11->xcb, 1, 2);
+ xcb_present_query_version_reply_t *present_reply =
+ xcb_present_query_version_reply(x11->xcb, present_cookie, NULL);
+
+ if (!present_reply || (present_reply->major_version <= 1 &&
+ present_reply->minor_version < 2)) {
+ wlr_log(WLR_ERROR, "X11 does not support required Present version");
+ free(present_reply);
+ goto error_display;
+ }
+ free(present_reply);
+
+ /* Xfixes extension */
+
ext = xcb_get_extension_data(x11->xcb, &xcb_xfixes_id);
if (!ext || !ext->present) {
wlr_log(WLR_ERROR, "X11 does not support Xfixes extension");
@@ -242,6 +260,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
}
free(fixes_reply);
+ /* Xinput extension */
+
ext = xcb_get_extension_data(x11->xcb, &xcb_input_id);
if (!ext || !ext->present) {
wlr_log(WLR_ERROR, "X11 does not support Xinput extension");