From 23333bb158c4610eaa2c31ee38e8848f1fb9c42a Mon Sep 17 00:00:00 2001 From: sewn Date: Sat, 14 Mar 2026 12:58:05 +0300 Subject: [PATCH 1/5] shm: Close descriptor on buffer destroy only The buffer file descriptor is retained until there are no references, but it is closed immediately upon creation, which is inaccurate. --- libswc/shm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libswc/shm.c b/libswc/shm.c index 98b4449..7b3697b 100644 --- a/libswc/shm.c +++ b/libswc/shm.c @@ -32,7 +32,9 @@ #include #include +#include #include +#include #include #include #include @@ -43,6 +45,7 @@ struct pool { struct swc_shm *shm; void *data; uint32_t size; + int fd; unsigned references; }; @@ -68,6 +71,7 @@ unref_pool(struct pool *pool) return; munmap(pool->data, pool->size); + close(pool->fd); free(pool); } @@ -186,7 +190,7 @@ create_pool(struct wl_client *client, struct wl_resource *resource, uint32_t id, wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mmap failed: %s", strerror(errno)); goto error2; } - close(fd); + pool->fd = fd; pool->size = size; pool->references = 1; return; From e634cf21020290d353286ab2c73451faa1df3731 Mon Sep 17 00:00:00 2001 From: sewn Date: Sat, 14 Mar 2026 13:04:32 +0300 Subject: [PATCH 2/5] shm: Allow writing to user-provided buffer --- libswc/shm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswc/shm.c b/libswc/shm.c index 7b3697b..2eef26d 100644 --- a/libswc/shm.c +++ b/libswc/shm.c @@ -185,7 +185,7 @@ create_pool(struct wl_client *client, struct wl_resource *resource, uint32_t id, goto error1; } wl_resource_set_implementation(pool->resource, &shm_pool_impl, pool, &destroy_pool_resource); - pool->data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (pool->data == MAP_FAILED) { wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mmap failed: %s", strerror(errno)); goto error2; From b61fd42858a68b1b8be28ec756a399cc303337a5 Mon Sep 17 00:00:00 2001 From: sewn Date: Sat, 14 Mar 2026 12:58:57 +0300 Subject: [PATCH 3/5] view: Add signals for pre-attach Allows a user to know when a view buffer has been changed. --- libswc/view.c | 2 ++ libswc/view.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libswc/view.c b/libswc/view.c index 84cf2db..ea293be 100644 --- a/libswc/view.c +++ b/libswc/view.c @@ -47,6 +47,7 @@ view_initialize(struct view *view, const struct view_impl *impl) view->geometry.height = 0; view->buffer = NULL; view->screens = 0; + wl_signal_init(&view->attach_signal); wl_list_init(&view->handlers); } @@ -73,6 +74,7 @@ view_attach(struct view *view, struct wld_buffer *buffer) wld_buffer_reference(buffer); view->buffer = buffer; + wl_signal_emit(&view->attach_signal, view->buffer); HANDLE(view, handler, attach); return 0; diff --git a/libswc/view.h b/libswc/view.h index 83780c0..3708b28 100644 --- a/libswc/view.h +++ b/libswc/view.h @@ -26,6 +26,7 @@ #include "swc.h" +#include #include /** @@ -47,6 +48,7 @@ struct view { struct swc_rectangle geometry; uint32_t screens; + struct wl_signal attach_signal; struct wld_buffer *buffer; }; From 4a8b60af8a244c1febf08b55957e57ab2d3530e4 Mon Sep 17 00:00:00 2001 From: sewn Date: Sat, 14 Mar 2026 12:59:35 +0300 Subject: [PATCH 4/5] Add helpers for retrieving/setting damage for all outputs --- libswc/compositor.c | 21 +++++++++++++++++++++ libswc/compositor.h | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/libswc/compositor.c b/libswc/compositor.c index 543615c..bb46ca9 100644 --- a/libswc/compositor.c +++ b/libswc/compositor.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -345,6 +346,26 @@ schedule_updates(uint32_t screens) compositor.scheduled_updates |= screens; } +void +compositor_damage_all(void) +{ + struct screen *screen; + + wl_list_for_each(screen, &swc.screens, link) + pixman_region32_union_rect( + &compositor.damage, &compositor.damage, screen->base.geometry.x, + screen->base.geometry.y, screen->base.geometry.width, + screen->base.geometry.height); + + schedule_updates(-1); +} + +void +compositor_get_damage(pixman_region32_t *damage) +{ + pixman_region32_copy(damage, &compositor.damage); +} + static bool update(struct view *base) { diff --git a/libswc/compositor.h b/libswc/compositor.h index 9844bd9..e989e2d 100644 --- a/libswc/compositor.h +++ b/libswc/compositor.h @@ -24,6 +24,7 @@ #ifndef SWC_COMPOSITOR_H #define SWC_COMPOSITOR_H +#include "screen.h" #include "view.h" #include @@ -43,6 +44,9 @@ struct swc_compositor { } signal; }; +void compositor_get_damage(pixman_region32_t *damage); +void compositor_damage_all(void); + bool compositor_initialize(void); void compositor_finalize(void); From 2f8e49b5691caf8f6bc9c762561c61e602ce7194 Mon Sep 17 00:00:00 2001 From: sewn Date: Sat, 14 Mar 2026 13:01:29 +0300 Subject: [PATCH 5/5] Add support for wlr-screencopy-unstable --- .gitignore | 2 + libswc/internal.h | 1 + libswc/local.mk | 3 + libswc/screencopy.c | 301 ++++++++++++++++++++++++ libswc/screencopy.h | 51 ++++ libswc/swc.c | 9 + protocol/local.mk | 1 + protocol/wlr-screencopy-unstable-v1.xml | 234 ++++++++++++++++++ 8 files changed, 602 insertions(+) create mode 100644 libswc/screencopy.c create mode 100644 libswc/screencopy.h create mode 100644 protocol/wlr-screencopy-unstable-v1.xml diff --git a/.gitignore b/.gitignore index 3466d09..77d2229 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ protocol/swc-protocol.c protocol/swc-server-protocol.h protocol/wayland-drm-protocol.c protocol/wayland-drm-server-protocol.h +protocol/wlr-screencopy-unstable-v1-protocol.c +protocol/wlr-screencopy-unstable-v1-server-protocol.h protocol/xdg-decoration-unstable-v1-protocol.c protocol/xdg-decoration-unstable-v1-server-protocol.h protocol/xdg-shell-protocol.c diff --git a/libswc/internal.h b/libswc/internal.h index 8efba6d..cb554db 100644 --- a/libswc/internal.h +++ b/libswc/internal.h @@ -52,6 +52,7 @@ struct swc { struct wl_global *subcompositor; struct wl_global *xdg_decoration_manager; struct wl_global *xdg_shell; + struct wl_global *wlr_screencopy_manager; #ifdef ENABLE_XWAYLAND const struct swc_xserver *const xserver; diff --git a/libswc/local.mk b/libswc/local.mk index 5368aef..192638c 100644 --- a/libswc/local.mk +++ b/libswc/local.mk @@ -24,6 +24,7 @@ SWC_SOURCES = \ launch/protocol.c \ libswc/bindings.c \ libswc/compositor.c \ + libswc/screencopy.c \ libswc/data.c \ libswc/data_device.c \ libswc/data_device_manager.c \ @@ -59,6 +60,7 @@ SWC_SOURCES = \ protocol/server-decoration-protocol.c \ protocol/swc-protocol.c \ protocol/wayland-drm-protocol.c \ + protocol/wlr-screencopy-unstable-v1-protocol.c \ protocol/xdg-decoration-unstable-v1-protocol.c \ protocol/xdg-shell-protocol.c @@ -93,6 +95,7 @@ $(call objects,drm drm_buffer): protocol/wayland-drm-server-protocol.h $(call objects,kde_decoration): protocol/server-decoration-server-protocol.h $(call objects,xdg_decoration): protocol/xdg-decoration-unstable-v1-server-protocol.h $(call objects,xdg_shell): protocol/xdg-shell-server-protocol.h +$(call objects,screencopy): protocol/wlr-screencopy-unstable-v1-server-protocol.h $(call objects,pointer): cursor/cursor_data.h $(dir)/libswc-internal.o: $(SWC_STATIC_OBJECTS) diff --git a/libswc/screencopy.c b/libswc/screencopy.c new file mode 100644 index 0000000..87d41cc --- /dev/null +++ b/libswc/screencopy.c @@ -0,0 +1,301 @@ +/* swc: libswc/screencopy.c + * + * Copyright (c) 2026 sewn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "screencopy.h" +#include "compositor.h" +#include "internal.h" +#include "output.h" +#include "seat.h" +#include "screen.h" +#include "pointer.h" +#include "shm.h" +#include "util.h" +#include "wayland_buffer.h" + +#include "wlr-screencopy-unstable-v1-server-protocol.h" +#include +#include +#include +#include + +extern struct swc swc; + +static void +composite_cursor(struct wld_buffer *dst, struct screen *screen) +{ + struct pointer *pointer = swc.seat ? swc.seat->pointer : NULL; + struct wld_buffer *cursor_buf; + pixman_image_t *src_img, *dest_img; + int32_t dst_x, dst_y; + + if (!pointer || !pointer->cursor.buffer || !pointer->cursor.view.buffer) { + return; + } + + if (!(pointer->cursor.view.screens & screen_mask(screen))) { + return; + } + + cursor_buf = pointer->cursor.buffer; + + if (!cursor_buf->map) { + return; + } + + dst_x = pointer->cursor.view.geometry.x - screen->base.geometry.x; + dst_y = pointer->cursor.view.geometry.y - screen->base.geometry.y; + + src_img = pixman_image_create_bits(PIXMAN_x8r8g8b8, cursor_buf->width, + cursor_buf->height, cursor_buf->map, + cursor_buf->pitch); + + dest_img = pixman_image_create_bits(PIXMAN_x8r8g8b8, dst->width, + dst->height, dst->map, dst->pitch); + + pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dest_img, 0, 0, 0, 0, + dst_x, dst_y, cursor_buf->width, cursor_buf->height); + + pixman_image_unref(src_img); + pixman_image_unref(dest_img); + wld_unmap(cursor_buf); +} + +static struct screencopy_frame * +create_frame(struct wl_client *client, struct wl_resource *resource, + uint32_t id, int32_t overlay_cursor, + struct wl_resource *output_resource) +{ + struct screencopy_frame *frame; + struct output *output = + output_resource ? wl_resource_get_user_data(output_resource) : NULL; + struct screen *screen; + + (void)client; + + screen = output ? output->screen + : wl_container_of(swc.screens.next, screen, link); + + if (!(frame = malloc(sizeof(*frame)))) { + return NULL; + } + frame->resource = + wl_resource_create(client, &zwlr_screencopy_frame_v1_interface, + wl_resource_get_version(resource), id); + if (!frame->resource) { + return NULL; + } + + frame->screen = screen; + + return frame; +} + +static void +frame_send(struct screencopy_frame *frame, struct wld_buffer *buffer) +{ + struct wld_buffer *dst_buf = NULL; + struct timespec ts; + + if (frame->client_buffer) { + dst_buf = wayland_buffer_get(frame->client_buffer); + if (!dst_buf) { + wl_resource_post_error(frame->resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "buffer is not a wl_buffer"); + return; + } + } else { + wl_resource_post_error(frame->resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "no buffer given"); + return; + } + + if (frame->geom.width != (uint32_t)dst_buf->width || + frame->geom.height != (uint32_t)dst_buf->height || + frame->stride < (int32_t)dst_buf->pitch) { + wl_resource_post_error(frame->resource, + ZWLR_SCREENCOPY_FRAME_V1_ERROR_INVALID_BUFFER, + "buffer has invalid parameters"); + return; + } + + if (!wld_set_target_buffer(swc.shm->renderer, dst_buf)) { + zwlr_screencopy_frame_v1_send_failed(frame->resource); + return; + } + + wld_copy_rectangle(swc.shm->renderer, buffer, + 0, 0, + frame->geom.x - frame->screen->base.geometry.x, + frame->geom.y - frame->screen->base.geometry.y, + buffer->width, buffer->height); + + /* XXX: Currently, cursor composition is very slow since the cursor buffer + * is hardware backed. There should be a way to transform the cursor to + * software. */ + if (frame->overlay_cursor) + composite_cursor(dst_buf, frame->screen); + + zwlr_screencopy_frame_v1_send_flags(frame->resource, 0); + clock_gettime(CLOCK_MONOTONIC, &ts); + zwlr_screencopy_frame_v1_send_ready(frame->resource, (ts.tv_sec >> 32), + (ts.tv_sec & 0xFFFFFFFF), ts.tv_nsec); +} + +static void +frame_screen_attach(struct wl_listener *listener, void *data) +{ + struct wld_buffer *buffer = data; + struct screencopy_frame *frame = + wl_container_of(listener, frame, screen_attach); + const struct swc_rectangle *geom = &frame->screen->base.geometry; + struct pixman_region32 damage, screen_damage; + struct pixman_box32 *box; + + if (frame->with_damage) { + /* XXX: Untested, no modern recorder uses this. */ + pixman_region32_init(&damage); + pixman_region32_init(&screen_damage); + compositor_get_damage(&damage); + pixman_region32_intersect_rect(&screen_damage, &damage, geom->x, geom->y, geom->width, geom->height); + pixman_region32_translate(&damage, -geom->x, -geom->y); + box = pixman_region32_extents(&screen_damage); + + zwlr_screencopy_frame_v1_send_damage(frame->resource, box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1); + }; + + wl_list_remove(&frame->screen_attach.link); + frame_send(frame, buffer); +} + +static void +frame_copy(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource) +{ + struct screencopy_frame *frame = wl_resource_get_user_data(resource); + (void)client; + + frame->client_buffer = buffer_resource; + wl_signal_add(&frame->screen->planes.primary.view.attach_signal, &frame->screen_attach); + frame->screen_attach.notify = &frame_screen_attach; + /* XXX: Ask for redraw instead of damaging all windows for screencopy. */ + compositor_damage_all(); +} + +static void +frame_copy_damage(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer_resource) +{ + struct screencopy_frame *frame = wl_resource_get_user_data(resource); + + frame->with_damage = true; + frame_copy(client, resource, buffer_resource); +} + +static void +frame_destroy(struct wl_resource *resource) +{ + struct screencopy_frame *frame = wl_resource_get_user_data(resource); + free(frame); +} + +static const struct zwlr_screencopy_frame_v1_interface frame_impl = { + .copy = frame_copy, + .copy_with_damage = frame_copy_damage, + .destroy = destroy_resource, +}; + +static void +capture(struct wl_client *client, struct wl_resource *resource, uint32_t id, + int32_t overlay_cursor, struct wl_resource *output) +{ + struct screencopy_frame *frame; + + frame = create_frame(client, resource, id, overlay_cursor, output); + if (!frame) { + wl_resource_post_no_memory(resource); + return; + } + + frame->overlay_cursor = overlay_cursor; + frame->geom = frame->screen->base.geometry; + frame->stride = frame->geom.width * 4; + wl_resource_set_implementation(frame->resource, &frame_impl, frame, + &frame_destroy); + + zwlr_screencopy_frame_v1_send_buffer( + frame->resource, WL_SHM_FORMAT_XRGB8888, frame->geom.width, + frame->geom.height, frame->stride); +} + +static void +capture_region(struct wl_client *client, struct wl_resource *resource, + uint32_t id, int32_t overlay_cursor, struct wl_resource *output, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + struct screencopy_frame *frame; + + frame = create_frame(client, resource, id, overlay_cursor, output); + if (!frame) { + wl_resource_post_no_memory(resource); + return; + } + + frame->geom.width = width; + frame->geom.height = height; + frame->geom.x = x; + frame->geom.y = y; + frame->stride = width * 4; + wl_resource_set_implementation(frame->resource, &frame_impl, frame, + &frame_destroy); + zwlr_screencopy_frame_v1_send_flags(frame->resource, 0); + zwlr_screencopy_frame_v1_send_buffer( + frame->resource, WL_SHM_FORMAT_XRGB8888, frame->geom.width, + frame->geom.height, frame->stride); +} + +static const struct zwlr_screencopy_manager_v1_interface screencopy_manager_impl = { + .destroy = destroy_resource, + .capture_output = capture, + .capture_output_region = capture_region, +}; + +static void +bind_screencopy_manager(struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create(client, &zwlr_screencopy_manager_v1_interface, + version, id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(resource, &screencopy_manager_impl, NULL, NULL); +} + +struct wl_global * +screencopy_manager_create(struct wl_display *display) +{ + return wl_global_create(display, &zwlr_screencopy_manager_v1_interface, 2, + NULL, &bind_screencopy_manager); +} diff --git a/libswc/screencopy.h b/libswc/screencopy.h new file mode 100644 index 0000000..d10ddaf --- /dev/null +++ b/libswc/screencopy.h @@ -0,0 +1,51 @@ +/* swc: libswc/screencopy.h + * + * Copyright (c) 2026 sewn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef SWC_SCREENCOPY_H +#define SWC_SCREENCOPY_H + +#include "swc.h" + +#include +#include +#include +#include + +struct screencopy_frame { + struct wl_resource *resource; + struct wl_resource *client_buffer; + struct screen *screen; + + bool with_damage; + bool overlay_cursor; + + struct wl_listener screen_attach; + + struct swc_rectangle geom; + uint32_t stride; +}; + +struct wl_global * +screencopy_manager_create(struct wl_display *display); + +#endif diff --git a/libswc/swc.c b/libswc/swc.c index 0fca9f9..b51913c 100644 --- a/libswc/swc.c +++ b/libswc/swc.c @@ -34,6 +34,7 @@ #include "panel_manager.h" #include "pointer.h" #include "screen.h" +#include "screencopy.h" #include "seat.h" #include "shell.h" #include "shm.h" @@ -203,10 +204,18 @@ swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop, con } #endif + swc.wlr_screencopy_manager = screencopy_manager_create(display); + if (!swc.wlr_screencopy_manager) { + ERROR("Could not screencopy manager\n"); + goto error15; + } + setup_compositor(); return true; +error15: + wl_global_destroy(swc.wlr_screencopy_manager); #ifdef ENABLE_XWAYLAND error14: wl_global_destroy(swc.panel_manager); diff --git a/protocol/local.mk b/protocol/local.mk index d25afa1..87662cb 100644 --- a/protocol/local.mk +++ b/protocol/local.mk @@ -7,6 +7,7 @@ PROTOCOL_EXTENSIONS = \ $(dir)/server-decoration.xml\ $(dir)/swc.xml \ $(dir)/wayland-drm.xml \ + $(dir)/wlr-screencopy-unstable-v1.xml \ $(wayland_protocols)/stable/xdg-shell/xdg-shell.xml \ $(wayland_protocols)/unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml \ $(wayland_protocols)/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml diff --git a/protocol/wlr-screencopy-unstable-v1.xml b/protocol/wlr-screencopy-unstable-v1.xml new file mode 100644 index 0000000..8b20661 --- /dev/null +++ b/protocol/wlr-screencopy-unstable-v1.xml @@ -0,0 +1,234 @@ + + + + Copyright © 2018 Simon Ser + Copyright © 2019 Andri Yngvason + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol allows clients to ask the compositor to copy part of the + screen content to a client buffer. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + Note! This protocol is deprecated and not intended for production use. + The ext-image-copy-capture-v1 protocol should be used instead. + + + + + This object is a manager which offers requests to start capturing from a + source. + + + + + Capture the next frame of an entire output. + + + + + + + + + Capture the next frame of an output's region. + + The region is given in output logical coordinates, see + xdg_output.logical_size. The region will be clipped to the output's + extents. + + + + + + + + + + + + + All objects created by the manager will still remain valid, until their + appropriate destroy request has been called. + + + + + + + This object represents a single frame. + + When created, a series of buffer events will be sent, each representing a + supported buffer type. The "buffer_done" event is sent afterwards to + indicate that all supported buffer types have been enumerated. The client + will then be able to send a "copy" request. If the capture is successful, + the compositor will send a "flags" event followed by a "ready" event. + + For objects version 2 or lower, wl_shm buffers are always supported, ie. + the "buffer" event is guaranteed to be sent. + + If the capture failed, the "failed" event is sent. This can happen anytime + before the "ready" event. + + Once either a "ready" or a "failed" event is received, the client should + destroy the frame. + + + + + Provides information about wl_shm buffer parameters that need to be + used for this frame. This event is sent once after the frame is created + if wl_shm buffers are supported. + + + + + + + + + + Copy the frame to the supplied buffer. The buffer must have the + correct size, see zwlr_screencopy_frame_v1.buffer and + zwlr_screencopy_frame_v1.linux_dmabuf. The buffer needs to have a + supported format. + + If the frame is successfully copied, "flags" and "ready" events are + sent. Otherwise, a "failed" event is sent. + + + + + + + + + + + + + + + + Provides flags about the frame. This event is sent once before the + "ready" event. + + + + + + + Called as soon as the frame is copied, indicating it is available + for reading. This event includes the time at which the presentation took place. + + The timestamp is expressed as tv_sec_hi, tv_sec_lo, tv_nsec triples, + each component being an unsigned 32-bit value. Whole seconds are in + tv_sec which is a 64-bit value combined from tv_sec_hi and tv_sec_lo, + and the additional fractional part in tv_nsec as nanoseconds. Hence, + for valid timestamps tv_nsec must be in [0, 999999999]. The seconds part + may have an arbitrary offset at start. + + After receiving this event, the client should destroy the object. + + + + + + + + + This event indicates that the attempted frame copy has failed. + + After receiving this event, the client should destroy the object. + + + + + + Destroys the frame. This request can be sent at any time by the client. + + + + + + + Same as copy, except it waits until there is damage to copy. + + + + + + + This event is sent right before the ready event when copy_with_damage is + requested. It may be generated multiple times for each copy_with_damage + request. + + The arguments describe a box around an area that has changed since the + last copy request that was derived from the current screencopy manager + instance. + + The union of all regions received between the call to copy_with_damage + and a ready event is the total damage since the prior ready event. + + + + + + + + + + + Provides information about linux-dmabuf buffer parameters that need to + be used for this frame. This event is sent once after the frame is + created if linux-dmabuf buffers are supported. + + + + + + + + + This event is sent once after all buffer events have been sent. + + The client should proceed to create a buffer of one of the supported + types, and send a "copy" request. + + + +