mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-20 06:47:19 -04:00
backend/wayland: switch to cursor layers
This commit is contained in:
parent
6c89732d8b
commit
e0a69804ed
1 changed files with 56 additions and 46 deletions
|
|
@ -19,6 +19,7 @@
|
||||||
#include "backend/wayland.h"
|
#include "backend/wayland.h"
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
#include "render/wlr_renderer.h"
|
#include "render/wlr_renderer.h"
|
||||||
|
#include "types/wlr_output.h"
|
||||||
|
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
#include "presentation-time-client-protocol.h"
|
#include "presentation-time-client-protocol.h"
|
||||||
|
|
@ -270,10 +271,6 @@ static bool test_layer(struct wlr_wl_output *output, struct wlr_output_layer_sta
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer_state->layer->cursor) {
|
|
||||||
return false; // TODO: add support for cursor layers
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = layer_state->dst_box.x;
|
int x = layer_state->dst_box.x;
|
||||||
int y = layer_state->dst_box.y;
|
int y = layer_state->dst_box.y;
|
||||||
int width = layer_state->dst_box.width;
|
int width = layer_state->dst_box.width;
|
||||||
|
|
@ -294,6 +291,13 @@ static bool test_layer(struct wlr_wl_output *output, struct wlr_output_layer_sta
|
||||||
return test_buffer(output->backend, layer_state->buffer);
|
return test_buffer(output->backend, layer_state->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool test_cursor(struct wlr_wl_output *output, struct wlr_output_layer_state *layer_state) {
|
||||||
|
if (layer_state->buffer == NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !layer_needs_viewport(layer_state) && test_buffer(output->backend, layer_state->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
static bool output_test(struct wlr_output *wlr_output,
|
static bool output_test(struct wlr_output *wlr_output,
|
||||||
const struct wlr_output_state *state) {
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_wl_output *output =
|
struct wlr_wl_output *output =
|
||||||
|
|
@ -330,10 +334,17 @@ static bool output_test(struct wlr_output *wlr_output,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->committed & WLR_OUTPUT_STATE_LAYERS) {
|
if (state->committed & WLR_OUTPUT_STATE_LAYERS) {
|
||||||
|
size_t layers_len = state->layers_len;
|
||||||
|
struct wlr_output_layer_state *cursor_state = output_state_get_cursor_layer(state);
|
||||||
|
if (cursor_state != NULL) {
|
||||||
|
cursor_state->accepted = test_cursor(output, cursor_state);
|
||||||
|
layers_len--;
|
||||||
|
}
|
||||||
|
|
||||||
// If we can't use a sub-surface for a layer, then we can't use a
|
// If we can't use a sub-surface for a layer, then we can't use a
|
||||||
// sub-surface for any layer underneath
|
// sub-surface for any layer underneath
|
||||||
bool supported = output->backend->subcompositor != NULL;
|
bool supported = output->backend->subcompositor != NULL;
|
||||||
for (ssize_t i = state->layers_len - 1; i >= 0; i--) {
|
for (ssize_t i = layers_len - 1; i >= 0; i--) {
|
||||||
struct wlr_output_layer_state *layer_state = &state->layers[i];
|
struct wlr_output_layer_state *layer_state = &state->layers[i];
|
||||||
supported = supported && test_layer(output, layer_state);
|
supported = supported && test_layer(output, layer_state);
|
||||||
layer_state->accepted = supported;
|
layer_state->accepted = supported;
|
||||||
|
|
@ -363,6 +374,7 @@ static const struct wlr_addon_interface output_layer_addon_impl = {
|
||||||
static struct wlr_wl_output_layer *get_or_create_output_layer(
|
static struct wlr_wl_output_layer *get_or_create_output_layer(
|
||||||
struct wlr_wl_output *output, struct wlr_output_layer *wlr_layer) {
|
struct wlr_wl_output *output, struct wlr_output_layer *wlr_layer) {
|
||||||
assert(output->backend->subcompositor != NULL);
|
assert(output->backend->subcompositor != NULL);
|
||||||
|
assert(!wlr_layer->cursor);
|
||||||
|
|
||||||
struct wlr_wl_output_layer *layer;
|
struct wlr_wl_output_layer *layer;
|
||||||
struct wlr_addon *addon = wlr_addon_find(&wlr_layer->addons, output,
|
struct wlr_addon *addon = wlr_addon_find(&wlr_layer->addons, output,
|
||||||
|
|
@ -501,6 +513,10 @@ static bool commit_layers(struct wlr_wl_output *output,
|
||||||
|
|
||||||
struct wlr_wl_output_layer *prev_layer = NULL;
|
struct wlr_wl_output_layer *prev_layer = NULL;
|
||||||
for (size_t i = 0; i < layers_len; i++) {
|
for (size_t i = 0; i < layers_len; i++) {
|
||||||
|
if (layers[i].layer->cursor) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_wl_output_layer *layer =
|
struct wlr_wl_output_layer *layer =
|
||||||
get_or_create_output_layer(output, layers[i].layer);
|
get_or_create_output_layer(output, layers[i].layer);
|
||||||
if (layer == NULL) {
|
if (layer == NULL) {
|
||||||
|
|
@ -525,6 +541,36 @@ static bool commit_layers(struct wlr_wl_output *output,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool commit_cursor(struct wlr_wl_output *output,
|
||||||
|
const struct wlr_output_layer_state *cursor_state) {
|
||||||
|
struct wlr_wl_backend *backend = output->backend;
|
||||||
|
|
||||||
|
output->cursor.hotspot_x = cursor_state->cursor_hotspot.x;
|
||||||
|
output->cursor.hotspot_y = cursor_state->cursor_hotspot.y;
|
||||||
|
|
||||||
|
if (output->cursor.surface == NULL) {
|
||||||
|
output->cursor.surface = wl_compositor_create_surface(backend->compositor);
|
||||||
|
}
|
||||||
|
struct wl_surface *surface = output->cursor.surface;
|
||||||
|
|
||||||
|
if (cursor_state->buffer != NULL) {
|
||||||
|
struct wlr_wl_buffer *buffer = get_or_create_wl_buffer(backend, cursor_state->buffer);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_surface_attach(surface, buffer->wl_buffer, 0, 0);
|
||||||
|
wl_surface_damage_buffer(surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||||
|
} else {
|
||||||
|
wl_surface_attach(surface, NULL, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_surface_commit(surface);
|
||||||
|
|
||||||
|
update_wl_output_cursor(output);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool output_commit(struct wlr_output *wlr_output,
|
static bool output_commit(struct wlr_output *wlr_output,
|
||||||
const struct wlr_output_state *state) {
|
const struct wlr_output_state *state) {
|
||||||
struct wlr_wl_output *output =
|
struct wlr_wl_output *output =
|
||||||
|
|
@ -556,6 +602,11 @@ static bool output_commit(struct wlr_output *wlr_output,
|
||||||
damage_surface(output->surface, damage);
|
damage_surface(output->surface, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_output_layer_state *cursor_state = output_state_get_cursor_layer(state);
|
||||||
|
if (cursor_state != NULL && !commit_cursor(output, cursor_state)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if ((state->committed & WLR_OUTPUT_STATE_LAYERS) &&
|
if ((state->committed & WLR_OUTPUT_STATE_LAYERS) &&
|
||||||
!commit_layers(output, state->layers, state->layers_len)) {
|
!commit_layers(output, state->layers, state->layers_len)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -604,40 +655,6 @@ static bool output_commit(struct wlr_output *wlr_output,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_set_cursor(struct wlr_output *wlr_output,
|
|
||||||
struct wlr_buffer *wlr_buffer, int hotspot_x, int hotspot_y) {
|
|
||||||
struct wlr_wl_output *output = get_wl_output_from_output(wlr_output);
|
|
||||||
struct wlr_wl_backend *backend = output->backend;
|
|
||||||
|
|
||||||
output->cursor.hotspot_x = hotspot_x;
|
|
||||||
output->cursor.hotspot_y = hotspot_y;
|
|
||||||
|
|
||||||
if (output->cursor.surface == NULL) {
|
|
||||||
output->cursor.surface =
|
|
||||||
wl_compositor_create_surface(backend->compositor);
|
|
||||||
}
|
|
||||||
struct wl_surface *surface = output->cursor.surface;
|
|
||||||
|
|
||||||
if (wlr_buffer != NULL) {
|
|
||||||
struct wlr_wl_buffer *buffer =
|
|
||||||
get_or_create_wl_buffer(output->backend, wlr_buffer);
|
|
||||||
if (buffer == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_surface_attach(surface, buffer->wl_buffer, 0, 0);
|
|
||||||
wl_surface_damage_buffer(surface, 0, 0, INT32_MAX, INT32_MAX);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
} else {
|
|
||||||
wl_surface_attach(surface, NULL, 0, 0);
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
update_wl_output_cursor(output);
|
|
||||||
wl_display_flush(backend->remote_display);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wlr_drm_format_set *output_get_formats(
|
static const struct wlr_drm_format_set *output_get_formats(
|
||||||
struct wlr_output *wlr_output, uint32_t buffer_caps) {
|
struct wlr_output *wlr_output, uint32_t buffer_caps) {
|
||||||
struct wlr_wl_output *output = get_wl_output_from_output(wlr_output);
|
struct wlr_wl_output *output = get_wl_output_from_output(wlr_output);
|
||||||
|
|
@ -694,17 +711,10 @@ void update_wl_output_cursor(struct wlr_wl_output *output) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool output_move_cursor(struct wlr_output *_output, int x, int y) {
|
|
||||||
// TODO: only return true if x == current x and y == current y
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct wlr_output_impl output_impl = {
|
static const struct wlr_output_impl output_impl = {
|
||||||
.destroy = output_destroy,
|
.destroy = output_destroy,
|
||||||
.test = output_test,
|
.test = output_test,
|
||||||
.commit = output_commit,
|
.commit = output_commit,
|
||||||
.set_cursor = output_set_cursor,
|
|
||||||
.move_cursor = output_move_cursor,
|
|
||||||
.get_cursor_formats = output_get_formats,
|
.get_cursor_formats = output_get_formats,
|
||||||
.get_primary_formats = output_get_formats,
|
.get_primary_formats = output_get_formats,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue