mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-04 20:55:58 +01:00
cursor: add wlr_cursor_set_buffer()
A saner replacement for wlr_cursor_set_image(): - Takes a wlr_buffer instead of numerous parameters and a hardcoded format. - The scale is not used to filter outputs. - A ref to the buffer is kept to apply it to new outputs.
This commit is contained in:
parent
bb91787b5f
commit
71c87ff4b8
2 changed files with 64 additions and 2 deletions
|
@ -147,6 +147,15 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
|
|||
int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x,
|
||||
int32_t hotspot_y, float scale);
|
||||
|
||||
/**
|
||||
* Set the cursor buffer.
|
||||
*
|
||||
* The buffer is used on all outputs and is scaled accordingly. The hotspot is
|
||||
* expressed in logical coordinates. A NULL buffer hides the cursor.
|
||||
*/
|
||||
void wlr_cursor_set_buffer(struct wlr_cursor *cur, struct wlr_buffer *buffer,
|
||||
int32_t hotspot_x, int32_t hotspot_y, float scale);
|
||||
|
||||
/**
|
||||
* Hide the cursor image.
|
||||
*/
|
||||
|
|
|
@ -81,6 +81,13 @@ struct wlr_cursor_state {
|
|||
struct wl_listener layout_change;
|
||||
struct wl_listener layout_destroy;
|
||||
|
||||
// only when using a buffer as the cursor image
|
||||
struct wlr_buffer *buffer;
|
||||
struct {
|
||||
int32_t x, y;
|
||||
} buffer_hotspot;
|
||||
float buffer_scale;
|
||||
|
||||
// only when using a surface as the cursor image
|
||||
struct wlr_surface *surface;
|
||||
struct {
|
||||
|
@ -207,6 +214,9 @@ static void cursor_device_destroy(struct wlr_cursor_device *c_device) {
|
|||
}
|
||||
|
||||
static void cursor_reset_image(struct wlr_cursor *cur) {
|
||||
wlr_buffer_unlock(cur->state->buffer);
|
||||
cur->state->buffer = NULL;
|
||||
|
||||
if (cur->state->surface != NULL) {
|
||||
struct wlr_cursor_output_cursor *output_cursor;
|
||||
wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
|
||||
|
@ -430,6 +440,27 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
|
|||
|
||||
static void cursor_update_outputs(struct wlr_cursor *cur);
|
||||
|
||||
void wlr_cursor_set_buffer(struct wlr_cursor *cur, struct wlr_buffer *buffer,
|
||||
int32_t hotspot_x, int32_t hotspot_y, float scale) {
|
||||
if (buffer == cur->state->buffer &&
|
||||
hotspot_x == cur->state->buffer_hotspot.x &&
|
||||
hotspot_y == cur->state->buffer_hotspot.y &&
|
||||
scale == cur->state->buffer_scale) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor_reset_image(cur);
|
||||
|
||||
if (buffer != NULL) {
|
||||
cur->state->buffer = wlr_buffer_lock(buffer);
|
||||
cur->state->buffer_hotspot.x = hotspot_x;
|
||||
cur->state->buffer_hotspot.y = hotspot_y;
|
||||
cur->state->buffer_scale = scale;
|
||||
}
|
||||
|
||||
cursor_update_outputs(cur);
|
||||
}
|
||||
|
||||
void wlr_cursor_unset_image(struct wlr_cursor *cur) {
|
||||
cursor_reset_image(cur);
|
||||
cursor_update_outputs(cur);
|
||||
|
@ -489,8 +520,30 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
|||
|
||||
cursor_output_cursor_reset_image(output_cursor);
|
||||
|
||||
struct wlr_surface *surface = cur->state->surface;
|
||||
if (surface != NULL) {
|
||||
if (cur->state->buffer != NULL) {
|
||||
struct wlr_renderer *renderer = output_cursor->output_cursor->output->renderer;
|
||||
if (!renderer) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_buffer *buffer = cur->state->buffer;
|
||||
int32_t hotspot_x = cur->state->buffer_hotspot.x;
|
||||
int32_t hotspot_y = cur->state->buffer_hotspot.y;
|
||||
float scale = cur->state->buffer_scale;
|
||||
|
||||
struct wlr_texture *texture = NULL;
|
||||
if (buffer != NULL) {
|
||||
texture = wlr_texture_from_buffer(renderer, buffer);
|
||||
if (texture == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
output_cursor_set_texture(output_cursor->output_cursor, texture, true,
|
||||
scale, WL_OUTPUT_TRANSFORM_NORMAL, hotspot_x, hotspot_y);
|
||||
} else if (cur->state->surface != NULL) {
|
||||
struct wlr_surface *surface = cur->state->surface;
|
||||
|
||||
wl_signal_add(&output_cursor->output_cursor->output->events.commit,
|
||||
&output_cursor->output_commit);
|
||||
output_cursor->output_commit.notify = output_cursor_output_handle_output_commit;
|
||||
|
|
Loading…
Reference in a new issue