aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2023-11-13 18:16:22 +0100
committerFederico Angelilli <code@fedang.net>2023-11-13 18:16:22 +0100
commit818800377e039ad780ab3aa932872ab7306aae07 (patch)
treeff1f0f07edd39e5b26bf983405bee1ec2cb6cb8d
parentdc98ed4f21ddba80199b37c1d7617b92d4f6b056 (diff)
Display events and errors with `xcb-errors`
-rw-r--r--Makefile2
-rw-r--r--x11.c49
2 files changed, 37 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index da5c16d..e01374a 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ DEPS = \
xcb-icccm \
xcb-xrm \
xcb-ewmh \
- xcb-event \
+ xcb-errors \
"xcb-randr >= 1.5" \
"glib-2.0 >= 2.44" \
gio-2.0
diff --git a/x11.c b/x11.c
index b8e105b..d2eb233 100644
--- a/x11.c
+++ b/x11.c
@@ -7,8 +7,8 @@
#include <xcb/xcb_aux.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_xrm.h>
-#include <xcb/xcb_event.h>
#include <xcb/randr.h>
+#include <xcb/xcb_errors.h>
#include "x11.h"
#include "log.h"
@@ -20,6 +20,7 @@ struct Window {
xcb_screen_t *screen;
xcb_connection_t *connection;
xcb_xrm_database_t *database;
+ xcb_errors_context_t *errors;
xcb_drawable_t window;
xcb_visualtype_t *visual_type;
cairo_surface_t *surface;
@@ -65,21 +66,32 @@ static gboolean xcb_source_dispatch(GSource *source, GSourceFunc callback, gpoin
g_assert_nonnull(callback);
g_assert_nonnull(data);
+ Window *win = (Window *)data;
+
do {
switch (xsource->event->response_type & ~0x80) {
case 0: {
xcb_generic_error_t *error = (xcb_generic_error_t *)xsource->event;
- // TODO: This code crashes the program, so we should handle the errors
- log_warning("Xcb event loop error '%s' [type %d]",
- xcb_event_get_error_label(error->response_type),
- error->response_type);
+ const char *extension;
+ const char *name = xcb_errors_get_name_for_error(win->errors, error->error_code, &extension);
+ const char *major = xcb_errors_get_name_for_major_code(win->errors, error->major_code);
+ const char *minor = xcb_errors_get_name_for_minor_code(win->errors, error->major_code, error->minor_code);
+
+ // TODO: Handle errors instead of aborting
+ log_error("Xcb error '%s' [extension=%s, major=%s, minor=%s, resource=%u, sequence=%u]",
+ name,
+ extension ? extension : "none",
+ major,
+ minor ? minor : "none",
+ (unsigned int)error->resource_id,
+ (unsigned int)error->sequence);
break;
}
case XCB_EXPOSE: {
xcb_expose_event_t *expose = (xcb_expose_event_t *)xsource->event;
- log_debug("Processing event 'Expose' [type %d]", XCB_EXPOSE);
+ log_debug("Processing event 'Expose' [type=%d]", XCB_EXPOSE);
// Redraw
callback(data);
@@ -93,7 +105,7 @@ static gboolean xcb_source_dispatch(GSource *source, GSourceFunc callback, gpoin
case XCB_PROPERTY_NOTIFY: {
xcb_property_notify_event_t *property = (xcb_property_notify_event_t *)xsource->event;
- log_debug("Processing event 'PropertyNotify' [type %d]", XCB_PROPERTY_NOTIFY);
+ log_debug("Processing event 'PropertyNotify' [type=%d]", XCB_PROPERTY_NOTIFY);
if (property->atom == XCB_ATOM_RESOURCE_MANAGER) {
window_update_scale(data);
@@ -105,9 +117,13 @@ static gboolean xcb_source_dispatch(GSource *source, GSourceFunc callback, gpoin
}
default: {
- log_debug("Ignoring event '%s' [type %d]",
- xcb_event_get_label(xsource->event->response_type),
- XCB_EVENT_RESPONSE_TYPE(xsource->event));
+ const char *extension;
+ const char *name = xcb_errors_get_name_for_xcb_event(win->errors, xsource->event, &extension);
+
+ log_debug("Ignoring event '%s' [extension=%s, type=%d]",
+ name,
+ extension ? extension : "none",
+ xsource->event->response_type & 0x7f);
}
}
} while ((xsource->event = xcb_poll_for_event(xsource->win->connection)) != NULL);
@@ -189,7 +205,7 @@ Window *window_create(void)
win->x = win->y = 0;
xcb_randr_select_input(win->connection,
- win->window,
+ win->screen->root,
XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
@@ -199,6 +215,8 @@ Window *window_create(void)
window_update_scale(win);
+ g_assert(xcb_errors_context_new(win->connection, &win->errors) == 0);
+
xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(win->screen);
while (depth_iter.rem) {
xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
@@ -224,7 +242,7 @@ found_visual:
| XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS;
xcb_colormap_t colormap = xcb_generate_id(win->connection);
- xcb_create_colormap(win->connection, XCB_COLORMAP_ALLOC_NONE, colormap, win->screen->root, win->visual_type->visual_id);
+ xcb_create_colormap(win->connection, XCB_COLORMAP_ALLOC_NONE, colormap, win->screen->root, win->visual_type->visual_id);
log_debug("Xcb colormap created (id %u)", colormap);
const uint32_t value_list[] = {
@@ -269,11 +287,12 @@ found_visual:
screen_size->height);
g_assert_cmpint(cairo_surface_status(win->surface), ==, CAIRO_STATUS_SUCCESS);
+ log_debug("Cairo surface created");
win->cr = cairo_create(win->surface);
g_assert_cmpint(cairo_status(win->cr), ==, CAIRO_STATUS_SUCCESS);
+ log_debug("Cairo context created");
- log_debug("Cairo initialized");
attach_source(win);
log_debug("Xcb event loop attached");
@@ -297,8 +316,11 @@ void window_update_scale(Window *win)
g_free(dpi_value);
} else {
log_debug("Xrm query '%s' not found", dpi_res);
+
win->dpi = 96.0;
+ // TODO: Should we actually calculate the dpi depending on the screen size?
//win->dpi = (double)screen_size->height * 25.4 / (double)screen_size->mheight;
+
log_debug("Fallback dpi value '%.2lf'", win->dpi);
}
}
@@ -386,6 +408,7 @@ void window_destroy(Window *win)
cairo_destroy(win->cr);
cairo_surface_destroy(win->surface);
+ xcb_errors_context_free(win->errors);
xcb_xrm_database_free(win->database);
xcb_disconnect(win->connection);
g_free(win);