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
|
@ -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 stride, uint32_t width, uint32_t height, int32_t hotspot_x,
|
||||||
int32_t hotspot_y, float scale);
|
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.
|
* Hide the cursor image.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -81,6 +81,13 @@ struct wlr_cursor_state {
|
||||||
struct wl_listener layout_change;
|
struct wl_listener layout_change;
|
||||||
struct wl_listener layout_destroy;
|
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
|
// only when using a surface as the cursor image
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
struct {
|
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) {
|
static void cursor_reset_image(struct wlr_cursor *cur) {
|
||||||
|
wlr_buffer_unlock(cur->state->buffer);
|
||||||
|
cur->state->buffer = NULL;
|
||||||
|
|
||||||
if (cur->state->surface != NULL) {
|
if (cur->state->surface != NULL) {
|
||||||
struct wlr_cursor_output_cursor *output_cursor;
|
struct wlr_cursor_output_cursor *output_cursor;
|
||||||
wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
|
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);
|
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) {
|
void wlr_cursor_unset_image(struct wlr_cursor *cur) {
|
||||||
cursor_reset_image(cur);
|
cursor_reset_image(cur);
|
||||||
cursor_update_outputs(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);
|
cursor_output_cursor_reset_image(output_cursor);
|
||||||
|
|
||||||
|
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;
|
struct wlr_surface *surface = cur->state->surface;
|
||||||
if (surface != NULL) {
|
|
||||||
wl_signal_add(&output_cursor->output_cursor->output->events.commit,
|
wl_signal_add(&output_cursor->output_cursor->output->events.commit,
|
||||||
&output_cursor->output_commit);
|
&output_cursor->output_commit);
|
||||||
output_cursor->output_commit.notify = output_cursor_output_handle_output_commit;
|
output_cursor->output_commit.notify = output_cursor_output_handle_output_commit;
|
||||||
|
|
Loading…
Reference in New Issue