bar/wayland: cursor support

This implements backend.set_cursor().
This commit is contained in:
Daniel Eklöf 2019-02-03 13:13:10 +01:00
parent 130043a259
commit 47ac57dd03
2 changed files with 65 additions and 3 deletions

View file

@ -26,7 +26,7 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(XCB REQUIRED xcb xcb-aux xcb-cursor xcb-event xcb-ewmh pkg_check_modules(XCB REQUIRED xcb xcb-aux xcb-cursor xcb-event xcb-ewmh
xcb-randr xcb-render) xcb-randr xcb-render)
pkg_check_modules(XCB_ERRORS xcb-errors) pkg_check_modules(XCB_ERRORS xcb-errors)
pkg_check_modules(WAYLAND REQUIRED wayland-client wlroots) pkg_check_modules(WAYLAND REQUIRED wayland-client wayland-cursor wlroots)
pkg_check_modules(FONTCONFIG REQUIRED fontconfig) pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
pkg_check_modules(CAIRO REQUIRED cairo cairo-xcb cairo-ft) pkg_check_modules(CAIRO REQUIRED cairo cairo-xcb cairo-ft)
pkg_check_modules(YAML REQUIRED yaml-0.1) pkg_check_modules(YAML REQUIRED yaml-0.1)

View file

@ -12,6 +12,7 @@
#include <cairo.h> #include <cairo.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <wayland-cursor.h>
#include <wlr-layer-shell-unstable-v1-client.h> #include <wlr-layer-shell-unstable-v1-client.h>
@ -45,8 +46,14 @@ struct wayland_backend {
struct { struct {
struct wl_pointer *pointer; struct wl_pointer *pointer;
uint32_t serial;
int x; int x;
int y; int y;
struct wl_surface *surface;
struct wl_cursor_theme *theme;
struct wl_cursor *cursor;
} pointer; } pointer;
/* TODO: set directly in bar instead */ /* TODO: set directly in bar instead */
@ -79,11 +86,37 @@ static const struct wl_shm_listener shm_listener = {
.format = &shm_format, .format = &shm_format,
}; };
static void
update_cursor_surface(struct wayland_backend *backend)
{
assert(backend->pointer.cursor != NULL);
struct wl_cursor_image *image = backend->pointer.cursor->images[0];
wl_surface_attach(
backend->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0);
wl_pointer_set_cursor(
backend->pointer.pointer, backend->pointer.serial,
backend->pointer.surface, image->hotspot_x, image->hotspot_y);
wl_surface_damage_buffer(
backend->pointer.surface, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_commit(backend->pointer.surface);
}
static void static void
wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
uint32_t serial, struct wl_surface *surface, uint32_t serial, struct wl_surface *surface,
wl_fixed_t surface_x, wl_fixed_t surface_y) wl_fixed_t surface_x, wl_fixed_t surface_y)
{ {
struct wayland_backend *backend = data;
backend->pointer.serial = serial;
backend->pointer.x = wl_fixed_to_int(surface_x);
backend->pointer.y = wl_fixed_to_int(surface_y);
update_cursor_surface(backend);
} }
static void static void
@ -100,6 +133,10 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
//printf("MOTION: %dx%d\n", wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); //printf("MOTION: %dx%d\n", wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
backend->pointer.x = wl_fixed_to_int(surface_x); backend->pointer.x = wl_fixed_to_int(surface_x);
backend->pointer.y = wl_fixed_to_int(surface_y); backend->pointer.y = wl_fixed_to_int(surface_y);
write(backend->pipe_fds[1], &(uint8_t){3}, sizeof(uint8_t));
write(backend->pipe_fds[1], &backend->pointer.x, sizeof(backend->pointer.x));
write(backend->pipe_fds[1], &backend->pointer.y, sizeof(backend->pointer.y));
} }
static void static void
@ -324,11 +361,18 @@ setup(struct bar *_bar)
wl_display_roundtrip(backend->display); wl_display_roundtrip(backend->display);
assert(backend->compositor != NULL && assert(backend->compositor != NULL &&
backend->layer_shell != NULL && backend->layer_shell != NULL &&
backend->output != NULL); backend->output != NULL &&
backend->shm != NULL);
backend->surface = wl_compositor_create_surface(backend->compositor); backend->surface = wl_compositor_create_surface(backend->compositor);
assert(backend->surface != NULL); assert(backend->surface != NULL);
backend->pointer.surface = wl_compositor_create_surface(backend->compositor);
assert(backend->pointer.surface != NULL);
backend->pointer.theme = wl_cursor_theme_load(NULL, 24, backend->shm);
assert(backend->pointer.theme != NULL);
backend->layer_surface = zwlr_layer_shell_v1_get_layer_surface( backend->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
backend->layer_shell, backend->surface, backend->output, backend->layer_shell, backend->surface, backend->output,
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "f00bar"); ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "f00bar");
@ -394,8 +438,12 @@ cleanup(struct bar *_bar)
zwlr_layer_surface_v1_destroy(backend->layer_surface); zwlr_layer_surface_v1_destroy(backend->layer_surface);
zwlr_layer_shell_v1_destroy(backend->layer_shell); zwlr_layer_shell_v1_destroy(backend->layer_shell);
wl_compositor_destroy(backend->compositor); wl_cursor_theme_destroy(backend->pointer.theme);
wl_pointer_destroy(backend->pointer.pointer);
wl_surface_destroy(backend->pointer.surface);
wl_surface_destroy(backend->surface); wl_surface_destroy(backend->surface);
wl_seat_destroy(backend->seat);
wl_compositor_destroy(backend->compositor);
wl_shm_destroy(backend->shm); wl_shm_destroy(backend->shm);
wl_output_destroy(backend->output); wl_output_destroy(backend->output);
wl_registry_destroy(backend->registry); wl_registry_destroy(backend->registry);
@ -473,6 +521,13 @@ loop(struct bar *_bar,
read(backend->pipe_fds[0], &y, sizeof(y)); read(backend->pipe_fds[0], &y, sizeof(y));
on_mouse(_bar, ON_MOUSE_CLICK, x, y); on_mouse(_bar, ON_MOUSE_CLICK, x, y);
} }
if (command == 3) {
int x, y;
read(backend->pipe_fds[0], &x, sizeof(x));
read(backend->pipe_fds[0], &y, sizeof(y));
on_mouse(_bar, ON_MOUSE_MOTION, x, y);
}
continue; continue;
} }
@ -575,6 +630,13 @@ refresh(const struct bar *_bar)
static void static void
set_cursor(struct bar *_bar, const char *cursor) set_cursor(struct bar *_bar, const char *cursor)
{ {
struct private *bar = _bar->private;
struct wayland_backend *backend = bar->backend.data;
backend->pointer.cursor = wl_cursor_theme_get_cursor(
backend->pointer.theme, cursor);
update_cursor_surface(backend);
} }
const struct backend wayland_backend_iface = { const struct backend wayland_backend_iface = {