Skip to content

Commit

Permalink
Update to wlr-screencopy-unstable-v1 version 3
Browse files Browse the repository at this point in the history
  • Loading branch information
columbarius authored Oct 19, 2020
1 parent 39b82ff commit dafb25f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 23 deletions.
9 changes: 8 additions & 1 deletion include/wlr_screencast.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@

#include "screencast_common.h"

#define SC_MANAGER_VERSION 2
#define WL_OUTPUT_VERSION 1

#define SC_MANAGER_VERSION 3
#define SC_MANAGER_VERSION_MIN 2

#define WL_SHM_VERSION 1

#define XDG_OUTPUT_MANAGER_VERSION 3

struct xdpw_state;

Expand Down
53 changes: 39 additions & 14 deletions protocols/wlr-screencopy-unstable-v1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
interface version number is reset.
</description>

<interface name="zwlr_screencopy_manager_v1" version="2">
<interface name="zwlr_screencopy_manager_v1" version="3">
<description summary="manager to inform clients and begin capturing">
This object is a manager which offers requests to start capturing from a
source.
Expand Down Expand Up @@ -80,13 +80,18 @@
</request>
</interface>

<interface name="zwlr_screencopy_frame_v1" version="2">
<interface name="zwlr_screencopy_frame_v1" version="3">
<description summary="a frame ready for copy">
This object represents a single frame.

When created, a "buffer" event will be sent. The client will then be able
to send a "copy" request. If the capture is successful, the compositor
will send a "flags" followed by a "ready" event.
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" 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.
Expand All @@ -96,14 +101,12 @@
</description>

<event name="buffer">
<description summary="buffer information">
Provides information about the frame's buffer. This event is sent once
as soon as the frame is created.

The client should then create a buffer with the provided attributes, and
send a "copy" request.
<description summary="wl_shm buffer information">
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.
</description>
<arg name="format" type="uint" summary="buffer format"/>
<arg name="format" type="uint" enum="wl_shm.format" summary="buffer format"/>
<arg name="width" type="uint" summary="buffer width"/>
<arg name="height" type="uint" summary="buffer height"/>
<arg name="stride" type="uint" summary="buffer stride"/>
Expand All @@ -112,8 +115,9 @@
<request name="copy">
<description summary="copy the frame">
Copy the frame to the supplied buffer. The buffer must have a the
correct size, see zwlr_screencopy_frame_v1.buffer. The buffer needs to
have a supported format.
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, a "flags" and a "ready" events are
sent. Otherwise, a "failed" event is sent.
Expand Down Expand Up @@ -203,5 +207,26 @@
<arg name="width" type="uint" summary="current width"/>
<arg name="height" type="uint" summary="current height"/>
</event>

<!-- Version 3 additions -->
<event name="linux_dmabuf" since="3">
<description summary="linux-dmabuf buffer information">
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.
</description>
<arg name="format" type="uint" summary="fourcc pixel format"/>
<arg name="width" type="uint" summary="buffer width"/>
<arg name="height" type="uint" summary="buffer height"/>
</event>

<event name="buffer_done" since="3">
<description summary="all buffer types reported">
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.
</description>
</event>
</interface>
</protocol>
46 changes: 38 additions & 8 deletions src/screencast/wlr_screencast.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@

