From 0beae99188d7885bed15eef548acf6b2a9fb9f79 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 31 Oct 2017 18:00:33 +0100 Subject: Apply output transformation to pointer events in Wayland backend --- include/wlr/interfaces/wlr_output.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index d365e8f5..1f6c60eb 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -2,6 +2,7 @@ #define WLR_INTERFACES_WLR_OUTPUT_H #include +#include #include #include @@ -31,4 +32,7 @@ struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output, struct wl_display *display); void wlr_output_destroy_global(struct wlr_output *wlr_output); +void wlr_output_transform_apply_to_box(enum wl_output_transform transform, + struct wlr_box *box, struct wlr_box *dest); + #endif -- cgit v1.2.3 From 60c018c01760bef047d156a60e9ab32799a26f14 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 1 Nov 2017 14:25:41 +0100 Subject: Fix hidden software cursors, fix cursor transformations on DRM backend --- backend/drm/drm.c | 65 ++++++++++++++++++------------------- backend/wayland/output.c | 1 + include/wlr/interfaces/wlr_output.h | 1 + rootston/config.c | 4 ++- types/wlr_output.c | 17 +++++++--- 5 files changed, 50 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index cfaaae21..137ca85e 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -558,17 +558,28 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output, } } - struct wlr_box hotspot_box = { - .width = plane->surf.width, - .height = plane->surf.height, - .x = hotspot_x, - .y = hotspot_y, - }; - struct wlr_box transformed_hotspot_box; - wlr_output_transform_apply_to_box(output->transform, - &hotspot_box, &transformed_hotspot_box); - plane->cursor_hotspot_x = transformed_hotspot_box.x; - plane->cursor_hotspot_y = transformed_hotspot_box.y; + switch (output->transform) { + case WL_OUTPUT_TRANSFORM_NORMAL: + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + plane->cursor_hotspot_x = hotspot_x; + plane->cursor_hotspot_y = -plane->surf.height + hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_180: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + plane->cursor_hotspot_x = -plane->surf.width + hotspot_x; + plane->cursor_hotspot_y = -plane->surf.height + hotspot_y; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED: + case WL_OUTPUT_TRANSFORM_270: + plane->cursor_hotspot_x = -plane->surf.width + hotspot_x; + plane->cursor_hotspot_y = hotspot_y; + break; + } if (!update_pixels) { // Only update the cursor hotspot @@ -621,30 +632,18 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output, x -= plane->cursor_hotspot_x; y -= plane->cursor_hotspot_y; - int width, height, tmp; - wlr_output_effective_resolution(output, &width, &height); + struct wlr_box box; + box.x = x; + box.y = y; + wlr_output_effective_resolution(output, &box.width, &box.height); - switch (output->transform) { - case WL_OUTPUT_TRANSFORM_NORMAL: - case WL_OUTPUT_TRANSFORM_FLIPPED: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - // nothing to do - break; - case WL_OUTPUT_TRANSFORM_270: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - tmp = x; - x = y; - y = -(tmp - width); - break; - case WL_OUTPUT_TRANSFORM_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - tmp = x; - x = -(y - height); - y = tmp; - break; - } + enum wl_output_transform transform = + wlr_output_transform_invert(output->transform); + struct wlr_box transformed_box; + wlr_output_transform_apply_to_box(transform, &box, &transformed_box); - return drm->iface->crtc_move_cursor(drm, conn->crtc, x, y); + return drm->iface->crtc_move_cursor(drm, conn->crtc, transformed_box.x, + transformed_box.y); } static void wlr_drm_connector_destroy(struct wlr_output *output) { diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 494e0522..fd20b3e3 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -59,6 +59,7 @@ static bool wlr_wl_output_set_cursor(struct wlr_output *_output, (struct wlr_wl_backend_output *)_output; struct wlr_wl_backend *backend = output->backend; + // TODO: use output->wlr_output.transform to transform pixels and hotpot output->cursor.hotspot_x = hotspot_x; output->cursor.hotspot_y = hotspot_y; diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 1f6c60eb..b4f39d35 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -34,5 +34,6 @@ void wlr_output_destroy_global(struct wlr_output *wlr_output); void wlr_output_transform_apply_to_box(enum wl_output_transform transform, struct wlr_box *box, struct wlr_box *dest); +enum wl_output_transform wlr_output_transform_invert(enum wl_output_transform); #endif diff --git a/rootston/config.c b/rootston/config.c index b3fd4f01..d72c1284 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -228,7 +228,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(name, "y") == 0) { oc->y = strtol(value, NULL, 10); } else if (strcmp(name, "rotate") == 0) { - if (strcmp(value, "90") == 0) { + if (strcmp(value, "normal") == 0) { + oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; + } else if (strcmp(value, "90") == 0) { oc->transform = WL_OUTPUT_TRANSFORM_90; } else if (strcmp(value, "180") == 0) { oc->transform = WL_OUTPUT_TRANSFORM_180; diff --git a/types/wlr_output.c b/types/wlr_output.c index 08d32963..6e36ae12 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -267,8 +267,8 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { struct wlr_box output_box; output_box.x = output_box.y = 0; - output_box.width = cursor->output->width; - output_box.height = cursor->output->height; + wlr_output_effective_resolution(cursor->output, &output_box.width, + &output_box.height); struct wlr_box cursor_box; output_cursor_get_box(cursor, &cursor_box); @@ -294,7 +294,7 @@ void wlr_output_swap_buffers(struct wlr_output *output) { struct wlr_output_cursor *cursor; wl_list_for_each(cursor, &output->cursors, link) { if (output->hardware_cursor == cursor) { - continue; + //continue; // TODO } output_cursor_render(cursor); } @@ -342,7 +342,7 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, stride, width, height, hotspot_x, hotspot_y, true); if (ok) { cursor->output->hardware_cursor = cursor; - return true; + //return true; // TODO } } @@ -546,3 +546,12 @@ void wlr_output_transform_apply_to_box(enum wl_output_transform transform, break; } } + +enum wl_output_transform wlr_output_transform_invert( + enum wl_output_transform transform) { + if ((transform & WL_OUTPUT_TRANSFORM_90) && + !(transform & WL_OUTPUT_TRANSFORM_FLIPPED)) { + transform ^= WL_OUTPUT_TRANSFORM_180; + } + return transform; +} -- cgit v1.2.3 From 0df7a3c22d3d6c2bc8969f1c4e4d10e2aa148325 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 1 Nov 2017 18:15:37 +0100 Subject: Add wlr_seat_pointer_request_set_cursor_event.serial --- include/wlr/types/wlr_seat.h | 1 + types/wlr_seat.c | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b1872a3d..b8b467d2 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -142,6 +142,7 @@ struct wlr_seat { struct wlr_seat_pointer_request_set_cursor_event { struct wlr_seat_client *seat_client; struct wlr_surface *surface; + uint32_t serial; int32_t hotspot_x, hotspot_y; }; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 1e01c058..bdea96ac 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -43,6 +43,7 @@ static void wl_pointer_set_cursor(struct wl_client *client, } event->seat_client = seat_client; event->surface = surface; + event->serial = serial; event->hotspot_x = hotspot_x; event->hotspot_y = hotspot_y; -- cgit v1.2.3 From e18460c9811a8c9b0283aec330500f536747d078 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 1 Nov 2017 20:08:15 +0100 Subject: Add wlr_output.needs_swap --- include/wlr/types/wlr_output.h | 7 ++++--- types/wlr_output.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index f9bce91f..b5523100 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -1,9 +1,9 @@ #ifndef WLR_TYPES_WLR_OUTPUT_H #define WLR_TYPES_WLR_OUTPUT_H +#include #include #include -#include struct wlr_output_mode { uint32_t flags; // enum wl_output_mode @@ -44,8 +44,9 @@ struct wlr_output { uint32_t scale; int32_t width, height; int32_t phys_width, phys_height; // mm - int32_t subpixel; // enum wl_output_subpixel - int32_t transform; // enum wl_output_transform + enum wl_output_subpixel subpixel; + enum wl_output_transform transform; + bool needs_swap; float transform_matrix[16]; diff --git a/types/wlr_output.c b/types/wlr_output.c index 93d4de93..85e3d05e 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -291,6 +291,8 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { } void wlr_output_swap_buffers(struct wlr_output *output) { + wl_signal_emit(&output->events.swap_buffers, &output); + struct wlr_output_cursor *cursor; wl_list_for_each(cursor, &output->cursors, link) { if (output->hardware_cursor == cursor) { @@ -299,9 +301,8 @@ void wlr_output_swap_buffers(struct wlr_output *output) { output_cursor_render(cursor); } - wl_signal_emit(&output->events.swap_buffers, &output); - output->impl->swap_buffers(output); + output->needs_swap = false; } void wlr_output_set_gamma(struct wlr_output *output, @@ -319,6 +320,9 @@ uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { } static void output_cursor_reset(struct wlr_output_cursor *cursor) { + if (cursor->output->hardware_cursor != cursor) { + cursor->output->needs_swap = true; + } if (cursor->surface != NULL) { wl_list_remove(&cursor->surface_commit.link); wl_list_remove(&cursor->surface_destroy.link); @@ -347,6 +351,7 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, } wlr_log(L_INFO, "Falling back to software cursor"); + cursor->output->needs_swap = true; if (cursor->renderer == NULL) { cursor->renderer = wlr_gles2_renderer_create(cursor->output->backend); @@ -370,7 +375,11 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) { cursor->width = cursor->surface->current->width; cursor->height = cursor->surface->current->height; - // TODO: if hardware cursor, upload pixels + if (cursor->output->hardware_cursor != cursor) { + cursor->output->needs_swap = true; + } else { + // TODO: upload pixels + } } static inline int64_t timespec_to_msec(const struct timespec *a) { -- cgit v1.2.3 From d11973ed7d6881cbef879d505829b16be04b03f4 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 11:37:43 +0100 Subject: Fix disabled cursors --- include/wlr/types/wlr_output.h | 2 ++ types/wlr_output.c | 28 +++++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index b5523100..e6323f9c 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -15,10 +15,12 @@ struct wlr_output_mode { struct wlr_output_cursor { struct wlr_output *output; int32_t x, y; + bool enabled; uint32_t width, height; int32_t hotspot_x, hotspot_y; struct wl_list link; + // only when using a software cursor without a surface struct wlr_renderer *renderer; struct wlr_texture *texture; diff --git a/types/wlr_output.c b/types/wlr_output.c index 85e3d05e..d4c6b2fe 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -253,10 +253,6 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { struct wlr_texture *texture = cursor->texture; struct wlr_renderer *renderer = cursor->renderer; if (cursor->surface != NULL) { - // Some clients commit a cursor surface with a NULL buffer to hide it. - if (!wlr_surface_has_buffer(cursor->surface)) { - return; - } texture = cursor->surface->texture; renderer = cursor->surface->renderer; } @@ -295,7 +291,7 @@ void wlr_output_swap_buffers(struct wlr_output *output) { struct wlr_output_cursor *cursor; wl_list_for_each(cursor, &output->cursors, link) { - if (output->hardware_cursor == cursor) { + if (!cursor->enabled || output->hardware_cursor == cursor) { continue; } output_cursor_render(cursor); @@ -353,6 +349,11 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, wlr_log(L_INFO, "Falling back to software cursor"); cursor->output->needs_swap = true; + cursor->enabled = pixels != NULL; + if (!cursor->enabled) { + return true; + } + if (cursor->renderer == NULL) { cursor->renderer = wlr_gles2_renderer_create(cursor->output->backend); if (cursor->renderer == NULL) { @@ -372,6 +373,8 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, } static void output_cursor_commit(struct wlr_output_cursor *cursor) { + // Some clients commit a cursor surface with a NULL buffer to hide it. + cursor->enabled = wlr_surface_has_buffer(cursor->surface); cursor->width = cursor->surface->current->width; cursor->height = cursor->surface->current->height; @@ -418,10 +421,6 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, return; } - if (surface) { - cursor->width = surface->current->width; - cursor->height = surface->current->height; - } cursor->hotspot_x = hotspot_x; cursor->hotspot_y = hotspot_y; @@ -454,6 +453,10 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, wl_signal_add(&surface->events.destroy, &cursor->surface_destroy); output_cursor_commit(cursor); } else { + cursor->enabled = false; + cursor->width = 0; + cursor->height = 0; + // TODO: if hardware cursor, disable cursor } } @@ -463,6 +466,7 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { cursor->y = y; if (cursor->output->hardware_cursor != cursor) { + cursor->output->needs_swap = true; return true; } @@ -500,12 +504,6 @@ void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { } cursor->output->hardware_cursor = NULL; } - if (cursor->texture != NULL) { - wlr_texture_destroy(cursor->texture); - } - if (cursor->renderer != NULL) { - wlr_renderer_destroy(cursor->renderer); - } wl_list_remove(&cursor->link); free(cursor); } -- cgit v1.2.3 From 3f4ad47421721c5df576e1a99e487a28a6318f82 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 2 Nov 2017 16:49:22 +0100 Subject: 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 | 5 ++++- 5 files changed, 61 insertions(+), 11 deletions(-) (limited to 'include') 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; }; +struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); + void xwm_destroy(struct wlr_xwm *xwm); -struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland); +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 -- cgit v1.2.3