aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2020-11-18 19:06:45 +0100
committerSimon Ser <contact@emersion.fr>2020-11-24 14:57:25 +0100
commit52805feae9bd6332c972065c799f4ac3b7ef2275 (patch)
tree27f13a8bb445fa6a176363e7539243fa0b0a7049
parent262740bc9a282554c8aacb001e06aeb96d0afdce (diff)
backend/x11: log errors
Register an X11 error handler, and optionally use xcb-errors to print a detailed message.
-rw-r--r--backend/x11/backend.c56
-rw-r--r--include/backend/x11.h11
2 files changed, 66 insertions, 1 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 6dc650ab..4472396e 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -38,6 +38,8 @@ struct wlr_x11_output *get_x11_output_from_window_id(
return NULL;
}
+static void handle_x11_error(struct wlr_x11_backend *x11, xcb_value_error_t *ev);
+
static void handle_x11_event(struct wlr_x11_backend *x11,
xcb_generic_event_t *event) {
switch (event->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) {
@@ -76,6 +78,12 @@ static void handle_x11_event(struct wlr_x11_backend *x11,
if (ev->extension == x11->xinput_opcode) {
handle_x11_xinput_event(x11, ev);
}
+ break;
+ }
+ case 0: {
+ xcb_value_error_t *ev = (xcb_value_error_t *)event;
+ handle_x11_error(x11, ev);
+ break;
}
}
}
@@ -140,6 +148,10 @@ static void backend_destroy(struct wlr_backend *backend) {
wlr_renderer_destroy(x11->renderer);
wlr_egl_finish(&x11->egl);
+#if WLR_HAS_XCB_ERRORS
+ xcb_errors_context_free(x11->errors_context);
+#endif
+
if (x11->xlib_conn) {
XCloseDisplay(x11->xlib_conn);
}
@@ -296,6 +308,13 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
goto error_event;
}
+#if WLR_HAS_XCB_ERRORS
+ if (xcb_errors_context_new(x11->xcb, &x11->errors_context) != 0) {
+ wlr_log(WLR_ERROR, "Failed to create error context");
+ return false;
+ }
+#endif
+
wlr_input_device_init(&x11->keyboard_dev, WLR_INPUT_DEVICE_KEYBOARD,
&input_device_impl, "X11 keyboard", 0, 0);
wlr_keyboard_init(&x11->keyboard, &keyboard_impl);
@@ -314,3 +333,40 @@ error_x11:
free(x11);
return NULL;
}
+
+static void handle_x11_error(struct wlr_x11_backend *x11, xcb_value_error_t *ev) {
+#if WLR_HAS_XCB_ERRORS
+ const char *major_name = xcb_errors_get_name_for_major_code(
+ x11->errors_context, ev->major_opcode);
+ if (!major_name) {
+ wlr_log(WLR_DEBUG, "X11 error happened, but could not get major name");
+ goto log_raw;
+ }
+
+ const char *minor_name = xcb_errors_get_name_for_minor_code(
+ x11->errors_context, ev->major_opcode, ev->minor_opcode);
+
+ const char *extension;
+ const char *error_name = xcb_errors_get_name_for_error(x11->errors_context,
+ ev->error_code, &extension);
+ if (!error_name) {
+ wlr_log(WLR_DEBUG, "X11 error happened, but could not get error name");
+ goto log_raw;
+ }
+
+ wlr_log(WLR_ERROR, "X11 error: op %s (%s), code %s (%s), "
+ "sequence %"PRIu16", value %"PRIu32,
+ major_name, minor_name ? minor_name : "no minor",
+ error_name, extension ? extension : "no extension",
+ ev->sequence, ev->bad_value);
+
+ return;
+
+log_raw:
+#endif
+
+ wlr_log(WLR_ERROR, "X11 error: op %"PRIu8":%"PRIu16", code %"PRIu8", "
+ "sequence %"PRIu16", value %"PRIu32,
+ ev->major_opcode, ev->minor_opcode, ev->error_code,
+ ev->sequence, ev->bad_value);
+}
diff --git a/include/backend/x11.h b/include/backend/x11.h
index 03396361..7ce3ed98 100644
--- a/include/backend/x11.h
+++ b/include/backend/x11.h
@@ -1,14 +1,19 @@
#ifndef BACKEND_X11_H
#define BACKEND_X11_H
+#include <wlr/config.h>
+
#include <stdbool.h>
#include <X11/Xlib-xcb.h>
#include <wayland-server-core.h>
#include <xcb/xcb.h>
+#if WLR_HAS_XCB_ERRORS
+#include <xcb/xcb_errors.h>
+#endif
+
#include <wlr/backend/x11.h>
-#include <wlr/config.h>
#include <wlr/interfaces/wlr_input_device.h>
#include <wlr/interfaces/wlr_keyboard.h>
#include <wlr/interfaces/wlr_output.h>
@@ -81,6 +86,10 @@ struct wlr_x11_backend {
// The time we last received an event
xcb_timestamp_t time;
+#if WLR_HAS_XCB_ERRORS
+ xcb_errors_context_t *errors_context;
+#endif
+
uint8_t xinput_opcode;
struct wl_listener display_destroy;