static void wlr_frame_buffer_destroy(struct xdpw_screencast_instance *cast) {
// Even though this check may be deemed unnecessary,
// this has been found to cause SEGFAULTs, like this one:
// this has been found to cause SEGFAULTs, like this one:
// https://github.com/emersion/xdg-desktop-portal-wlr/issues/50
if (cast->simple_frame.data != NULL) {
munmap(cast->simple_frame.data, cast->simple_frame.size);
cast->simple_frame.data = NULL;
}

if (cast->simple_frame.buffer != NULL) {
wl_buffer_destroy(cast->simple_frame.buffer);
cast->simple_frame.buffer = NULL;
Expand Down Expand Up @@ -123,6 +123,22 @@ static void wlr_frame_buffer_chparam(struct xdpw_screencast_instance *cast,
wlr_frame_buffer_destroy(cast);
}

static void wlr_frame_linux_dmabuf(void *data,
struct zwlr_screencopy_frame_v1 *frame,
uint32_t format, uint32_t width, uint32_t height) {

logprint(TRACE, "wlroots: linux_dmabuf event handler");
}

static void wlr_frame_buffer_done(void *data,
struct zwlr_screencopy_frame_v1 *frame) {
struct xdpw_screencast_instance *cast = data;

logprint(TRACE, "wlroots: buffer_done event handler");
zwlr_screencopy_frame_v1_copy_with_damage(frame, cast->simple_frame.buffer);
logprint(TRACE, "wlroots: frame copied");
}

static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame,
uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
struct xdpw_screencast_instance *cast = data;
Expand Down Expand Up @@ -150,8 +166,9 @@ static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame,
abort();
}

zwlr_screencopy_frame_v1_copy_with_damage(frame, cast->simple_frame.buffer);
logprint(TRACE, "wlroots: frame copied");
if (zwlr_screencopy_manager_v1_get_version(cast->ctx->screencopy_manager) < 3) {
wlr_frame_buffer_done(cast,frame);
}
}

static void wlr_frame_flags(void *data, struct zwlr_screencopy_frame_v1 *frame,
Expand Down Expand Up @@ -203,6 +220,8 @@ static void wlr_frame_damage(void *data, struct zwlr_screencopy_frame_v1 *frame,

static const struct zwlr_screencopy_frame_v1_listener wlr_frame_listener = {
.buffer = wlr_frame_buffer,
.buffer_done = wlr_frame_buffer_done,
.linux_dmabuf = wlr_frame_linux_dmabuf,
.flags = wlr_frame_flags,
.ready = wlr_frame_ready,
.failed = wlr_frame_failed,
Expand Down Expand Up @@ -325,28 +344,39 @@ static void wlr_registry_handle_add(void *data, struct wl_registry *reg,
uint32_t id, const char *interface, uint32_t ver) {
struct xdpw_screencast_context *ctx = data;

logprint(DEBUG, "wlroots: interface to register %s (Version: %u)",interface, ver);
if (!strcmp(interface, wl_output_interface.name)) {
struct xdpw_wlr_output *output = malloc(sizeof(*output));

output->id = id;
output->output = wl_registry_bind(reg, id, &wl_output_interface, 1);
logprint(DEBUG, "wlroots: |-- registered to interface %s (Version %u)", interface, WL_OUTPUT_VERSION);
output->output = wl_registry_bind(reg, id, &wl_output_interface, WL_OUTPUT_VERSION);

wl_output_add_listener(output->output, &wlr_output_listener, output);
wl_list_insert(&ctx->output_list, &output->link);
}

if (!strcmp(interface, zwlr_screencopy_manager_v1_interface.name)) {
uint32_t version = ver;
if (SC_MANAGER_VERSION < ver) {
version = SC_MANAGER_VERSION;
} else if (ver < SC_MANAGER_VERSION_MIN) {
version = SC_MANAGER_VERSION_MIN;
}
logprint(DEBUG, "wlroots: |-- registered to interface %s (Version %u)", interface, version);
ctx->screencopy_manager = wl_registry_bind(
reg, id, &zwlr_screencopy_manager_v1_interface, SC_MANAGER_VERSION);
reg, id, &zwlr_screencopy_manager_v1_interface, version);
}

if (strcmp(interface, wl_shm_interface.name) == 0) {
ctx->shm = wl_registry_bind(reg, id, &wl_shm_interface, 1);
logprint(DEBUG, "wlroots: |-- registered to interface %s (Version %u)", interface, WL_SHM_VERSION);
ctx->shm = wl_registry_bind(reg, id, &wl_shm_interface, WL_SHM_VERSION);
}

if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
logprint(DEBUG, "wlroots: |-- registered to interface %s (Version %u)", interface, XDG_OUTPUT_MANAGER_VERSION);
ctx->xdg_output_manager =
wl_registry_bind(reg, id, &zxdg_output_manager_v1_interface, 3);
wl_registry_bind(reg, id, &zxdg_output_manager_v1_interface, XDG_OUTPUT_MANAGER_VERSION);
}
}

Expand Down

0 comments on commit dafb25f

Please sign in to comment.