mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -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