Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland: add cursor-shape-v1 support #11701

Merged
merged 1 commit into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions generated/wayland/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ if features['wayland_protocols_1_31']
protocols += [[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml']]
endif

features += {'wayland_protocols_1_32': wayland['deps'][2].version().version_compare('>=1.32')}
if features['wayland_protocols_1_32']
protocols += [[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml']] # required by cursor-shape
endif

foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
Expand Down
70 changes: 58 additions & 12 deletions video/out/wayland_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@
#include "generated/wayland/fractional-scale-v1.h"
#endif

#if HAVE_WAYLAND_PROTOCOLS_1_32
#include "generated/wayland/cursor-shape-v1.h"
#endif

#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 22
#define HAVE_WAYLAND_1_22
#endif
Expand Down Expand Up @@ -180,6 +184,7 @@ static int spawn_cursor(struct vo_wayland_state *wl);

static void add_feedback(struct vo_wayland_feedback_pool *fback_pool,
struct wp_presentation_feedback *fback);
static void get_shape_device(struct vo_wayland_state *wl);
static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b);
static void guess_focus(struct vo_wayland_state *wl);
static void remove_feedback(struct vo_wayland_feedback_pool *fback_pool,
Expand Down Expand Up @@ -482,6 +487,7 @@ static void seat_handle_caps(void *data, struct wl_seat *seat,

if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->pointer) {
wl->pointer = wl_seat_get_pointer(seat);
get_shape_device(wl);
wl_pointer_add_listener(wl->pointer, &pointer_listener, wl);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->pointer) {
wl_pointer_destroy(wl->pointer);
Expand Down Expand Up @@ -1295,6 +1301,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
}
#endif

#if HAVE_WAYLAND_PROTOCOLS_1_32
if (!strcmp(interface, wp_cursor_shape_manager_v1_interface.name) && found++) {
wl->cursor_shape_manager = wl_registry_bind(reg, id, &wp_cursor_shape_manager_v1_interface, 1);
}
#endif

if (!strcmp(interface, wp_presentation_interface.name) && found++) {
wl->presentation = wl_registry_bind(reg, id, &wp_presentation_interface, 1);
wp_presentation_add_listener(wl->presentation, &pres_listener, wl);
Expand Down Expand Up @@ -1529,7 +1541,18 @@ static int get_mods(struct vo_wayland_state *wl)
return modifiers;
}

static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b) {
static void get_shape_device(struct vo_wayland_state *wl)
{
#if HAVE_WAYLAND_PROTOCOLS_1_32
if (!wl->cursor_shape_device && wl->cursor_shape_manager) {
wl->cursor_shape_device = wp_cursor_shape_manager_v1_get_pointer(wl->cursor_shape_manager,
wl->pointer);
}
#endif
}

static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b)
{
// euclidean algorithm
int larger;
int smaller;
Expand Down Expand Up @@ -1673,21 +1696,33 @@ static void set_content_type(struct vo_wayland_state *wl)
#endif
}

static void set_cursor_shape(struct vo_wayland_state *wl)
{
#if HAVE_WAYLAND_PROTOCOLS_1_32
wp_cursor_shape_device_v1_set_shape(wl->cursor_shape_device, wl->pointer_id,
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
#endif
}

static int set_cursor_visibility(struct vo_wayland_state *wl, bool on)
{
wl->cursor_visible = on;
if (on) {
if (spawn_cursor(wl))
return VO_FALSE;
struct wl_cursor_image *img = wl->default_cursor->images[0];
struct wl_buffer *buffer = wl_cursor_image_get_buffer(img);
if (!buffer)
return VO_FALSE;
wl_pointer_set_cursor(wl->pointer, wl->pointer_id, wl->cursor_surface,
img->hotspot_x/wl->scaling, img->hotspot_y/wl->scaling);
wl_surface_set_buffer_scale(wl->cursor_surface, wl->scaling);
wl_surface_attach(wl->cursor_surface, buffer, 0, 0);
wl_surface_damage_buffer(wl->cursor_surface, 0, 0, img->width, img->height);
if (wl->cursor_shape_device) {
set_cursor_shape(wl);
} else {
if (spawn_cursor(wl))
return VO_FALSE;
struct wl_cursor_image *img = wl->default_cursor->images[0];
struct wl_buffer *buffer = wl_cursor_image_get_buffer(img);
if (!buffer)
return VO_FALSE;
wl_pointer_set_cursor(wl->pointer, wl->pointer_id, wl->cursor_surface,
img->hotspot_x/wl->scaling, img->hotspot_y/wl->scaling);
wl_surface_set_buffer_scale(wl->cursor_surface, wl->scaling);
wl_surface_attach(wl->cursor_surface, buffer, 0, 0);
wl_surface_damage_buffer(wl->cursor_surface, 0, 0, img->width, img->height);
}
wl_surface_commit(wl->cursor_surface);
} else {
wl_pointer_set_cursor(wl->pointer, wl->pointer_id, NULL, 0, 0);
Expand Down Expand Up @@ -1780,6 +1815,9 @@ static void set_window_bounds(struct vo_wayland_state *wl)

static int spawn_cursor(struct vo_wayland_state *wl)
{
/* Don't use this if we have cursor-shape. */
if (wl->cursor_shape_device)
return 0;
/* Reuse if size is identical */
if (!wl->pointer || wl->allocated_cursor_scale == wl->scaling)
return 0;
Expand Down Expand Up @@ -2315,6 +2353,14 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->subcompositor)
wl_subcompositor_destroy(wl->subcompositor);

#if HAVE_WAYLAND_PROTOCOLS_1_32
if (wl->cursor_shape_device)
wp_cursor_shape_device_v1_destroy(wl->cursor_shape_device);

if (wl->cursor_shape_manager)
wp_cursor_shape_manager_v1_destroy(wl->cursor_shape_manager);
#endif

if (wl->cursor_surface)
wl_surface_destroy(wl->cursor_surface);

Expand Down
5 changes: 5 additions & 0 deletions video/out/wayland_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ struct vo_wayland_state {
void *content_type;
int current_content_type;

/* cursor-shape */
/* TODO: unvoid these if required wayland protocols is bumped to 1.32+ */
void *cursor_shape_manager;
void *cursor_shape_device;

/* fractional-scale */
/* TODO: unvoid these if required wayland protocols is bumped to 1.31+ */
void *fractional_scale_manager;
Expand Down
5 changes: 5 additions & 0 deletions wscript
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,11 @@ video_output_features = [
'desc': 'wayland-protocols version 1.31+',
'deps': 'wayland',
'func': check_pkg_config('wayland-protocols >= 1.31'),
} , {
'name': 'wayland-protocols-1-32',
'desc': 'wayland-protocols version 1.32+',
'deps': 'wayland',
'func': check_pkg_config('wayland-protocols >= 1.32'),
} , {
'name': 'memfd_create',
'desc': "Linux's memfd_create()",
Expand Down
14 changes: 14 additions & 0 deletions wscript_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@ def build(ctx):
protocol = "staging/fractional-scale/fractional-scale-v1",
target = "generated/wayland/fractional-scale-v1.h")

if ctx.dependency_satisfied('wayland-protocols-1-32'):
ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "staging/cursor-shape/cursor-shape-v1",
target = "generated/wayland/cursor-shape-v1.c")
ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "staging/cursor-shape/cursor-shape-v1",
target = "generated/wayland/cursor-shape-v1.h")
ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "unstable/tablet/tablet-unstable-v2",
target = "generated/wayland/tablet-unstable-v2.c")
ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
protocol = "unstable/tablet/tablet-unstable-v2",
target = "generated/wayland/tablet-unstable-v2.h")

ctx(features = "ebml_header", target = "generated/ebml_types.h")
ctx(features = "ebml_definitions", target = "generated/ebml_defs.inc")

Expand Down