From bdaf66a292ed77b3589ad5d4c4cf2bbf484df840 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 00:03:55 +0100 Subject: [PATCH 1/7] Set xwayland root cursor --- meson.build | 1 + xwayland/meson.build | 1 + xwayland/xwm.c | 36 +++++++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 74bb6dcd..e37250a7 100644 --- a/meson.build +++ b/meson.build @@ -52,6 +52,7 @@ pixman = dependency('pixman-1') xcb = dependency('xcb') xcb_composite = dependency('xcb-composite') xcb_xfixes = dependency('xcb-xfixes') +xcb_image = dependency('xcb-image') xcb_icccm = dependency('xcb-icccm', required: false) x11_xcb = dependency('x11-xcb') libcap = dependency('libcap', required: false) diff --git a/xwayland/meson.build b/xwayland/meson.build index a05ae584..669a0984 100644 --- a/xwayland/meson.build +++ b/xwayland/meson.build @@ -11,6 +11,7 @@ lib_wlr_xwayland = static_library( xcb, xcb_composite, xcb_xfixes, + xcb_image, xcb_icccm, pixman, ], diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 4930d45c..b6a49574 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "wlr/util/log.h" #include "wlr/types/wlr_surface.h" #include "wlr/xwayland.h" @@ -1220,15 +1221,40 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm_get_resources(xwm); xwm_get_visual_and_colormap(xwm); - uint32_t values[1]; - values[0] = + xcb_cursor_t cursor = xcb_generate_id(xwm->xcb_conn); + + { + // Create root cursor + + uint8_t data[] = { + 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x03, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x03, + 0xfe, 0x07, 0xfe, 0x0f, 0xfe, 0x1f, 0xe6, 0x0f, 0xc2, 0x07, 0x80, 0x03, + 0x00, 0x01, 0x00, 0x00 + }; + + uint8_t mask[] = { + 0xff, 0x3f, 0xff, 0x1f, 0xff, 0x07, 0xff, 0x03, 0xff, 0x03, 0xff, 0x07, + 0xff, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0xff, 0x1f, 0xe7, 0x0f, 0xc3, 0x07, + 0x83, 0x03, 0x01, 0x01 + }; + + xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, data, 14, 14, 1, 0, 0, 0); + xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, mask, 14, 14, 1, 0, 0, 0); + xcb_create_cursor(xwm->xcb_conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0); + xcb_free_pixmap(xwm->xcb_conn, cp); + xcb_free_pixmap(xwm->xcb_conn, mp); + } + + uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | - XCB_EVENT_MASK_PROPERTY_CHANGE; + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | + XCB_EVENT_MASK_PROPERTY_CHANGE, + cursor, + }; xcb_change_window_attributes(xwm->xcb_conn, xwm->screen->root, - XCB_CW_EVENT_MASK /* | XCB_CW_CURSOR */, + XCB_CW_EVENT_MASK | XCB_CW_CURSOR, values); xcb_composite_redirect_subwindows(xwm->xcb_conn, From f31fea79779e7ad119a7cd75340f6f51df7cebcf Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 00:19:51 +0100 Subject: [PATCH 2/7] Fix CI build --- .build.yml | 1 + .travis.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.build.yml b/.build.yml index 60412f0e..7ba5559c 100644 --- a/.build.yml +++ b/.build.yml @@ -6,6 +6,7 @@ packages: - mesa - libinput - libxkbcommon + - xcb-util-image - libcap - pixman - clang diff --git a/.travis.yml b/.travis.yml index 52d6eae4..f6bbd7f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ arch: - libinput - pixman - libxkbcommon + - xcb-util-image - libcap script: - "meson build" From 4254c28138e33e0dfc7661f39a08a3be5a6f03a6 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 11:09:14 +0100 Subject: [PATCH 3/7] Free xwm cursor in xwm_destroy --- xwayland/xwm.c | 11 ++++++----- xwayland/xwm.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index b6a49574..8f324411 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1036,6 +1036,9 @@ void xwm_destroy(struct wlr_xwm *xwm) { if (!xwm) { return; } + if (xwm->cursor) { + xcb_free_cursor(xwm->xcb_conn, xwm->cursor); + } if (xwm->event_source) { wl_event_source_remove(xwm->event_source); } @@ -1098,7 +1101,6 @@ static void xwm_get_resources(struct wlr_xwm *xwm) { xfixes_reply->major_version, xfixes_reply->minor_version); free(xfixes_reply); - } static void xwm_create_wm_window(struct wlr_xwm *xwm) { @@ -1221,8 +1223,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm_get_resources(xwm); xwm_get_visual_and_colormap(xwm); - xcb_cursor_t cursor = xcb_generate_id(xwm->xcb_conn); - + xwm->cursor = xcb_generate_id(xwm->xcb_conn); { // Create root cursor @@ -1240,7 +1241,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, data, 14, 14, 1, 0, 0, 0); xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, mask, 14, 14, 1, 0, 0, 0); - xcb_create_cursor(xwm->xcb_conn, cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0); + xcb_create_cursor(xwm->xcb_conn, xwm->cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0); xcb_free_pixmap(xwm->xcb_conn, cp); xcb_free_pixmap(xwm->xcb_conn, mp); } @@ -1249,7 +1250,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_PROPERTY_CHANGE, - cursor, + xwm->cursor, }; xcb_change_window_attributes(xwm->xcb_conn, diff --git a/xwayland/xwm.h b/xwayland/xwm.h index 7d30d278..ba1ed3c2 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -49,6 +49,7 @@ struct wlr_xwm { xcb_window_t window; xcb_visualid_t visual_id; xcb_colormap_t colormap; + xcb_cursor_t cursor; struct wlr_xwayland_surface *focus_surface; From ddd7b7711cabcabe73db6446bc02965fc645b244 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 15:52:02 +0100 Subject: [PATCH 4/7] Load xwm cursor from theme --- meson.build | 1 + xwayland/meson.build | 1 + xwayland/xwm.c | 91 ++++++++++++++++++++++++++++++++------------ 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/meson.build b/meson.build index e37250a7..642dc38d 100644 --- a/meson.build +++ b/meson.build @@ -53,6 +53,7 @@ xcb = dependency('xcb') xcb_composite = dependency('xcb-composite') xcb_xfixes = dependency('xcb-xfixes') xcb_image = dependency('xcb-image') +xcb_render = dependency('xcb-render') xcb_icccm = dependency('xcb-icccm', required: false) x11_xcb = dependency('x11-xcb') libcap = dependency('libcap', required: false) diff --git a/xwayland/meson.build b/xwayland/meson.build index 669a0984..e92e042c 100644 --- a/xwayland/meson.build +++ b/xwayland/meson.build @@ -12,6 +12,7 @@ lib_wlr_xwayland = static_library( xcb_composite, xcb_xfixes, xcb_image, + xcb_render, xcb_icccm, pixman, ], diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 8f324411..8b94a199 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -6,9 +6,11 @@ #include #include #include +#include #include "wlr/util/log.h" #include "wlr/types/wlr_surface.h" #include "wlr/xwayland.h" +#include "wlr/xcursor.h" #include "xwm.h" #ifdef HAS_XCB_ICCCM @@ -1186,6 +1188,60 @@ static void xwm_get_visual_and_colormap(struct wlr_xwm *xwm) { xwm->visual_id); } +void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, + uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) { + if (xwm->cursor) { + xcb_free_cursor(xwm->xcb_conn, xwm->cursor); + } + + int depth = 32; + + xcb_pixmap_t pix = xcb_generate_id(xwm->xcb_conn); + xcb_create_pixmap(xwm->xcb_conn, depth, pix, xwm->screen->root, width, + height); + + xcb_render_query_pict_formats_cookie_t cookie = + xcb_render_query_pict_formats(xwm->xcb_conn); + xcb_generic_error_t *err = NULL; + xcb_render_query_pict_formats_reply_t *reply = + xcb_render_query_pict_formats_reply(xwm->xcb_conn, cookie, &err); + xcb_render_pictforminfo_t *formats = + xcb_render_query_pict_formats_formats(reply); + int len = xcb_render_query_pict_formats_formats_length(reply); + xcb_render_pictforminfo_t *format = NULL; + for (int i = 0; i < len; ++i) { + if (formats[i].depth == depth) { + format = &formats[i]; + break; + } + // TODO: segfaults when not found + } + if (format == NULL) { + wlr_log(L_ERROR, "Cannot find %d-bit depth render format", depth); + return; + } + + xcb_render_picture_t pic = xcb_generate_id(xwm->xcb_conn); + xcb_render_create_picture(xwm->xcb_conn, pic, pix, format->id, 0, 0); + + xcb_gcontext_t gc = xcb_generate_id(xwm->xcb_conn); + xcb_create_gc(xwm->xcb_conn, gc, pix, 0, NULL); + + xcb_put_image(xwm->xcb_conn, XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc, + width, height, 0, 0, 0, depth, stride * height * sizeof(uint8_t), + pixels); + xcb_free_gc(xwm->xcb_conn, gc); + + xwm->cursor = xcb_generate_id(xwm->xcb_conn); + xcb_render_create_cursor(xwm->xcb_conn, xwm->cursor, pic, hotspot_x, + hotspot_y); + xcb_free_pixmap(xwm->xcb_conn, pix); + + uint32_t values[] = {xwm->cursor}; + xcb_change_window_attributes(xwm->xcb_conn, xwm->screen->root, + XCB_CW_CURSOR, values); +} + struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { struct wlr_xwm *xwm = calloc(1, sizeof(struct wlr_xwm)); if (xwm == NULL) { @@ -1223,39 +1279,24 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm_get_resources(xwm); xwm_get_visual_and_colormap(xwm); - xwm->cursor = xcb_generate_id(xwm->xcb_conn); - { - // Create root cursor - - uint8_t data[] = { - 0x00, 0x00, 0xfe, 0x07, 0xfe, 0x03, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x03, - 0xfe, 0x07, 0xfe, 0x0f, 0xfe, 0x1f, 0xe6, 0x0f, 0xc2, 0x07, 0x80, 0x03, - 0x00, 0x01, 0x00, 0x00 - }; - - uint8_t mask[] = { - 0xff, 0x3f, 0xff, 0x1f, 0xff, 0x07, 0xff, 0x03, 0xff, 0x03, 0xff, 0x07, - 0xff, 0x0f, 0xff, 0x1f, 0xff, 0x3f, 0xff, 0x1f, 0xe7, 0x0f, 0xc3, 0x07, - 0x83, 0x03, 0x01, 0x01 - }; - - xcb_pixmap_t cp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, data, 14, 14, 1, 0, 0, 0); - xcb_pixmap_t mp = xcb_create_pixmap_from_bitmap_data(xwm->xcb_conn, xwm->screen->root, mask, 14, 14, 1, 0, 0, 0); - xcb_create_cursor(xwm->xcb_conn, xwm->cursor, cp, mp, 0, 0, 0, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0); - xcb_free_pixmap(xwm->xcb_conn, cp); - xcb_free_pixmap(xwm->xcb_conn, mp); - } + // TODO + struct wlr_xcursor_theme *xcursor_theme = + wlr_xcursor_theme_load("default", 16); + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(xcursor_theme, "left_ptr"); + struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; + xwm_set_cursor(xwm, xcursor_image->buffer, 4 * xcursor_image->width, + xcursor_image->width, xcursor_image->height, xcursor_image->hotspot_x, + xcursor_image->hotspot_y); uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_PROPERTY_CHANGE, - xwm->cursor, }; - xcb_change_window_attributes(xwm->xcb_conn, xwm->screen->root, - XCB_CW_EVENT_MASK | XCB_CW_CURSOR, + XCB_CW_EVENT_MASK, values); xcb_composite_redirect_subwindows(xwm->xcb_conn, From 3f4ad47421721c5df576e1a99e487a28a6318f82 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 16:49:22 +0100 Subject: [PATCH 5/7] Use compositor theme for xwm cursor --- include/wlr/xwayland.h | 6 ++++++ rootston/input.c | 9 +++++++++ xwayland/xwayland.c | 40 ++++++++++++++++++++++++++++++++++++++++ xwayland/xwm.c | 12 ++---------- xwayland/xwm.h | 7 +++++-- 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 2d968133..bea97394 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -12,6 +12,7 @@ #endif struct wlr_xwm; +struct wlr_xwayland_cursor; struct wlr_xwayland { pid_t pid; @@ -25,6 +26,7 @@ struct wlr_xwayland { struct wl_event_source *sigusr1_source; struct wl_listener destroy_listener; struct wlr_xwm *xwm; + struct wlr_xwayland_cursor *cursor; struct { struct wl_signal new_surface; @@ -148,6 +150,10 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland); +void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland, + uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height, + int32_t hotspot_x, int32_t hotspot_y); + void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland, struct wlr_xwayland_surface *surface, bool activated); diff --git a/rootston/input.c b/rootston/input.c index 8109d2b6..5d367a5e 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" @@ -96,6 +97,14 @@ struct roots_input *input_create(struct roots_server *server, return NULL; } + if (server->desktop->xwayland != NULL) { + struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; + wlr_xwayland_set_cursor(server->desktop->xwayland, + xcursor_image->buffer, xcursor_image->width, xcursor_image->width, + xcursor_image->height, xcursor_image->hotspot_x, + xcursor_image->hotspot_y); + } + input->wl_seat = wlr_seat_create(server->wl_display, "seat0"); if (input->wl_seat == NULL) { wlr_log(L_ERROR, "Cannot create seat"); diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 81bac2ce..0452f04c 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -29,6 +29,15 @@ static inline int clearenv(void) { } #endif +struct wlr_xwayland_cursor { + uint8_t *pixels; + uint32_t stride; + uint32_t width; + uint32_t height; + int32_t hotspot_x; + int32_t hotspot_y; +}; + static void safe_close(int fd) { if (fd >= 0) { close(fd); @@ -190,6 +199,14 @@ static int xserver_handle_ready(int signal_number, void *data) { wl_event_source_remove(wlr_xwayland->sigusr1_source); wlr_xwayland->sigusr1_source = NULL; + if (wlr_xwayland->cursor != NULL) { + struct wlr_xwayland_cursor *cur = wlr_xwayland->cursor; + xwm_set_cursor(wlr_xwayland->xwm, cur->pixels, cur->stride, cur->width, + cur->height, cur->hotspot_x, cur->hotspot_y); + free(cur); + wlr_xwayland->cursor = NULL; + } + char display_name[16]; snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); setenv("DISPLAY", display_name, true); @@ -298,3 +315,26 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, free(wlr_xwayland); return NULL; } + +void wlr_xwayland_set_cursor(struct wlr_xwayland *wlr_xwayland, + uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height, + int32_t hotspot_x, int32_t hotspot_y) { + if (wlr_xwayland->xwm != NULL) { + xwm_set_cursor(wlr_xwayland->xwm, pixels, stride, width, height, + hotspot_x, hotspot_y); + return; + } + + free(wlr_xwayland->cursor); + + wlr_xwayland->cursor = calloc(1, sizeof(struct wlr_xwayland_cursor)); + if (wlr_xwayland->cursor == NULL) { + return; + } + wlr_xwayland->cursor->pixels = pixels; + wlr_xwayland->cursor->stride = stride; + wlr_xwayland->cursor->width = width; + wlr_xwayland->cursor->height = height; + wlr_xwayland->cursor->hotspot_x = hotspot_x; + wlr_xwayland->cursor->hotspot_y = hotspot_y; +} diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 8b94a199..9d6bc347 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1194,6 +1194,7 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, xcb_free_cursor(xwm->xcb_conn, xwm->cursor); } + stride *= 4; int depth = 32; xcb_pixmap_t pix = xcb_generate_id(xwm->xcb_conn); @@ -1240,6 +1241,7 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, uint32_t values[] = {xwm->cursor}; xcb_change_window_attributes(xwm->xcb_conn, xwm->screen->root, XCB_CW_CURSOR, values); + xcb_flush(xwm->xcb_conn); } struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { @@ -1279,16 +1281,6 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm_get_resources(xwm); xwm_get_visual_and_colormap(xwm); - // TODO - struct wlr_xcursor_theme *xcursor_theme = - wlr_xcursor_theme_load("default", 16); - struct wlr_xcursor *xcursor = - wlr_xcursor_theme_get_cursor(xcursor_theme, "left_ptr"); - struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; - xwm_set_cursor(xwm, xcursor_image->buffer, 4 * xcursor_image->width, - xcursor_image->width, xcursor_image->height, xcursor_image->hotspot_x, - xcursor_image->hotspot_y); - uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | diff --git a/xwayland/xwm.h b/xwayland/xwm.h index ba1ed3c2..d3911ecd 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -61,8 +61,11 @@ struct wlr_xwm { struct wl_listener compositor_surface_create; }; -void xwm_destroy(struct wlr_xwm *xwm); - struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); +void xwm_destroy(struct wlr_xwm *xwm); + +void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, + uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y); + #endif From bb76f5264080be36138ec7c3e4dc3d83ed37d858 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 16:59:57 +0100 Subject: [PATCH 6/7] Fetch xcb_render_pictformat_t at startup --- xwayland/xwm.c | 55 +++++++++++++++++++++++++++++--------------------- xwayland/xwm.h | 3 +++ 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 9d6bc347..9b75879e 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1175,7 +1175,7 @@ static void xwm_get_visual_and_colormap(struct wlr_xwm *xwm) { } if (visualtype == NULL) { - wlr_log(L_DEBUG, "no 32 bit visualtype\n"); + wlr_log(L_DEBUG, "No 32 bit visualtype\n"); return; } @@ -1188,8 +1188,36 @@ static void xwm_get_visual_and_colormap(struct wlr_xwm *xwm) { xwm->visual_id); } +static void xwm_get_render_format(struct wlr_xwm *xwm) { + xcb_render_query_pict_formats_cookie_t cookie = + xcb_render_query_pict_formats(xwm->xcb_conn); + xcb_render_query_pict_formats_reply_t *reply = + xcb_render_query_pict_formats_reply(xwm->xcb_conn, cookie, NULL); + xcb_render_pictforminfo_t *formats = + xcb_render_query_pict_formats_formats(reply); + int len = xcb_render_query_pict_formats_formats_length(reply); + xcb_render_pictforminfo_t *format = NULL; + for (int i = 0; i < len; ++i) { + if (formats[i].depth == 32) { + format = &formats[i]; + break; + } + // TODO: segfaults when not found + } + if (format == NULL) { + wlr_log(L_DEBUG, "No 32 bit render format"); + return; + } + + xwm->render_format_id = format->id; +} + void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, int32_t hotspot_y) { + if (!xwm->render_format_id) { + wlr_log(L_ERROR, "Cannot set xwm cursor: no render format available"); + return; + } if (xwm->cursor) { xcb_free_cursor(xwm->xcb_conn, xwm->cursor); } @@ -1201,29 +1229,9 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride, xcb_create_pixmap(xwm->xcb_conn, depth, pix, xwm->screen->root, width, height); - xcb_render_query_pict_formats_cookie_t cookie = - xcb_render_query_pict_formats(xwm->xcb_conn); - xcb_generic_error_t *err = NULL; - xcb_render_query_pict_formats_reply_t *reply = - xcb_render_query_pict_formats_reply(xwm->xcb_conn, cookie, &err); - xcb_render_pictforminfo_t *formats = - xcb_render_query_pict_formats_formats(reply); - int len = xcb_render_query_pict_formats_formats_length(reply); - xcb_render_pictforminfo_t *format = NULL; - for (int i = 0; i < len; ++i) { - if (formats[i].depth == depth) { - format = &formats[i]; - break; - } - // TODO: segfaults when not found - } - if (format == NULL) { - wlr_log(L_ERROR, "Cannot find %d-bit depth render format", depth); - return; - } - xcb_render_picture_t pic = xcb_generate_id(xwm->xcb_conn); - xcb_render_create_picture(xwm->xcb_conn, pic, pix, format->id, 0, 0); + xcb_render_create_picture(xwm->xcb_conn, pic, pix, xwm->render_format_id, + 0, 0); xcb_gcontext_t gc = xcb_generate_id(xwm->xcb_conn); xcb_create_gc(xwm->xcb_conn, gc, pix, 0, NULL); @@ -1280,6 +1288,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm_get_resources(xwm); xwm_get_visual_and_colormap(xwm); + xwm_get_render_format(xwm); uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | diff --git a/xwayland/xwm.h b/xwayland/xwm.h index d3911ecd..547cd5eb 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -1,5 +1,7 @@ #ifndef XWAYLAND_INTERNALS_H #define XWAYLAND_INTERNALS_H + +#include #include #include @@ -49,6 +51,7 @@ struct wlr_xwm { xcb_window_t window; xcb_visualid_t visual_id; xcb_colormap_t colormap; + xcb_render_pictformat_t render_format_id; xcb_cursor_t cursor; struct wlr_xwayland_surface *focus_surface; From 900fb326f7608695a160a2ce645db94f33df7f87 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 17:21:00 +0100 Subject: [PATCH 7/7] Fixes segfault when no xcb_render_pictforminfo_t is available --- xwayland/xwm.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 9b75879e..f011587e 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -1193,17 +1193,18 @@ static void xwm_get_render_format(struct wlr_xwm *xwm) { xcb_render_query_pict_formats(xwm->xcb_conn); xcb_render_query_pict_formats_reply_t *reply = xcb_render_query_pict_formats_reply(xwm->xcb_conn, cookie, NULL); - xcb_render_pictforminfo_t *formats = - xcb_render_query_pict_formats_formats(reply); - int len = xcb_render_query_pict_formats_formats_length(reply); + xcb_render_pictforminfo_iterator_t iter = + xcb_render_query_pict_formats_formats_iterator(reply); xcb_render_pictforminfo_t *format = NULL; - for (int i = 0; i < len; ++i) { - if (formats[i].depth == 32) { - format = &formats[i]; + while (iter.rem > 0) { + if (iter.data->depth == 32) { + format = iter.data; break; } - // TODO: segfaults when not found + + xcb_render_pictforminfo_next(&iter); } + if (format == NULL) { wlr_log(L_DEBUG, "No 32 bit render format"); return;