diff options
author | Simon Ser <contact@emersion.fr> | 2020-11-18 19:06:45 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2020-11-24 14:57:25 +0100 |
commit | 52805feae9bd6332c972065c799f4ac3b7ef2275 (patch) | |
tree | 27f13a8bb445fa6a176363e7539243fa0b0a7049 | |
parent | 262740bc9a282554c8aacb001e06aeb96d0afdce (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.c | 56 | ||||
-rw-r--r-- | include/backend/x11.h | 11 |
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; |