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);
 | 
			
		||||
	void (*destroy)(struct wlr_output *output);
 | 
			
		||||
	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 (*set_gamma)(struct wlr_output *output, size_t size,
 | 
			
		||||
		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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +105,7 @@ struct wlr_output {
 | 
			
		|||
	float transform_matrix[9];
 | 
			
		||||
 | 
			
		||||
	struct wlr_output_state pending;
 | 
			
		||||
	struct wlr_output_cursor cursor_pending;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		// 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);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
 | 
			
		||||
	const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
 | 
			
		||||
	int32_t hotspot_x, int32_t hotspot_y);
 | 
			
		||||
bool wlr_output_cursor_move(struct wlr_output_cursor *cursor,
 | 
			
		||||
	double x, double y);
 | 
			
		||||
#endif
 | 
			
		||||
/**
 | 
			
		||||
 * Hardware cursors:
 | 
			
		||||
 *
 | 
			
		||||
 * Hardware cursors are a feature of GPUs that allow a small framebuffer
 | 
			
		||||
 * to be displayed over the main framebuffer. This is more efficient than
 | 
			
		||||
 * drawing onto the main framebuffer using e.g. OpenGL.
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -628,6 +628,51 @@ void wlr_output_lock_software_cursors(struct wlr_output *output, bool lock) {
 | 
			
		|||
		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
 | 
			
		||||
bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor,
 | 
			
		||||
		const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue