diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | x11.c | 49 |
2 files changed, 37 insertions, 14 deletions
@@ -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 @@ -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); |
