mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-04 13:29:45 -05:00
Add new output cursor API
This commit is contained in:
parent
b2d717dccc
commit
f5e5b3eec3
3 changed files with 147 additions and 7 deletions
|
|
@ -25,6 +25,9 @@ struct wlr_output_impl {
|
||||||
bool (*move_cursor)(struct wlr_output *output, int x, int y);
|
bool (*move_cursor)(struct wlr_output *output, int x, int y);
|
||||||
void (*destroy)(struct wlr_output *output);
|
void (*destroy)(struct wlr_output *output);
|
||||||
bool (*attach_render)(struct wlr_output *output, int *buffer_age);
|
bool (*attach_render)(struct wlr_output *output, int *buffer_age);
|
||||||
|
bool (*cursor_try_set_size)(struct wlr_output *output, int *x, int *y);
|
||||||
|
bool (*cursor_attach_render)(struct wlr_output *output, int *buffer_age);
|
||||||
|
bool (*cursor_commit)(struct wlr_output *output);
|
||||||
bool (*commit)(struct wlr_output *output);
|
bool (*commit)(struct wlr_output *output);
|
||||||
bool (*set_gamma)(struct wlr_output *output, size_t size,
|
bool (*set_gamma)(struct wlr_output *output, size_t size,
|
||||||
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
const uint16_t *r, const uint16_t *g, const uint16_t *b);
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,20 @@ struct wlr_output_state {
|
||||||
struct wlr_buffer *buffer; // if WLR_OUTPUT_STATE_BUFFER_SCANOUT
|
struct wlr_buffer *buffer; // if WLR_OUTPUT_STATE_BUFFER_SCANOUT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wlr_output_cursor_field {
|
||||||
|
WLR_OUTPUT_CURSOR_BUFFER = 1 << 0,
|
||||||
|
WLR_OUTPUT_CURSOR_ENABLE = 1 << 1,
|
||||||
|
WLR_OUTPUT_CURSOR_POS = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_output_cursor {
|
||||||
|
uint32_t committed; // enum wlr_output_cursor_state_field
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
int x, y;
|
||||||
|
int hotspot_x, hotspot_y;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_output_impl;
|
struct wlr_output_impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,6 +105,7 @@ struct wlr_output {
|
||||||
float transform_matrix[9];
|
float transform_matrix[9];
|
||||||
|
|
||||||
struct wlr_output_state pending;
|
struct wlr_output_state pending;
|
||||||
|
struct wlr_output_cursor cursor_pending;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// Request to render a frame
|
// Request to render a frame
|
||||||
|
|
@ -280,13 +295,90 @@ void wlr_output_lock_attach_render(struct wlr_output *output, bool lock);
|
||||||
*/
|
*/
|
||||||
void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
|
void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock);
|
||||||
|
|
||||||
#if 0
|
/**
|
||||||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
* Hardware cursors:
|
||||||
const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
|
*
|
||||||
int32_t hotspot_x, int32_t hotspot_y);
|
* Hardware cursors are a feature of GPUs that allow a small framebuffer
|
||||||
bool wlr_output_cursor_move(struct wlr_output_cursor *cursor,
|
* to be displayed over the main framebuffer. This is more efficient than
|
||||||
double x, double y);
|
* drawing onto the main framebuffer using e.g. OpenGL.
|
||||||
#endif
|
*
|
||||||
|
* Not every backend/output will support hardware cursors, so you must always
|
||||||
|
* be prepared to fall back to rendering the cursor to the main framebuffer
|
||||||
|
* yourself.
|
||||||
|
*
|
||||||
|
* Hardware cursors are always in output buffer coordinates, and does not take
|
||||||
|
* scale nor rotation into account. You are responsible for doing this
|
||||||
|
* yourself.
|
||||||
|
*
|
||||||
|
* Hardware cursors are always in the ARGB8888 format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the size of the hardware cursor buffer to the values pointed to by
|
||||||
|
* x and y.
|
||||||
|
*
|
||||||
|
* Some backends have strict requirements for the cursor size and may not be
|
||||||
|
* able to use the size you requested exactly. The actual value used will be
|
||||||
|
* left in x and y. If this is not large enough for the cursor you wish to
|
||||||
|
* draw, you should fall back to using software cursors.
|
||||||
|
*
|
||||||
|
* This returns false if the backend does not support hardware cursors or from
|
||||||
|
* some other internal error. Either way, you should fall back to using
|
||||||
|
* software cursors.
|
||||||
|
*/
|
||||||
|
bool wlr_output_cursor_try_set_size(struct wlr_output *output, int *x, int *y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the renderer to the cursor buffer.
|
||||||
|
*
|
||||||
|
* You must successfully call `wlr_output_cursor_try_set_size` at least once
|
||||||
|
* before using this. Any rendering done will be applied on
|
||||||
|
* `wlr_output_cursor_commit`.
|
||||||
|
*/
|
||||||
|
bool wlr_output_cursor_attach_render(struct wlr_output *output, int *buffer_age);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables displaying the hardware cursor.
|
||||||
|
*
|
||||||
|
* This does not affect the ability to render to the cursor. It only sets
|
||||||
|
* whether or not it will be displayed. By default, the cursor is disabled.
|
||||||
|
*
|
||||||
|
* This will be applied on `wlr_output_cursor_commit`.
|
||||||
|
*/
|
||||||
|
void wlr_output_cursor_enable(struct wlr_output *output, bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position of the hardware cursor on the main framebuffer.
|
||||||
|
*
|
||||||
|
* This is in output buffer coordinates. Negative values and values that would
|
||||||
|
* place the cursor partially or entirely off the main framebuffer are allowed.
|
||||||
|
*
|
||||||
|
* The hotspot is the point on the cursor buffer (from the top left) where the
|
||||||
|
* cursor actually points. For example, with a cursor representing a hand, the
|
||||||
|
* hotspot may be over the index finger, rather than the top left corner.
|
||||||
|
*
|
||||||
|
* Some backends may not be able to move the cursor freely, but may still be
|
||||||
|
* able to make use of the hotspot to correctly show the cursor.
|
||||||
|
*
|
||||||
|
* This will be applied on `wlr_output_cursor_commit`.
|
||||||
|
*/
|
||||||
|
void wlr_output_cursor_move(struct wlr_output *output, int x, int y,
|
||||||
|
int hotspot_x, int hotspot_y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply pending cursor state.
|
||||||
|
*
|
||||||
|
* This may or may not be synchronized with the output, and would be applied on
|
||||||
|
* `wlr_output_commit`, depending on the backend limitations. However, it's
|
||||||
|
* advised to assume that they are sychronized and do any cursor operations at
|
||||||
|
* the same time you render to the output.
|
||||||
|
*
|
||||||
|
* If you have called `wlr_output_cursor_attach_render`, you must call this
|
||||||
|
* function before `wlr_output_attach_render`, otherwise you risk losing or
|
||||||
|
* corrupting rendering state.
|
||||||
|
*/
|
||||||
|
bool wlr_output_cursor_commit(struct wlr_output *output);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transform that, when composed with `tr`, gives
|
* Returns the transform that, when composed with `tr`, gives
|
||||||
|
|
|
||||||
|
|
@ -628,6 +628,51 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
|
||||||
output->software_cursor_locks);
|
output->software_cursor_locks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wlr_output_cursor_try_set_size(struct wlr_output *output, int *x, int *y) {
|
||||||
|
if (!output->impl->cursor_try_set_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output->impl->cursor_try_set_size(output, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_output_cursor_attach_render(struct wlr_output *output, int *buffer_age) {
|
||||||
|
if (!output->impl->cursor_attach_render) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!output->impl->cursor_attach_render(output, buffer_age)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->cursor_pending.committed |= WLR_OUTPUT_CURSOR_BUFFER;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_output_cursor_enable(struct wlr_output *output, bool enable) {
|
||||||
|
output->cursor_pending.enabled = enable;
|
||||||
|
output->cursor_pending.committed |= WLR_OUTPUT_CURSOR_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_output_cursor_move(struct wlr_output *output, int x, int y,
|
||||||
|
int hotspot_x, int hotspot_y) {
|
||||||
|
output->cursor_pending.x = x;
|
||||||
|
output->cursor_pending.y = y;
|
||||||
|
output->cursor_pending.hotspot_x = hotspot_x;
|
||||||
|
output->cursor_pending.hotspot_y = hotspot_y;
|
||||||
|
output->cursor_pending.committed |= WLR_OUTPUT_CURSOR_POS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_output_cursor_commit(struct wlr_output *output) {
|
||||||
|
if (!output->impl->cursor_commit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = output->impl->cursor_commit(output);
|
||||||
|
output->cursor_pending.committed = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
|
||||||
const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
|
const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue