mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-31 22:25:21 -04:00
Compare commits
25 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c9e6b7c9f | ||
|
|
e432b7bd1c | ||
|
|
ea1ade5e5d | ||
|
|
f56a69aa76 | ||
|
|
8fc64ae8d5 | ||
|
|
761927bbbd | ||
|
|
0d20e46498 | ||
|
|
eba71d59d4 | ||
|
|
9b42c1901d | ||
|
|
7a52788929 | ||
|
|
d4009183a1 | ||
|
|
d092e40dec | ||
|
|
bb5180ce9e | ||
|
|
73aa61686f | ||
|
|
9079380498 | ||
|
|
3118ca5c3e | ||
|
|
c1938f79c3 | ||
|
|
aa904ccf06 | ||
|
|
52e1ad01e3 | ||
|
|
30c0602457 | ||
|
|
b7205866c0 | ||
|
|
f935404e68 | ||
|
|
5aa8c192a5 | ||
|
|
68dea55970 | ||
|
|
f3fe6b9a43 |
23 changed files with 158 additions and 142 deletions
|
|
@ -41,9 +41,10 @@ tasks:
|
|||
cd wlroots/build-gcc/tinywl
|
||||
sudo modprobe vkms
|
||||
udevadm settle
|
||||
card="/dev/dri/$(ls /sys/devices/faux/vkms/drm/ | grep ^card)"
|
||||
export WLR_BACKENDS=drm
|
||||
export WLR_RENDERER=pixman
|
||||
export WLR_DRM_DEVICES=/dev/dri/by-path/platform-vkms-card
|
||||
export WLR_DRM_DEVICES="$card"
|
||||
export UBSAN_OPTIONS=halt_on_error=1
|
||||
sudo chmod ugo+rw /dev/dri/by-path/platform-vkms-card
|
||||
sudo chmod ugo+rw "$card"
|
||||
sudo -E seatd-launch -- ./tinywl -s 'kill $PPID' || [ $? = 143 ]
|
||||
|
|
|
|||
|
|
@ -485,5 +485,10 @@ bool wlr_backend_commit(struct wlr_backend *backend,
|
|||
output_apply_commit(state->output, &state->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < states_len; i++) {
|
||||
const struct wlr_backend_output_state *state = &states[i];
|
||||
output_send_commit_event(state->output, &state->base);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ void init_device_tablet_pad(struct wlr_libinput_input_device *dev) {
|
|||
struct udev_device *udev = libinput_device_get_udev_device(handle);
|
||||
char **dst = wl_array_add(&wlr_tablet_pad->paths, sizeof(char *));
|
||||
*dst = strdup(udev_device_get_syspath(udev));
|
||||
udev_device_unref(udev);
|
||||
|
||||
int groups = libinput_device_tablet_pad_get_num_mode_groups(handle);
|
||||
for (int i = 0; i < groups; ++i) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ void init_device_tablet(struct wlr_libinput_input_device *dev) {
|
|||
struct udev_device *udev = libinput_device_get_udev_device(dev->handle);
|
||||
char **dst = wl_array_add(&wlr_tablet->paths, sizeof(char *));
|
||||
*dst = strdup(udev_device_get_syspath(udev));
|
||||
udev_device_unref(udev);
|
||||
|
||||
wl_list_init(&dev->tablet_tools);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -367,7 +367,10 @@ void wlr_session_close_file(struct wlr_session *session,
|
|||
}
|
||||
|
||||
assert(wl_list_empty(&dev->events.change.listener_list));
|
||||
assert(wl_list_empty(&dev->events.remove.listener_list));
|
||||
// TODO: assert that the "remove" listener list is empty as well. Listeners
|
||||
// will typically call wlr_session_close_file() in response, and
|
||||
// wl_signal_emit_mutable() installs two phantom listeners, so we'd count
|
||||
// these two.
|
||||
|
||||
close(dev->fd);
|
||||
wl_list_remove(&dev->link);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ void output_defer_present(struct wlr_output *output, struct wlr_output_event_pre
|
|||
|
||||
bool output_prepare_commit(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
void output_apply_commit(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
void output_send_commit_event(struct wlr_output *output, const struct wlr_output_state *state);
|
||||
|
||||
void output_state_get_buffer_src_box(const struct wlr_output_state *state,
|
||||
struct wlr_fbox *out);
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ struct wlr_drm_lease_connector_v1 {
|
|||
|
||||
struct wlr_output *output;
|
||||
struct wlr_drm_lease_device_v1 *device;
|
||||
/** NULL if no client is currently leasing this connector */
|
||||
struct wlr_drm_lease_v1 *active_lease;
|
||||
|
||||
struct wl_list link; // wlr_drm_lease_device_v1.connectors
|
||||
|
||||
|
|
@ -93,9 +91,6 @@ struct wlr_drm_lease_v1 {
|
|||
|
||||
struct wlr_drm_lease_device_v1 *device;
|
||||
|
||||
struct wlr_drm_lease_connector_v1 **connectors;
|
||||
size_t n_connectors;
|
||||
|
||||
struct wl_list link; // wlr_drm_lease_device_v1.leases
|
||||
|
||||
void *data;
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ struct wlr_xwm {
|
|||
struct wl_listener drop_focus_destroy;
|
||||
};
|
||||
|
||||
// xwm_create takes ownership of wm_fd and will close it under all circumstances.
|
||||
struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland, int wm_fd);
|
||||
|
||||
void xwm_destroy(struct wlr_xwm *xwm);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'wlroots',
|
||||
'c',
|
||||
version: '0.19.0',
|
||||
version: '0.19.2',
|
||||
license: 'MIT',
|
||||
meson_version: '>=1.3',
|
||||
default_options: [
|
||||
|
|
|
|||
20
render/egl.c
20
render/egl.c
|
|
@ -260,7 +260,8 @@ static struct wlr_egl *egl_create(void) {
|
|||
return egl;
|
||||
}
|
||||
|
||||
static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
||||
static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display,
|
||||
bool allow_software) {
|
||||
egl->display = display;
|
||||
|
||||
EGLint major, minor;
|
||||
|
|
@ -326,9 +327,8 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
|||
|
||||
// The only way a non-DRM device is selected is when the user
|
||||
// explicitly picks software rendering
|
||||
if (check_egl_ext(device_exts_str, "EGL_MESA_device_software") &&
|
||||
egl->exts.EXT_device_drm) {
|
||||
if (env_parse_bool("WLR_RENDERER_ALLOW_SOFTWARE")) {
|
||||
if (check_egl_ext(device_exts_str, "EGL_MESA_device_software")) {
|
||||
if (allow_software || env_parse_bool("WLR_RENDERER_ALLOW_SOFTWARE")) {
|
||||
wlr_log(WLR_INFO, "Using software rendering");
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Software rendering detected, please use "
|
||||
|
|
@ -382,7 +382,7 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) {
|
|||
}
|
||||
|
||||
static bool egl_init(struct wlr_egl *egl, EGLenum platform,
|
||||
void *remote_display) {
|
||||
void *remote_display, bool allow_software) {
|
||||
EGLint display_attribs[3] = {0};
|
||||
size_t display_attribs_len = 0;
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!egl_init_display(egl, display)) {
|
||||
if (!egl_init_display(egl, display, allow_software)) {
|
||||
if (egl->exts.KHR_display_reference) {
|
||||
eglTerminate(display);
|
||||
}
|
||||
|
|
@ -556,6 +556,8 @@ static int open_render_node(int drm_fd) {
|
|||
}
|
||||
|
||||
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
||||
bool allow_software = drm_fd < 0;
|
||||
|
||||
struct wlr_egl *egl = egl_create();
|
||||
if (egl == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to create EGL context");
|
||||
|
|
@ -569,7 +571,7 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
|||
*/
|
||||
EGLDeviceEXT egl_device = get_egl_device_from_drm_fd(egl, drm_fd);
|
||||
if (egl_device != EGL_NO_DEVICE_EXT) {
|
||||
if (egl_init(egl, EGL_PLATFORM_DEVICE_EXT, egl_device)) {
|
||||
if (egl_init(egl, EGL_PLATFORM_DEVICE_EXT, egl_device, allow_software)) {
|
||||
wlr_log(WLR_DEBUG, "Using EGL_PLATFORM_DEVICE_EXT");
|
||||
return egl;
|
||||
}
|
||||
|
|
@ -594,7 +596,7 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (egl_init(egl, EGL_PLATFORM_GBM_KHR, egl->gbm_device)) {
|
||||
if (egl_init(egl, EGL_PLATFORM_GBM_KHR, egl->gbm_device, allow_software)) {
|
||||
wlr_log(WLR_DEBUG, "Using EGL_PLATFORM_GBM_KHR");
|
||||
return egl;
|
||||
}
|
||||
|
|
@ -633,7 +635,7 @@ struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!egl_init_display(egl, display)) {
|
||||
if (!egl_init_display(egl, display, true)) {
|
||||
free(egl);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ void wlr_render_pass_add_texture(struct wlr_render_pass *render_pass,
|
|||
if (!wlr_fbox_empty(&options->src_box)) {
|
||||
const struct wlr_fbox *box = &options->src_box;
|
||||
assert(box->x >= 0 && box->y >= 0 &&
|
||||
box->x + box->width <= options->texture->width &&
|
||||
box->y + box->height <= options->texture->height);
|
||||
(uint32_t)(box->x + box->width) <= options->texture->width &&
|
||||
(uint32_t)(box->y + box->height) <= options->texture->height);
|
||||
}
|
||||
|
||||
render_pass->impl->add_texture(render_pass, options);
|
||||
|
|
|
|||
|
|
@ -66,59 +66,72 @@ static struct wlr_vk_descriptor_pool *alloc_ds(
|
|||
struct wl_list *pool_list, size_t *last_pool_size) {
|
||||
VkResult res;
|
||||
|
||||
bool found = false;
|
||||
struct wlr_vk_descriptor_pool *pool;
|
||||
wl_list_for_each(pool, pool_list, link) {
|
||||
if (pool->free > 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) { // create new pool
|
||||
pool = calloc(1, sizeof(*pool));
|
||||
if (!pool) {
|
||||
wlr_log_errno(WLR_ERROR, "allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t count = 2 * (*last_pool_size);
|
||||
if (!count) {
|
||||
count = start_descriptor_pool_size;
|
||||
}
|
||||
|
||||
pool->free = count;
|
||||
VkDescriptorPoolSize pool_size = {
|
||||
.descriptorCount = count,
|
||||
.type = type,
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo dpool_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.maxSets = count,
|
||||
.poolSizeCount = 1,
|
||||
.pPoolSizes = &pool_size,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
};
|
||||
|
||||
res = vkCreateDescriptorPool(renderer->dev->dev, &dpool_info, NULL,
|
||||
&pool->pool);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkCreateDescriptorPool", res);
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*last_pool_size = count;
|
||||
wl_list_insert(pool_list, &pool->link);
|
||||
}
|
||||
|
||||
VkDescriptorSetAllocateInfo ds_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = layout,
|
||||
.descriptorPool = pool->pool,
|
||||
};
|
||||
|
||||
struct wlr_vk_descriptor_pool *pool;
|
||||
wl_list_for_each(pool, pool_list, link) {
|
||||
if (pool->free > 0) {
|
||||
ds_info.descriptorPool = pool->pool;
|
||||
res = vkAllocateDescriptorSets(renderer->dev->dev, &ds_info, ds);
|
||||
switch (res) {
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY:
|
||||
// Descriptor sets with more than one descriptor can cause us
|
||||
// to run out of pool memory early or lead to fragmentation
|
||||
// that makes the pool unable to service our allocation
|
||||
// request. Try the next pool or allocate a new one.
|
||||
continue;
|
||||
case VK_SUCCESS:
|
||||
--pool->free;
|
||||
return pool;
|
||||
default:
|
||||
wlr_vk_error("vkAllocateDescriptorSets", res);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pool = calloc(1, sizeof(*pool));
|
||||
if (!pool) {
|
||||
wlr_log_errno(WLR_ERROR, "allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t count = 2 * (*last_pool_size);
|
||||
if (!count) {
|
||||
count = start_descriptor_pool_size;
|
||||
}
|
||||
|
||||
pool->free = count;
|
||||
VkDescriptorPoolSize pool_size = {
|
||||
.descriptorCount = count,
|
||||
.type = type,
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo dpool_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.maxSets = count,
|
||||
.poolSizeCount = 1,
|
||||
.pPoolSizes = &pool_size,
|
||||
.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
};
|
||||
|
||||
res = vkCreateDescriptorPool(renderer->dev->dev, &dpool_info, NULL,
|
||||
&pool->pool);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkCreateDescriptorPool", res);
|
||||
free(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*last_pool_size = count;
|
||||
wl_list_insert(pool_list, &pool->link);
|
||||
|
||||
ds_info.descriptorPool = pool->pool;
|
||||
res = vkAllocateDescriptorSets(renderer->dev->dev, &ds_info, ds);
|
||||
if (res != VK_SUCCESS) {
|
||||
wlr_vk_error("vkAllocateDescriptorSets", res);
|
||||
|
|
|
|||
|
|
@ -283,7 +283,8 @@ static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_
|
|||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame, WL_OUTPUT_TRANSFORM_NORMAL, &now);
|
||||
wlr_ext_image_copy_capture_frame_v1_ready(frame,
|
||||
cursor_source->output->transform, &now);
|
||||
}
|
||||
|
||||
static const struct wlr_ext_image_capture_source_v1_interface output_cursor_source_impl = {
|
||||
|
|
|
|||
|
|
@ -288,18 +288,10 @@ static struct wlr_buffer *render_cursor_buffer(struct wlr_output_cursor *cursor)
|
|||
static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) {
|
||||
struct wlr_output *output = cursor->output;
|
||||
|
||||
if (!output->impl->set_cursor ||
|
||||
output->software_cursor_locks > 0) {
|
||||
if (!output->impl->set_cursor || output->software_cursor_locks > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct wlr_output_cursor *hwcur = output->hardware_cursor;
|
||||
if (hwcur != NULL && hwcur != cursor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
output->hardware_cursor = NULL;
|
||||
|
||||
struct wlr_texture *texture = cursor->texture;
|
||||
|
||||
// If the cursor was hidden or was a software cursor, the hardware
|
||||
|
|
@ -424,12 +416,15 @@ bool output_cursor_set_texture(struct wlr_output_cursor *cursor,
|
|||
wl_list_init(&cursor->renderer_destroy.link);
|
||||
}
|
||||
|
||||
if (output_cursor_attempt_hardware(cursor)) {
|
||||
return true;
|
||||
if (output->hardware_cursor == NULL || output->hardware_cursor == cursor) {
|
||||
if (output_cursor_attempt_hardware(cursor)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Falling back to software cursor on output '%s'", output->name);
|
||||
output_disable_hardware_cursor(output);
|
||||
}
|
||||
|
||||
wlr_log(WLR_DEBUG, "Falling back to software cursor on output '%s'", output->name);
|
||||
output_disable_hardware_cursor(output);
|
||||
output_cursor_damage_whole(cursor);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -745,7 +745,9 @@ void output_apply_commit(struct wlr_output *output, const struct wlr_output_stat
|
|||
}
|
||||
|
||||
output_apply_state(output, state);
|
||||
}
|
||||
|
||||
void output_send_commit_event(struct wlr_output *output, const struct wlr_output_state *state) {
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
struct wlr_output_event_commit event = {
|
||||
|
|
@ -787,6 +789,7 @@ bool wlr_output_commit_state(struct wlr_output *output,
|
|||
}
|
||||
|
||||
output_apply_commit(output, &pending);
|
||||
output_send_commit_event(output, &pending);
|
||||
|
||||
if (new_back_buffer) {
|
||||
wlr_buffer_unlock(pending.buffer);
|
||||
|
|
|
|||
|
|
@ -96,8 +96,11 @@ static void scene_buffer_unmark_client_buffer(struct wlr_scene_buffer *scene_buf
|
|||
return;
|
||||
}
|
||||
|
||||
assert(buffer->n_ignore_locks > 0);
|
||||
buffer->n_ignore_locks--;
|
||||
// If the buffer was a single-pixel buffer where we cached its color
|
||||
// then it won't have been marked as damage-allowed.
|
||||
if (buffer->n_ignore_locks > 0) {
|
||||
buffer->n_ignore_locks--;
|
||||
}
|
||||
}
|
||||
|
||||
static int min(int a, int b) {
|
||||
|
|
@ -165,7 +168,21 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
scene_buffer_unmark_client_buffer(scene_buffer);
|
||||
|
||||
if (surface->buffer) {
|
||||
client_buffer_mark_next_can_damage(surface->buffer);
|
||||
// If we've cached the buffer's single-pixel buffer color
|
||||
// then any in-place updates to the texture wouldn't be
|
||||
// reflected in rendering. So only allow in-place texture
|
||||
// updates if it's not a single pixel buffer. Note that we
|
||||
// can't use the cached scene_buffer->is_single_pixel_buffer
|
||||
// because that's only set later on.
|
||||
bool is_single_pixel_buffer = false;
|
||||
if (surface->buffer->source != NULL) {
|
||||
struct wlr_single_pixel_buffer_v1 *spb =
|
||||
wlr_single_pixel_buffer_v1_try_from_buffer(surface->buffer->source);
|
||||
is_single_pixel_buffer = spb != NULL;
|
||||
}
|
||||
if (!is_single_pixel_buffer) {
|
||||
client_buffer_mark_next_can_damage(surface->buffer);
|
||||
}
|
||||
|
||||
struct wlr_linux_drm_syncobj_surface_v1_state *syncobj_surface_state =
|
||||
wlr_linux_drm_syncobj_v1_get_surface_state(surface);
|
||||
|
|
@ -186,7 +203,8 @@ static void surface_reconfigure(struct wlr_scene_surface *scene_surface) {
|
|||
&surface->buffer->base, &options);
|
||||
|
||||
if (syncobj_surface_state != NULL &&
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER)) {
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER) &&
|
||||
surface->buffer->source != NULL) {
|
||||
wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state,
|
||||
surface->buffer->source);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -530,10 +530,6 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
|||
struct wlr_cursor *cur = output_cursor->cursor;
|
||||
struct wlr_output *output = output_cursor->output_cursor->output;
|
||||
|
||||
if (!output->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor_output_cursor_reset_image(output_cursor);
|
||||
|
||||
if (cur->state->buffer != NULL) {
|
||||
|
|
@ -589,10 +585,11 @@ static void cursor_output_cursor_update(struct wlr_cursor_output_cursor *output_
|
|||
&src_box, dst_width, dst_height, surface->current.transform,
|
||||
hotspot_x, hotspot_y, wait_timeline, wait_point);
|
||||
|
||||
if (syncobj_surface_state != NULL && surface->buffer != NULL &&
|
||||
if (syncobj_surface_state != NULL &&
|
||||
surface->buffer != NULL && surface->buffer->source != NULL &&
|
||||
(surface->current.committed & WLR_SURFACE_STATE_BUFFER)) {
|
||||
wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(syncobj_surface_state,
|
||||
&surface->buffer->base);
|
||||
surface->buffer->source);
|
||||
}
|
||||
|
||||
if (output_cursor->output_cursor->visible) {
|
||||
|
|
|
|||
|
|
@ -68,10 +68,6 @@ static void drm_lease_connector_v1_destroy(
|
|||
|
||||
wlr_log(WLR_DEBUG, "Destroying connector %s", connector->output->name);
|
||||
|
||||
if (connector->active_lease) {
|
||||
wlr_drm_lease_terminate(connector->active_lease->drm_lease);
|
||||
}
|
||||
|
||||
struct wl_resource *resource, *tmp;
|
||||
wl_resource_for_each_safe(resource, tmp, &connector->resources) {
|
||||
wp_drm_lease_connector_v1_send_withdrawn(resource);
|
||||
|
|
@ -140,14 +136,9 @@ static void lease_handle_destroy(struct wl_listener *listener, void *data) {
|
|||
|
||||
wl_list_remove(&lease->destroy.link);
|
||||
|
||||
for (size_t i = 0; i < lease->n_connectors; ++i) {
|
||||
lease->connectors[i]->active_lease = NULL;
|
||||
}
|
||||
|
||||
wl_list_remove(&lease->link);
|
||||
wl_resource_set_user_data(lease->resource, NULL);
|
||||
|
||||
free(lease->connectors);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
|
|
@ -180,20 +171,6 @@ struct wlr_drm_lease_v1 *wlr_drm_lease_request_v1_grant(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lease->connectors = calloc(request->n_connectors, sizeof(*lease->connectors));
|
||||
if (!lease->connectors) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate lease connectors list");
|
||||
close(fd);
|
||||
wp_drm_lease_v1_send_finished(lease->resource);
|
||||
free(lease);
|
||||
return NULL;
|
||||
}
|
||||
lease->n_connectors = request->n_connectors;
|
||||
for (size_t i = 0; i < request->n_connectors; ++i) {
|
||||
lease->connectors[i] = request->connectors[i];
|
||||
lease->connectors[i]->active_lease = lease;
|
||||
}
|
||||
|
||||
lease->destroy.notify = lease_handle_destroy;
|
||||
wl_signal_add(&lease->drm_lease->events.destroy, &lease->destroy);
|
||||
|
||||
|
|
@ -338,16 +315,6 @@ static void drm_lease_request_v1_handle_submit(
|
|||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < request->n_connectors; ++i) {
|
||||
struct wlr_drm_lease_connector_v1 *conn = request->connectors[i];
|
||||
if (conn->active_lease) {
|
||||
wlr_log(WLR_ERROR, "Failed to create lease, connector %s has "
|
||||
"already been leased", conn->output->name);
|
||||
wp_drm_lease_v1_send_finished(lease_resource);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
request->lease_resource = lease_resource;
|
||||
|
||||
wl_signal_emit_mutable(&request->device->manager->events.request,
|
||||
|
|
@ -440,10 +407,6 @@ static struct wp_drm_lease_connector_v1_interface lease_connector_impl = {
|
|||
static void drm_lease_connector_v1_send_to_client(
|
||||
struct wlr_drm_lease_connector_v1 *connector,
|
||||
struct wl_resource *resource) {
|
||||
if (connector->active_lease) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wl_client *client = wl_resource_get_client(resource);
|
||||
|
||||
uint32_t version = wl_resource_get_version(resource);
|
||||
|
|
@ -490,10 +453,12 @@ static void lease_device_bind(struct wl_client *wl_client, void *data,
|
|||
if (!device) {
|
||||
wlr_log(WLR_DEBUG, "Failed to bind lease device, "
|
||||
"the wlr_drm_lease_device_v1 has been destroyed");
|
||||
wl_list_init(wl_resource_get_link(device_resource));
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_user_data(device_resource, device);
|
||||
wl_list_insert(&device->resources, wl_resource_get_link(device_resource));
|
||||
|
||||
int fd = wlr_drm_backend_get_non_master_fd(device->backend);
|
||||
if (fd < 0) {
|
||||
|
|
@ -505,8 +470,6 @@ static void lease_device_bind(struct wl_client *wl_client, void *data,
|
|||
wp_drm_lease_device_v1_send_drm_fd(device_resource, fd);
|
||||
close(fd);
|
||||
|
||||
wl_list_insert(&device->resources, wl_resource_get_link(device_resource));
|
||||
|
||||
struct wlr_drm_lease_connector_v1 *connector;
|
||||
wl_list_for_each(connector, &device->connectors, link) {
|
||||
drm_lease_connector_v1_send_to_client(connector, device_resource);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ struct wlr_linux_drm_syncobj_surface_v1 {
|
|||
};
|
||||
|
||||
struct wlr_linux_drm_syncobj_surface_v1_commit {
|
||||
struct wlr_linux_drm_syncobj_surface_v1 *surface;
|
||||
struct wlr_surface *surface;
|
||||
struct wlr_drm_syncobj_timeline_waiter waiter;
|
||||
uint32_t cached_seq;
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ static struct wlr_linux_drm_syncobj_surface_v1 *surface_from_wlr_surface(
|
|||
}
|
||||
|
||||
static void surface_commit_destroy(struct wlr_linux_drm_syncobj_surface_v1_commit *commit) {
|
||||
wlr_surface_unlock_cached(commit->surface->surface, commit->cached_seq);
|
||||
wlr_surface_unlock_cached(commit->surface, commit->cached_seq);
|
||||
wl_list_remove(&commit->surface_destroy.link);
|
||||
wlr_drm_syncobj_timeline_waiter_finish(&commit->waiter);
|
||||
free(commit);
|
||||
|
|
@ -237,7 +237,7 @@ static bool lock_surface_commit(struct wlr_linux_drm_syncobj_surface_v1 *surface
|
|||
return false;
|
||||
}
|
||||
|
||||
commit->surface = surface;
|
||||
commit->surface = surface->surface;
|
||||
commit->cached_seq = wlr_surface_lock_pending(surface->surface);
|
||||
|
||||
commit->surface_destroy.notify = surface_commit_handle_surface_destroy;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ static void manager_create_transient_seat(struct wl_client *client,
|
|||
wl_resource_set_implementation(seat->resource, &transient_seat_impl,
|
||||
seat, transient_seat_handle_resource_destroy);
|
||||
|
||||
wl_list_init(&seat->seat_destroy.link);
|
||||
wl_signal_emit_mutable(&manager->events.create_seat, seat);
|
||||
|
||||
return;
|
||||
|
|
|
|||
20
util/box.c
20
util/box.c
|
|
@ -19,16 +19,15 @@ void wlr_box_closest_point(const struct wlr_box *box, double x, double y,
|
|||
//
|
||||
// In order to be consistent with e.g. wlr_box_contains_point(),
|
||||
// this function returns a point inside the bottom and right edges
|
||||
// of the box by at least 1/65536 of a unit (pixel). 1/65536 is
|
||||
// of the box by at least 1/256 of a unit (pixel). 1/256 is
|
||||
// small enough to avoid a "dead zone" with high-resolution mice
|
||||
// but large enough to avoid rounding to zero (due to loss of
|
||||
// significant digits) in simple floating-point calculations.
|
||||
// but large enough to avoid rounding to zero in wl_fixed_from_double().
|
||||
|
||||
// find the closest x point
|
||||
if (x < box->x) {
|
||||
*dest_x = box->x;
|
||||
} else if (x > box->x + box->width - 1/65536.0) {
|
||||
*dest_x = box->x + box->width - 1/65536.0;
|
||||
} else if (x > box->x + box->width - 1/256.0) {
|
||||
*dest_x = box->x + box->width - 1/256.0;
|
||||
} else {
|
||||
*dest_x = x;
|
||||
}
|
||||
|
|
@ -36,8 +35,8 @@ void wlr_box_closest_point(const struct wlr_box *box, double x, double y,
|
|||
// find closest y point
|
||||
if (y < box->y) {
|
||||
*dest_y = box->y;
|
||||
} else if (y > box->y + box->height - 1/65536.0) {
|
||||
*dest_y = box->y + box->height - 1/65536.0;
|
||||
} else if (y > box->y + box->height - 1/256.0) {
|
||||
*dest_y = box->y + box->height - 1/256.0;
|
||||
} else {
|
||||
*dest_y = y;
|
||||
}
|
||||
|
|
@ -67,7 +66,12 @@ bool wlr_box_intersection(struct wlr_box *dest, const struct wlr_box *box_a,
|
|||
dest->width = x2 - x1;
|
||||
dest->height = y2 - y1;
|
||||
|
||||
return !wlr_box_empty(dest);
|
||||
if (wlr_box_empty(dest)) {
|
||||
*dest = (struct wlr_box){0};
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wlr_box_contains_point(const struct wlr_box *box, double x, double y) {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ static void handle_server_start(struct wl_listener *listener, void *data) {
|
|||
static void xwayland_mark_ready(struct wlr_xwayland *xwayland) {
|
||||
assert(xwayland->server->wm_fd[0] >= 0);
|
||||
xwayland->xwm = xwm_create(xwayland, xwayland->server->wm_fd[0]);
|
||||
// xwm_create takes ownership of wm_fd[0] under all circumstances
|
||||
xwayland->server->wm_fd[0] = -1;
|
||||
|
||||
if (!xwayland->xwm) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -69,6 +72,11 @@ static void handle_shell_destroy(struct wl_listener *listener, void *data) {
|
|||
struct wlr_xwayland *xwayland =
|
||||
wl_container_of(listener, xwayland, shell_destroy);
|
||||
xwayland->shell_v1 = NULL;
|
||||
wl_list_remove(&xwayland->shell_destroy.link);
|
||||
// Will remove this list in handle_shell_destroy().
|
||||
// This ensures the link is always initialized and
|
||||
// avoids the need to keep check conditions in sync.
|
||||
wl_list_init(&xwayland->shell_destroy.link);
|
||||
}
|
||||
|
||||
void wlr_xwayland_destroy(struct wlr_xwayland *xwayland) {
|
||||
|
|
|
|||
|
|
@ -2470,6 +2470,7 @@ void xwm_set_cursor(struct wlr_xwm *xwm, const uint8_t *pixels, uint32_t stride,
|
|||
struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
||||
struct wlr_xwm *xwm = calloc(1, sizeof(*xwm));
|
||||
if (xwm == NULL) {
|
||||
close(wm_fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2484,11 +2485,13 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
|||
|
||||
xwm->ping_timeout = 10000;
|
||||
|
||||
// xcb_connect_to_fd takes ownership of the FD regardless of success/failure
|
||||
xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL);
|
||||
|
||||
int rc = xcb_connection_has_error(xwm->xcb_conn);
|
||||
if (rc) {
|
||||
wlr_log(WLR_ERROR, "xcb connect failed: %d", rc);
|
||||
xcb_disconnect(xwm->xcb_conn);
|
||||
free(xwm);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue