Control: tags -1 moreinfo confirmed On 2023-04-28 11:26:00 +0200, Jochen Sprickerhof wrote: > Package: release.debian.org > Severity: normal > User: [email protected] > Usertags: unblock > X-Debbugs-Cc: [email protected], Birger Schacht > <[email protected]> > Control: affects -1 + src:xdg-desktop-portal-wlr > > Please unblock package xdg-desktop-portal-wlr > > [ Reason ] > Latest Chromium in testing fails to screen share with > xdg-desktop-portal-wlr. This is fixed with xdg-desktop-portal-wlr 0.7.0.
ACK. Please remove the moreinfo tag once the package is available in unstable. Cheers > > [ Impact ] > Wayland Chromium users would not be able to share their screen. > > [ Tests ] > Only manually tests that screen share works with Chromium and Firefox. > > [ Risks ] > Small no package depend on xdg-desktop-portal-wlr. > > [ Checklist ] > [X] all changes are documented in the d/changelog > [X] I reviewed all changes and I approve them > [X] attach debdiff against the package in testing > > [ Other info ] > I think it is better to import the new upstream version instead of > trying to extract single patches as changes are mostly for fixing this > issue. > > unblock xdg-desktop-portal-wlr/0.7.0-1 > diff -Nru xdg-desktop-portal-wlr-0.6.0/debian/changelog > xdg-desktop-portal-wlr-0.7.0/debian/changelog > --- xdg-desktop-portal-wlr-0.6.0/debian/changelog 2022-07-02 > 10:11:20.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/debian/changelog 2023-04-28 > 10:59:18.000000000 +0200 > @@ -1,3 +1,11 @@ > +xdg-desktop-portal-wlr (0.7.0-1) unstable; urgency=medium > + > + * Team upload > + * New upstream release. > + - fixes screen sharing with latest chromium. (Closes: #1034735) > + > + -- Jochen Sprickerhof <[email protected]> Fri, 28 Apr 2023 10:59:18 +0200 > + > xdg-desktop-portal-wlr (0.6.0-1) unstable; urgency=medium > > * New upstream release > diff -Nru xdg-desktop-portal-wlr-0.6.0/include/screencast_common.h > xdg-desktop-portal-wlr-0.7.0/include/screencast_common.h > --- xdg-desktop-portal-wlr-0.6.0/include/screencast_common.h 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/include/screencast_common.h 2023-04-15 > 10:32:26.000000000 +0200 > @@ -11,7 +11,8 @@ > > // this seems to be right based on > // > https://github.com/flatpak/xdg-desktop-portal/blob/309a1fc0cf2fb32cceb91dbc666d20cf0a3202c2/src/screen-cast.c#L955 > -#define XDP_CAST_PROTO_VER 2 > +#define XDP_CAST_PROTO_VER 4 > +#define XDP_CAST_DATA_VER 1 > > enum cursor_modes { > HIDDEN = 1, > @@ -24,6 +25,12 @@ > WINDOW = 2, > }; > > +enum persist_modes { > + PERSIST_NONE = 0, > + PERSIST_TRANSIENT = 1, > + PERSIST_PERMANENT = 2, > +}; > + > enum buffer_type { > WL_SHM = 0, > DMABUF = 1, > @@ -60,7 +67,8 @@ > bool y_invert; > uint64_t tv_sec; > uint32_t tv_nsec; > - struct xdpw_frame_damage damage; > + struct xdpw_frame_damage damage[4]; > + uint32_t damage_count; > struct xdpw_buffer *xdpw_buffer; > struct pw_buffer *pw_buffer; > }; > @@ -116,7 +124,6 @@ > struct wl_list output_list; > struct wl_registry *registry; > struct zwlr_screencopy_manager_v1 *screencopy_manager; > - struct zxdg_output_manager_v1 *xdg_output_manager; > struct wl_shm *shm; > struct zwp_linux_dmabuf_v1 *linux_dmabuf; > struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback; > @@ -130,6 +137,16 @@ > struct wl_list screencast_instances; > }; > > +struct xdpw_screencast_target { > + struct xdpw_wlr_output *output; > + bool with_cursor; > +}; > + > +struct xdpw_screencast_restore_data { > + uint32_t version; > + const char *output_name; > +}; > + > struct xdpw_screencast_instance { > // list > struct wl_list link; > @@ -154,11 +171,10 @@ > > // wlroots > struct zwlr_screencopy_frame_v1 *frame_callback; > - struct xdpw_wlr_output *target_output; > + struct xdpw_screencast_target *target; > uint32_t max_framerate; > struct zwlr_screencopy_frame_v1 *wlr_frame; > struct xdpw_screencopy_frame_info screencopy_frame_info[2]; > - bool with_cursor; > int err; > bool quit; > bool teardown; > @@ -168,17 +184,23 @@ > struct fps_limit_state fps_limit; > }; > > +struct xdpw_screencast_session_data { > + struct xdpw_screencast_instance *screencast_instance; > + uint32_t cursor_mode; > + uint32_t persist_mode; > +}; > + > struct xdpw_wlr_output { > struct wl_list link; > uint32_t id; > struct wl_output *output; > - struct zxdg_output_v1 *xdg_output; > char *make; > char *model; > char *name; > int width; > int height; > float framerate; > + enum wl_output_transform transformation; > }; > > void randname(char *buf); > @@ -195,4 +217,6 @@ > > enum xdpw_chooser_types get_chooser_type(const char *chooser_type); > const char *chooser_type_str(enum xdpw_chooser_types chooser_type); > + > +struct xdpw_frame_damage merge_damage(struct xdpw_frame_damage *damage1, > struct xdpw_frame_damage *damage2); > #endif /* SCREENCAST_COMMON_H */ > diff -Nru xdg-desktop-portal-wlr-0.6.0/include/screenshot_common.h > xdg-desktop-portal-wlr-0.7.0/include/screenshot_common.h > --- xdg-desktop-portal-wlr-0.6.0/include/screenshot_common.h 1970-01-01 > 01:00:00.000000000 +0100 > +++ xdg-desktop-portal-wlr-0.7.0/include/screenshot_common.h 2023-04-15 > 10:32:26.000000000 +0200 > @@ -0,0 +1,6 @@ > +#ifndef SCREENSHOT_COMMON_H > +#define SCREENSHOT_COMMON_H > + > +#define XDP_SHOT_PROTO_VER 1 > + > +#endif > diff -Nru xdg-desktop-portal-wlr-0.6.0/include/wlr_screencast.h > xdg-desktop-portal-wlr-0.7.0/include/wlr_screencast.h > --- xdg-desktop-portal-wlr-0.6.0/include/wlr_screencast.h 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/include/wlr_screencast.h 2023-04-15 > 10:32:26.000000000 +0200 > @@ -3,15 +3,13 @@ > > #include "screencast_common.h" > > -#define WL_OUTPUT_VERSION 1 > +#define WL_OUTPUT_VERSION 4 > > #define SC_MANAGER_VERSION 3 > #define SC_MANAGER_VERSION_MIN 2 > > #define WL_SHM_VERSION 1 > > -#define XDG_OUTPUT_MANAGER_VERSION 3 > - > #define LINUX_DMABUF_VERSION 4 > #define LINUX_DMABUF_VERSION_MIN 3 > > @@ -20,12 +18,9 @@ > int xdpw_wlr_screencopy_init(struct xdpw_state *state); > void xdpw_wlr_screencopy_finish(struct xdpw_screencast_context *ctx); > > -struct xdpw_wlr_output *xdpw_wlr_output_find_by_name(struct wl_list > *output_list, > - const char *name); > -struct xdpw_wlr_output *xdpw_wlr_output_first(struct wl_list *output_list); > -struct xdpw_wlr_output *xdpw_wlr_output_find(struct xdpw_screencast_context > *ctx, > - struct wl_output *out, uint32_t id); > -struct xdpw_wlr_output *xdpw_wlr_output_chooser(struct > xdpw_screencast_context *ctx); > +bool xdpw_wlr_target_chooser(struct xdpw_screencast_context *ctx, struct > xdpw_screencast_target *target); > +bool xdpw_wlr_target_from_data(struct xdpw_screencast_context *ctx, struct > xdpw_screencast_target *target, > + struct xdpw_screencast_restore_data *data); > > void xdpw_wlr_frame_finish(struct xdpw_screencast_instance *cast); > void xdpw_wlr_frame_start(struct xdpw_screencast_instance *cast); > diff -Nru xdg-desktop-portal-wlr-0.6.0/include/xdpw.h > xdg-desktop-portal-wlr-0.7.0/include/xdpw.h > --- xdg-desktop-portal-wlr-0.6.0/include/xdpw.h 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/include/xdpw.h 2023-04-15 > 10:32:26.000000000 +0200 > @@ -11,6 +11,7 @@ > #endif > > #include "screencast_common.h" > +#include "screenshot_common.h" > #include "config.h" > > struct xdpw_state { > @@ -22,6 +23,7 @@ > uint32_t screencast_source_types; // bitfield of enum source_types > uint32_t screencast_cursor_modes; // bitfield of enum cursor_modes > uint32_t screencast_version; > + uint32_t screenshot_version; > struct xdpw_config *config; > int timer_poll_fd; > struct wl_list timers; > @@ -36,7 +38,7 @@ > struct wl_list link; > sd_bus_slot *slot; > char *session_handle; > - struct xdpw_screencast_instance *screencast_instance; > + struct xdpw_screencast_session_data screencast_data; > }; > > typedef void (*xdpw_event_loop_timer_func_t)(void *data); > diff -Nru xdg-desktop-portal-wlr-0.6.0/meson.build > xdg-desktop-portal-wlr-0.7.0/meson.build > --- xdg-desktop-portal-wlr-0.6.0/meson.build 2022-06-09 11:25:25.000000000 > +0200 > +++ xdg-desktop-portal-wlr-0.7.0/meson.build 2023-04-15 10:32:26.000000000 > +0200 > @@ -1,7 +1,7 @@ > project( > 'xdg-desktop-portal-wlr', > 'c', > - version: '0.6.0', > + version: '0.7.0', > license: 'MIT', > meson_version: '>=0.58.0', > default_options: ['c_std=c11', 'warning_level=2', 'werror=true'], > @@ -23,7 +23,7 @@ > inc = include_directories('include') > > rt = cc.find_library('rt') > -pipewire = dependency('libpipewire-0.3', version: '>= 0.3.41') > +pipewire = dependency('libpipewire-0.3', version: '>= 0.3.62') > wayland_client = dependency('wayland-client') > wayland_protos = dependency('wayland-protocols', version: '>=1.24') > iniparser = dependency('inih') > @@ -36,12 +36,6 @@ > epoll = dependency('epoll-shim') > endif > > -if pipewire.version() == '0.3.49' > - add_project_arguments(cc.get_supported_arguments([ > - '-D_GNU_SOURCE', > - ]), language: 'c') > -endif > - > if get_option('sd-bus-provider') == 'auto' > assert(get_option('auto_features').auto(), 'sd-bus-provider must not be > set to auto since auto_features != auto') > sdbus = dependency('libsystemd', > @@ -136,7 +130,7 @@ > install_dir: join_paths(get_option('datadir'), 'xdg-desktop-portal', > 'portals'), > ) > > -scdoc = dependency('scdoc', required: get_option('man-pages'), version: '>= > 1.9.7') > +scdoc = dependency('scdoc', required: get_option('man-pages'), version: '>= > 1.9.7', native: true) > if scdoc.found() > man_pages = ['xdg-desktop-portal-wlr.5.scd'] > foreach src : man_pages > diff -Nru xdg-desktop-portal-wlr-0.6.0/README.md > xdg-desktop-portal-wlr-0.7.0/README.md > --- xdg-desktop-portal-wlr-0.6.0/README.md 2022-06-09 11:25:25.000000000 > +0200 > +++ xdg-desktop-portal-wlr-0.7.0/README.md 2023-04-15 10:32:26.000000000 > +0200 > @@ -1,6 +1,6 @@ > # xdg-desktop-portal-wlr > > -[](https://builds.sr.ht/~emersion/xdg-desktop-portal-wlr/commits?) > +[](https://builds.sr.ht/~emersion/xdg-desktop-portal-wlr/commits/master?) > > [xdg-desktop-portal] backend for wlroots > > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/core/main.c > xdg-desktop-portal-wlr-0.7.0/src/core/main.c > --- xdg-desktop-portal-wlr-0.6.0/src/core/main.c 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/core/main.c 2023-04-15 > 10:32:26.000000000 +0200 > @@ -119,12 +119,18 @@ > .screencast_source_types = MONITOR, > .screencast_cursor_modes = HIDDEN | EMBEDDED, > .screencast_version = XDP_CAST_PROTO_VER, > + .screenshot_version = XDP_SHOT_PROTO_VER, > .config = &config, > }; > > wl_list_init(&state.xdpw_sessions); > > - xdpw_screenshot_init(&state); > + ret = xdpw_screenshot_init(&state); > + if (ret < 0) { > + logprint(ERROR, "xdpw: failed to initialize screenshot"); > + goto error; > + } > + > ret = xdpw_screencast_init(&state); > if (ret < 0) { > logprint(ERROR, "xdpw: failed to initialize screencast"); > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/core/session.c > xdg-desktop-portal-wlr-0.7.0/src/core/session.c > --- xdg-desktop-portal-wlr-0.6.0/src/core/session.c 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/core/session.c 2023-04-15 > 10:32:26.000000000 +0200 > @@ -61,7 +61,7 @@ > if (!sess) { > return; > } > - struct xdpw_screencast_instance *cast = sess->screencast_instance; > + struct xdpw_screencast_instance *cast = > sess->screencast_data.screencast_instance; > if (cast) { > assert(cast->refcount > 0); > --cast->refcount; > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/screencast/pipewire_screencast.c > xdg-desktop-portal-wlr-0.7.0/src/screencast/pipewire_screencast.c > --- xdg-desktop-portal-wlr-0.6.0/src/screencast/pipewire_screencast.c > 2022-06-09 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/screencast/pipewire_screencast.c > 2023-04-15 10:32:26.000000000 +0200 > @@ -1,10 +1,12 @@ > #include "pipewire_screencast.h" > > #include <pipewire/pipewire.h> > +#include <spa/buffer/meta.h> > #include <spa/utils/result.h> > #include <spa/param/props.h> > #include <spa/param/format-utils.h> > #include <spa/param/video/format-utils.h> > +#include <spa/pod/dynamic.h> > #include <sys/mman.h> > #include <unistd.h> > #include <assert.h> > @@ -139,7 +141,7 @@ > return ret; > } > > -static uint32_t build_formats(struct spa_pod_builder *b, struct > xdpw_screencast_instance *cast, > +static uint32_t build_formats(struct spa_pod_builder *b[static 2], struct > xdpw_screencast_instance *cast, > const struct spa_pod *params[static 2]) { > uint32_t param_count; > uint32_t modifier_count; > @@ -148,17 +150,20 @@ > if (!cast->avoid_dmabufs && > build_modifierlist(cast, > cast->screencopy_frame_info[DMABUF].format, &modifiers, &modifier_count) && > modifier_count > 0) { > param_count = 2; > - params[0] = build_format(b, > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[DMABUF].format), > + params[0] = build_format(b[0], > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[DMABUF].format), > cast->screencopy_frame_info[DMABUF].width, > cast->screencopy_frame_info[DMABUF].height, cast->framerate, > modifiers, modifier_count); > - params[1] = build_format(b, > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format), > + assert(params[0] != NULL); > + params[1] = build_format(b[1], > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format), > cast->screencopy_frame_info[WL_SHM].width, > cast->screencopy_frame_info[WL_SHM].height, cast->framerate, > NULL, 0); > + assert(params[1] != NULL); > } else { > param_count = 1; > - params[0] = build_format(b, > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format), > + params[0] = build_format(b[0], > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[WL_SHM].format), > cast->screencopy_frame_info[WL_SHM].width, > cast->screencopy_frame_info[WL_SHM].height, cast->framerate, > NULL, 0); > + assert(params[0] != NULL); > } > free(modifiers); > return param_count; > @@ -196,10 +201,9 @@ > logprint(TRACE, "pipewire: stream parameters changed"); > struct xdpw_screencast_instance *cast = data; > struct pw_stream *stream = cast->stream; > - uint8_t params_buffer[1024]; > - struct spa_pod_builder b = > - SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer)); > - const struct spa_pod *params[3]; > + uint8_t params_buffer[3][1024]; > + struct spa_pod_dynamic_builder b[3]; > + const struct spa_pod *params[4]; > uint32_t blocks; > uint32_t data_type; > > @@ -207,6 +211,10 @@ > return; > } > > + spa_pod_dynamic_builder_init(&b[0], params_buffer[0], > sizeof(params_buffer[0]), 2048); > + spa_pod_dynamic_builder_init(&b[1], params_buffer[1], > sizeof(params_buffer[1]), 2048); > + spa_pod_dynamic_builder_init(&b[2], params_buffer[2], > sizeof(params_buffer[2]), 2048); > + > spa_format_video_raw_parse(param, &cast->pwr_format); > cast->framerate = (uint32_t)(cast->pwr_format.max_framerate.num / > cast->pwr_format.max_framerate.denom); > > @@ -224,6 +232,7 @@ > uint32_t flags = GBM_BO_USE_RENDERING; > uint64_t modifier; > uint32_t n_params; > + struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b}; > > struct gbm_bo *bo = > gbm_bo_create_with_modifiers2(cast->ctx->gbm, > > cast->screencopy_frame_info[cast->buffer_type].width, > cast->screencopy_frame_info[cast->buffer_type].height, > @@ -241,6 +250,9 @@ > flags = > cast->ctx->state->config->screencast_conf.force_mod_linear ? > GBM_BO_USE_RENDERING | > GBM_BO_USE_LINEAR : GBM_BO_USE_RENDERING; > break; > + case DRM_FORMAT_MOD_LINEAR: > + flags = GBM_BO_USE_RENDERING | > GBM_BO_USE_LINEAR; > + break; > default: > continue; > } > @@ -257,18 +269,24 @@ > logprint(WARN, "pipewire: unable to allocate a dmabuf. > Falling back to shm"); > cast->avoid_dmabufs = true; > > - n_params = build_formats(&b, cast, ¶ms[0]); > + n_params = build_formats(builder, cast, ¶ms[0]); > pw_stream_update_params(stream, params, n_params); > + spa_pod_dynamic_builder_clean(&b[0]); > + spa_pod_dynamic_builder_clean(&b[1]); > + spa_pod_dynamic_builder_clean(&b[2]); > return; > > fixate_format: > - params[0] = fixate_format(&b, > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[cast->buffer_type].format), > + params[0] = fixate_format(&b[2].b, > xdpw_format_pw_from_drm_fourcc(cast->screencopy_frame_info[cast->buffer_type].format), > > cast->screencopy_frame_info[cast->buffer_type].width, > cast->screencopy_frame_info[cast->buffer_type].height, cast->framerate, > &modifier); > > - n_params = build_formats(&b, cast, ¶ms[1]); > + n_params = build_formats(builder, cast, ¶ms[1]); > n_params++; > > pw_stream_update_params(stream, params, n_params); > + spa_pod_dynamic_builder_clean(&b[0]); > + spa_pod_dynamic_builder_clean(&b[1]); > + spa_pod_dynamic_builder_clean(&b[2]); > return; > } > > @@ -291,20 +309,37 @@ > logprint(DEBUG, "pipewire: size: (%u, %u)", > cast->pwr_format.size.width, cast->pwr_format.size.height); > logprint(DEBUG, "pipewire: max_framerate: (%u / %u)", > cast->pwr_format.max_framerate.num, cast->pwr_format.max_framerate.denom); > > - params[0] = build_buffer(&b, blocks, > cast->screencopy_frame_info[cast->buffer_type].size, > + params[0] = build_buffer(&b[0].b, blocks, > cast->screencopy_frame_info[cast->buffer_type].size, > cast->screencopy_frame_info[cast->buffer_type].stride, > data_type); > > - params[1] = spa_pod_builder_add_object(&b, > + params[1] = spa_pod_builder_add_object(&b[1].b, > SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, > SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), > SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct > spa_meta_header))); > > - pw_stream_update_params(stream, params, 2); > + params[2] = spa_pod_builder_add_object(&b[1].b, > + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, > + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoTransform), > + SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct > spa_meta_videotransform))); > + > + params[3] = spa_pod_builder_add_object(&b[2].b, > + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, > + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoDamage), > + SPA_PARAM_META_size, SPA_POD_CHOICE_RANGE_Int( > + sizeof(struct spa_meta_region) * 4, > + sizeof(struct spa_meta_region) * 1, > + sizeof(struct spa_meta_region) * 4)); > + > + pw_stream_update_params(stream, params, 4); > + spa_pod_dynamic_builder_clean(&b[0]); > + spa_pod_dynamic_builder_clean(&b[1]); > + spa_pod_dynamic_builder_clean(&b[2]); > } > > static void pwr_handle_stream_add_buffer(void *data, struct pw_buffer > *buffer) { > struct xdpw_screencast_instance *cast = data; > struct spa_data *d; > + enum spa_data_type t; > > logprint(DEBUG, "pipewire: add buffer event handle"); > > @@ -313,17 +348,17 @@ > // Select buffer type from negotiation result > if ((d[0].type & (1u << SPA_DATA_MemFd)) > 0) { > assert(cast->buffer_type == WL_SHM); > - d[0].type = SPA_DATA_MemFd; > + t = SPA_DATA_MemFd; > } else if ((d[0].type & (1u << SPA_DATA_DmaBuf)) > 0) { > assert(cast->buffer_type == DMABUF); > - d[0].type = SPA_DATA_DmaBuf; > + t = SPA_DATA_DmaBuf; > } else { > logprint(ERROR, "pipewire: unsupported buffer type"); > cast->err = 1; > return; > } > > - logprint(TRACE, "pipewire: selected buffertype %u", d[0].type); > + logprint(TRACE, "pipewire: selected buffertype %u", t); > > struct xdpw_buffer *xdpw_buffer = xdpw_buffer_create(cast, > cast->buffer_type, &cast->screencopy_frame_info[cast->buffer_type]); > if (xdpw_buffer == NULL) { > @@ -336,6 +371,7 @@ > > assert(xdpw_buffer->plane_count >= 0 && buffer->buffer->n_datas == > (uint32_t)xdpw_buffer->plane_count); > for (uint32_t plane = 0; plane < buffer->buffer->n_datas; plane++) { > + d[plane].type = t; > d[plane].maxsize = xdpw_buffer->size[plane]; > d[plane].mapoffset = 0; > d[plane].chunk->size = xdpw_buffer->size[plane]; > @@ -419,6 +455,44 @@ > logprint(TRACE, "pipewire: timestamp %"PRId64, h->pts); > } > > + struct spa_meta_videotransform *vt; > + if ((vt = spa_buffer_find_meta_data(spa_buf, SPA_META_VideoTransform, > sizeof(*vt)))) { > + vt->transform = cast->target->output->transformation; > + logprint(TRACE, "pipewire: transformation %u", vt->transform); > + } > + > + struct spa_meta *damage; > + if ((damage = spa_buffer_find_meta(spa_buf, SPA_META_VideoDamage))) { > + struct spa_region *d_region = spa_meta_first(damage); > + uint32_t damage_counter = 0; > + do { > + if (damage_counter >= cast->current_frame.damage_count) > { > + *d_region = SPA_REGION(0, 0, 0, 0); > + logprint(TRACE, "pipewire: end damage %u %u,%u > (%ux%u)", damage_counter, > + d_region->position.x, > d_region->position.y, d_region->size.width, d_region->size.height); > + break; > + } > + *d_region = > SPA_REGION(cast->current_frame.damage[damage_counter].x, > + cast->current_frame.damage[damage_counter].y, > + > cast->current_frame.damage[damage_counter].width, > + > cast->current_frame.damage[damage_counter].height); > + logprint(TRACE, "pipewire: damage %u %u,%u (%ux%u)", > damage_counter, > + d_region->position.x, > d_region->position.y, d_region->size.width, d_region->size.height); > + damage_counter++; > + } while (spa_meta_check(d_region + 1, damage) && d_region++); > + > + if (damage_counter < cast->current_frame.damage_count) { > + struct xdpw_frame_damage damage = > + {d_region->position.x, d_region->position.x, > d_region->size.width, d_region->size.height}; > + for (; damage_counter < > cast->current_frame.damage_count; damage_counter++) { > + damage = merge_damage(&damage, > &cast->current_frame.damage[damage_counter]); > + } > + *d_region = SPA_REGION(damage.x, damage.y, > damage.width, damage.height); > + logprint(TRACE, "pipewire: collected damage %u %u,%u > (%ux%u)", damage_counter, > + d_region->position.x, > d_region->position.y, d_region->size.width, d_region->size.height); > + } > + } > + > if (buffer_corrupt) { > for (uint32_t plane = 0; plane < spa_buf->n_datas; plane++) { > d[plane].chunk->flags = SPA_CHUNK_FLAG_CORRUPTED; > @@ -453,14 +527,18 @@ > void pwr_update_stream_param(struct xdpw_screencast_instance *cast) { > logprint(TRACE, "pipewire: stream update parameters"); > struct pw_stream *stream = cast->stream; > - uint8_t params_buffer[1024]; > - struct spa_pod_builder b = > - SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer)); > + uint8_t params_buffer[2][1024]; > + struct spa_pod_dynamic_builder b[2]; > + spa_pod_dynamic_builder_init(&b[0], params_buffer[0], > sizeof(params_buffer[0]), 2048); > + spa_pod_dynamic_builder_init(&b[1], params_buffer[1], > sizeof(params_buffer[1]), 2048); > const struct spa_pod *params[2]; > > - uint32_t n_params = build_formats(&b, cast, params); > + struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b}; > + uint32_t n_params = build_formats(builder, cast, params); > > pw_stream_update_params(stream, params, n_params); > + spa_pod_dynamic_builder_clean(&b[0]); > + spa_pod_dynamic_builder_clean(&b[1]); > } > > void xdpw_pwr_stream_create(struct xdpw_screencast_instance *cast) { > @@ -469,8 +547,10 @@ > > pw_loop_enter(state->pw_loop); > > - uint8_t buffer[1024]; > - struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); > + uint8_t buffer[2][1024]; > + struct spa_pod_dynamic_builder b[2]; > + spa_pod_dynamic_builder_init(&b[0], buffer[0], sizeof(buffer[0]), 2048); > + spa_pod_dynamic_builder_init(&b[1], buffer[1], sizeof(buffer[1]), 2048); > const struct spa_pod *params[2]; > > char name[] = "xdpw-stream-XXXXXX"; > @@ -486,7 +566,10 @@ > } > cast->pwr_stream_state = false; > > - uint32_t param_count = build_formats(&b, cast, params); > + struct spa_pod_builder *builder[2] = {&b[0].b, &b[1].b}; > + uint32_t param_count = build_formats(builder, cast, params); > + spa_pod_dynamic_builder_clean(&b[0]); > + spa_pod_dynamic_builder_clean(&b[1]); > > pw_stream_add_listener(cast->stream, &cast->stream_listener, > &pwr_stream_events, cast); > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/screencast/screencast.c > xdg-desktop-portal-wlr-0.7.0/src/screencast/screencast.c > --- xdg-desktop-portal-wlr-0.6.0/src/screencast/screencast.c 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/screencast/screencast.c 2023-04-15 > 10:32:26.000000000 +0200 > @@ -48,7 +48,7 @@ > } > > void xdpw_screencast_instance_init(struct xdpw_screencast_context *ctx, > - struct xdpw_screencast_instance *cast, struct xdpw_wlr_output > *out, bool with_cursor) { > + struct xdpw_screencast_instance *cast, struct > xdpw_screencast_target *target) { > > // only run exec_before if there's no other instance running that > already ran it > if (wl_list_empty(&ctx->screencast_instances)) { > @@ -60,15 +60,14 @@ > } > > cast->ctx = ctx; > - cast->target_output = out; > + cast->target = target; > if (ctx->state->config->screencast_conf.max_fps > 0) { > - cast->max_framerate = > ctx->state->config->screencast_conf.max_fps < (uint32_t)out->framerate ? > - ctx->state->config->screencast_conf.max_fps : > (uint32_t)out->framerate; > + cast->max_framerate = > ctx->state->config->screencast_conf.max_fps < > (uint32_t)target->output->framerate ? > + ctx->state->config->screencast_conf.max_fps : > (uint32_t)target->output->framerate; > } else { > - cast->max_framerate = (uint32_t)out->framerate; > + cast->max_framerate = (uint32_t)target->output->framerate; > } > cast->framerate = cast->max_framerate; > - cast->with_cursor = with_cursor; > cast->refcount = 1; > cast->node_id = SPA_ID_INVALID; > cast->avoid_dmabufs = false; > @@ -93,6 +92,7 @@ > } > } > > + free(cast->target); > wl_list_remove(&cast->link); > xdpw_pwr_stream_destroy(cast); > assert(wl_list_length(&cast->buffer_list) == 0); > @@ -102,13 +102,14 @@ > void xdpw_screencast_instance_teardown(struct xdpw_screencast_instance > *cast) { > struct xdpw_session *sess, *tmp; > wl_list_for_each_safe(sess, tmp, &cast->ctx->state->xdpw_sessions, > link) { > - if (sess->screencast_instance == cast) { > + if (sess->screencast_data.screencast_instance == cast) { > xdpw_session_destroy(sess); > } > } > } > > -bool setup_outputs(struct xdpw_screencast_context *ctx, struct xdpw_session > *sess, bool with_cursor) { > +bool setup_target(struct xdpw_screencast_context *ctx, struct xdpw_session > *sess, struct xdpw_screencast_restore_data *data) { > + bool target_initialized = false; > > struct xdpw_wlr_output *output, *tmp_o; > wl_list_for_each_reverse_safe(output, tmp_o, &ctx->output_list, link) { > @@ -116,29 +117,57 @@ > output->make, output->model, output->id, output->name); > } > > - struct xdpw_wlr_output *out; > - out = xdpw_wlr_output_chooser(ctx); > - if (!out) { > + struct xdpw_screencast_target *target = calloc(1, sizeof(struct > xdpw_screencast_target)); > + if (!target) { > + logprint(ERROR, "wlroots: unable to allocate target"); > + return false; > + } > + target->with_cursor = sess->screencast_data.cursor_mode == EMBEDDED; > + if (data) { > + target_initialized = xdpw_wlr_target_from_data(ctx, target, > data); > + } > + if (!target_initialized) { > + target_initialized = xdpw_wlr_target_chooser(ctx, target); > + //TODO: Chooser option to confirm the persist mode > + const char *env_persist_str = getenv("XDPW_PERSIST_MODE"); > + if (env_persist_str) { > + if (strcmp(env_persist_str, "transient") == 0) { > + sess->screencast_data.persist_mode = > sess->screencast_data.persist_mode > PERSIST_TRANSIENT > + ? PERSIST_TRANSIENT : > sess->screencast_data.persist_mode; > + } else if (strcmp(env_persist_str, "permanent") == 0) { > + sess->screencast_data.persist_mode = > sess->screencast_data.persist_mode > PERSIST_PERMANENT > + ? PERSIST_PERMANENT : > sess->screencast_data.persist_mode; > + } else { > + sess->screencast_data.persist_mode = > PERSIST_NONE; > + } > + > + } else { > + sess->screencast_data.persist_mode = PERSIST_NONE; > + } > + } > + if (!target_initialized) { > logprint(ERROR, "wlroots: no output found"); > + free(target); > return false; > } > + assert(target->output); > > // Disable screencast sharing to avoid sharing between dmabuf and shm > capable clients > /* > struct xdpw_screencast_instance *cast, *tmp_c; > wl_list_for_each_reverse_safe(cast, tmp_c, &ctx->screencast_instances, > link) { > logprint(INFO, "xdpw: existing screencast instance: %d %s > cursor", > - cast->target_output->id, > - cast->with_cursor ? "with" : "without"); > + cast->target->output->id, > + cast->target->with_cursor ? "with" : "without"); > > - if (cast->target_output->id == out->id && cast->with_cursor == > with_cursor) { > + if (cast->target->output->id == target->output->id && > cast->target->with_cursor == target->with_cursor) { > if (cast->refcount == 0) { > logprint(DEBUG, > "xdpw: matching cast instance found, " > "but is already scheduled for > destruction, skipping"); > } > else { > - sess->screencast_instance = cast; > + sess->screencast_data.screencast_instance = > cast; > ++cast->refcount; > } > logprint(INFO, "xdpw: screencast instance %p now has %d > references", > @@ -147,13 +176,12 @@ > } > */ > > - if (!sess->screencast_instance) { > - sess->screencast_instance = calloc(1, sizeof(struct > xdpw_screencast_instance)); > - xdpw_screencast_instance_init(ctx, sess->screencast_instance, > - out, with_cursor); > + if (!sess->screencast_data.screencast_instance) { > + sess->screencast_data.screencast_instance = calloc(1, > sizeof(struct xdpw_screencast_instance)); > + xdpw_screencast_instance_init(ctx, > sess->screencast_data.screencast_instance, target); > } > logprint(INFO, "wlroots: output: %s", > - sess->screencast_instance->target_output->name); > + > sess->screencast_data.screencast_instance->target->output->name); > > return true; > > @@ -276,9 +304,6 @@ > > logprint(INFO, "dbus: select sources method invoked"); > > - // default to embedded cursor mode if not specified > - bool cursor_embedded = true; > - > char *request_handle, *session_handle, *app_id; > ret = sd_bus_message_read(msg, "oos", &request_handle, &session_handle, > &app_id); > if (ret < 0) { > @@ -293,8 +318,26 @@ > logprint(INFO, "dbus: session_handle: %s", session_handle); > logprint(INFO, "dbus: app_id: %s", app_id); > > + sess = NULL; > + wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) > { > + if (strcmp(sess->session_handle, session_handle) == 0) { > + logprint(DEBUG, "dbus: select sources: found > matching session %s", sess->session_handle); > + break; > + } > + } > + if (!sess) { > + logprint(WARN, "dbus: select sources: no matching session %s > found", sess->session_handle); > + goto error; > + } > + > + // default to embedded cursor mode if not specified > + sess->screencast_data.cursor_mode = EMBEDDED; > + // default to no persist if not specified > + sess->screencast_data.persist_mode = PERSIST_NONE; > + > char *key; > int innerRet = 0; > + struct xdpw_screencast_restore_data restore_data = {0}; > while ((ret = sd_bus_message_enter_container(msg, 'e', "sv")) > 0) { > innerRet = sd_bus_message_read(msg, "s", &key); > if (innerRet < 0) { > @@ -314,16 +357,87 @@ > } > logprint(INFO, "dbus: option types:%x", mask); > } else if (strcmp(key, "cursor_mode") == 0) { > - uint32_t cursor_mode; > - sd_bus_message_read(msg, "v", "u", &cursor_mode); > - if (cursor_mode & HIDDEN) { > - cursor_embedded = false; > - } > - if (cursor_mode & METADATA) { > + sd_bus_message_read(msg, "v", "u", > &sess->screencast_data.cursor_mode); > + if (sess->screencast_data.cursor_mode & METADATA) { > logprint(ERROR, "dbus: unsupported cursor mode > requested, cancelling"); > goto error; > } > - logprint(INFO, "dbus: option cursor_mode:%x", > cursor_mode); > + logprint(INFO, "dbus: option cursor_mode:%x", > sess->screencast_data.cursor_mode); > + } else if (strcmp(key, "restore_data") == 0) { > + logprint(INFO, "dbus: restore data available"); > + char *portal_vendor; > + innerRet = sd_bus_message_enter_container(msg, 'v', > "(suv)"); > + if (innerRet < 0) { > + logprint(ERROR, "dbus: error entering variant"); > + return innerRet; > + } > + innerRet = sd_bus_message_enter_container(msg, 'r', > "suv"); > + if (innerRet < 0) { > + logprint(ERROR, "dbus: error entering struct"); > + return innerRet; > + } > + sd_bus_message_read(msg, "s", &portal_vendor); > + if (strcmp(portal_vendor, "wlroots") != 0) { > + logprint(INFO, "dbus: skipping restore_data > from another vendor (%s)", portal_vendor); > + sd_bus_message_skip(msg, "uv"); > + continue; > + } > + sd_bus_message_read(msg, "u", &restore_data.version); > + if (restore_data.version == 1) { > + innerRet = sd_bus_message_enter_container(msg, > 'v', "a{sv}"); > + if (innerRet < 0) { > + return innerRet; > + } > + innerRet = sd_bus_message_enter_container(msg, > 'a', "{sv}"); > + if (innerRet < 0) { > + return innerRet; > + } > + logprint(INFO, "dbus: restoring session from > data"); > + int rdRet; > + char *rdKey; > + while ((innerRet = > sd_bus_message_enter_container(msg, 'e', "sv")) > 0) { > + rdRet = sd_bus_message_read(msg, "s", > &rdKey); > + if (rdRet < 0) { > + return rdRet; > + } > + if (strcmp(rdKey, "output_name") == 0) { > + sd_bus_message_read(msg, "v", > "s", &restore_data.output_name); > + logprint(INFO, "dbus: option > restore_data.output_name: %s", restore_data.output_name); > + } else { > + logprint(WARN, "dbus: unknown > option %s", rdKey); > + sd_bus_message_skip(msg, "v"); > + } > + innerRet = > sd_bus_message_exit_container(msg); // dictionary > + if (innerRet < 0) { > + return innerRet; > + } > + } > + if (innerRet < 0) { > + return innerRet; > + } > + innerRet = sd_bus_message_exit_container(msg); > //array > + if (innerRet < 0) { > + return innerRet; > + } > + innerRet = sd_bus_message_exit_container(msg); > //variant > + if (innerRet < 0) { > + return innerRet; > + } > + } else { > + sd_bus_message_skip(msg, "v"); > + logprint(ERROR, "Unknown restore_data version: > %u", restore_data.version); > + } > + innerRet = sd_bus_message_exit_container(msg); // struct > + if (innerRet < 0) { > + return innerRet; > + } > + innerRet = sd_bus_message_exit_container(msg); // > variant > + if (innerRet < 0) { > + return innerRet; > + } > + } else if (strcmp(key, "persist_mode") == 0) { > + sd_bus_message_read(msg, "v", "u", > &sess->screencast_data.persist_mode); > + logprint(INFO, "dbus: option persist_mode:%u", > sess->screencast_data.persist_mode); > } else { > logprint(WARN, "dbus: unknown option %s", key); > sd_bus_message_skip(msg, "v"); > @@ -342,13 +456,7 @@ > return ret; > } > > - bool output_selection_canceled = 1; > - wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) > { > - if (strcmp(sess->session_handle, session_handle) == 0) { > - logprint(DEBUG, "dbus: select sources: found > matching session %s", sess->session_handle); > - output_selection_canceled = !setup_outputs(ctx, > sess, cursor_embedded); > - } > - } > + bool output_selection_canceled = !setup_target(ctx, sess, > restore_data.version > 0 ? &restore_data : NULL); > > ret = sd_bus_message_new_method_return(msg, &reply); > if (ret < 0) { > @@ -370,11 +478,8 @@ > return 0; > > error: > - wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) > { > - if (strcmp(sess->session_handle, session_handle) == 0) { > - logprint(DEBUG, "dbus: select sources error: > destroying matching session %s", sess->session_handle); > - xdpw_session_destroy(sess); > - } > + if (sess) { > + xdpw_session_destroy(sess); > } > > ret = sd_bus_message_new_method_return(msg, &reply); > @@ -443,7 +548,7 @@ > wl_list_for_each_reverse_safe(sess, tmp_s, &state->xdpw_sessions, link) > { > if (strcmp(sess->session_handle, session_handle) == 0) { > logprint(DEBUG, "dbus: start: found matching > session %s", sess->session_handle); > - cast = sess->screencast_instance; > + cast = > sess->screencast_data.screencast_instance; > } > } > if (!cast) { > @@ -472,12 +577,41 @@ > } > > logprint(DEBUG, "dbus: start: returning node %d", (int)cast->node_id); > - ret = sd_bus_message_append(reply, "ua{sv}", PORTAL_RESPONSE_SUCCESS, 1, > + ret = sd_bus_message_append(reply, "u", PORTAL_RESPONSE_SUCCESS); > + if (ret < 0) { > + return ret; > + } > + ret = sd_bus_message_open_container(reply, 'a', "{sv}"); > + if (ret < 0) { > + return ret; > + } > + ret = sd_bus_message_append(reply, "{sv}", > "streams", "a(ua{sv})", 1, > - cast->node_id, 2, > + cast->node_id, 3, > "position", "(ii)", 0, 0, > - "size", "(ii)", cast->screencopy_frame_info[WL_SHM].width, > cast->screencopy_frame_info[WL_SHM].height); > + "size", "(ii)", cast->screencopy_frame_info[WL_SHM].width, > cast->screencopy_frame_info[WL_SHM].height, > + "source_type", "u", 1 << MONITOR); > + if (ret < 0) { > + return ret; > + } > + ret = sd_bus_message_append(reply, "{sv}", > + "persist_mode", "u", sess->screencast_data.persist_mode); > + if (ret < 0) { > + return ret; > + } > + if (sess->screencast_data.persist_mode != PERSIST_NONE) { > + struct xdpw_screencast_restore_data restore_data; > + restore_data.output_name = cast->target->output->name; > + ret = sd_bus_message_append(reply, "{sv}", > + "restore_data", "(suv)", > + "wlroots", XDP_CAST_DATA_VER, > + "a{sv}", 1, "output_name", "s", > restore_data.output_name); > + if (ret < 0) { > + return ret; > + } > + } > > + ret = sd_bus_message_close_container(reply); > if (ret < 0) { > return ret; > } > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/screencast/screencast_common.c > xdg-desktop-portal-wlr-0.7.0/src/screencast/screencast_common.c > --- xdg-desktop-portal-wlr-0.6.0/src/screencast/screencast_common.c > 2022-06-09 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/screencast/screencast_common.c > 2023-04-15 10:32:26.000000000 +0200 > @@ -153,6 +153,12 @@ > frame_info->format, flags); > } > > + // Fallback for linear buffers via the implicit api > + if (buffer->bo == NULL && cast->pwr_format.modifier == > DRM_FORMAT_MOD_LINEAR) { > + buffer->bo = gbm_bo_create(cast->ctx->gbm, > frame_info->width, frame_info->height, > + frame_info->format, flags | > GBM_BO_USE_LINEAR); > + } > + > if (buffer->bo == NULL) { > logprint(ERROR, "xdpw: failed to create gbm_bo"); > free(buffer); > @@ -404,3 +410,17 @@ > fprintf(stderr, "Could not find chooser type %d\n", chooser_type); > abort(); > } > + > +struct xdpw_frame_damage merge_damage(struct xdpw_frame_damage *damage1, > struct xdpw_frame_damage *damage2) { > + struct xdpw_frame_damage damage; > + uint32_t x0, y0; > + damage.x = damage1->x < damage2->y ? damage1->x : damage2->x; > + damage.y = damage1->y < damage2->y ? damage1->y : damage2->y; > + > + x0 = damage1->x + damage1->width < damage2->x + damage2->width ? > damage2->x + damage2->width : damage1->x + damage1->width; > + y0 = damage1->y + damage1->height < damage2->y + damage2->height ? > damage2->y + damage2->height : damage1->y + damage1->height; > + damage.width = x0 - damage.x; > + damage.height = y0 - damage.y; > + > + return damage; > +} > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/screencast/wlr_screencast.c > xdg-desktop-portal-wlr-0.7.0/src/screencast/wlr_screencast.c > --- xdg-desktop-portal-wlr-0.6.0/src/screencast/wlr_screencast.c > 2022-06-09 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/screencast/wlr_screencast.c > 2023-04-15 10:32:26.000000000 +0200 > @@ -2,7 +2,6 @@ > > #include "linux-dmabuf-unstable-v1-client-protocol.h" > #include "wlr-screencopy-unstable-v1-client-protocol.h" > -#include "xdg-output-unstable-v1-client-protocol.h" > #include <fcntl.h> > #include <limits.h> > #include <stdbool.h> > @@ -174,6 +173,7 @@ > return; > } > > + cast->current_frame.damage_count = 0; > zwlr_screencopy_frame_v1_copy_with_damage(frame, > cast->current_frame.xdpw_buffer->buffer); > logprint(TRACE, "wlroots: frame copied"); > > @@ -200,10 +200,13 @@ > > logprint(TRACE, "wlroots: damage event handler"); > > - cast->current_frame.damage.x = x; > - cast->current_frame.damage.y = y; > - cast->current_frame.damage.width = width; > - cast->current_frame.damage.height = height; > + logprint(TRACE, "wlroots: damage %"PRIu32": > %"PRIu32",%"PRIu32"x%"PRIu32",%"PRIu32, cast->current_frame.damage_count, x, > y, width, height); > + struct xdpw_frame_damage damage = {x, y, width, height}; > + if (cast->current_frame.damage_count < 4) { > + cast->current_frame.damage[cast->current_frame.damage_count++] > = damage; > + } else { > + cast->current_frame.damage[3] = > merge_damage(&cast->current_frame.damage[3], &damage); > + } > } > > static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 > *frame, > @@ -250,7 +253,7 @@ > > void xdpw_wlr_register_cb(struct xdpw_screencast_instance *cast) { > cast->frame_callback = zwlr_screencopy_manager_v1_capture_output( > - cast->ctx->screencopy_manager, cast->with_cursor, > cast->target_output->output); > + cast->ctx->screencopy_manager, cast->target->with_cursor, > cast->target->output->output); > > zwlr_screencopy_frame_v1_add_listener(cast->frame_callback, > &wlr_frame_listener, cast); > @@ -263,6 +266,7 @@ > struct xdpw_wlr_output *output = data; > output->make = strdup(make); > output->model = strdup(model); > + output->transformation = transform; > } > > static void wlr_output_handle_mode(void *data, struct wl_output *wl_output, > @@ -282,55 +286,54 @@ > /* Nothing to do */ > } > > +static void wlr_output_handle_name(void *data, struct wl_output *wl_output, > + const char *name) { > + struct xdpw_wlr_output *output = data; > + output->name = strdup(name); > +} > + > +static void wlr_output_handle_description(void *data, struct wl_output > *wl_output, > + const char *description) { > + /* Nothing to do */ > +} > + > static const struct wl_output_listener wlr_output_listener = { > .geometry = wlr_output_handle_geometry, > .mode = wlr_output_handle_mode, > .done = wlr_output_handle_done, > .scale = wlr_output_handle_scale, > + .name = wlr_output_handle_name, > + .description = wlr_output_handle_description, > }; > > -static void wlr_xdg_output_name(void *data, struct zxdg_output_v1 > *xdg_output, > - const char *name) { > - struct xdpw_wlr_output *output = data; > - > - output->name = strdup(name); > -}; > - > -static void noop() { > - // This space intentionally left blank > +static struct xdpw_wlr_output *xdpw_wlr_output_first(struct wl_list > *output_list) { > + struct xdpw_wlr_output *output, *tmp; > + wl_list_for_each_safe(output, tmp, output_list, link) { > + return output; > + } > + return NULL; > } > > -static const struct zxdg_output_v1_listener wlr_xdg_output_listener = { > - .logical_position = noop, > - .logical_size = noop, > - .done = NULL, /* Deprecated */ > - .description = noop, > - .name = wlr_xdg_output_name, > -}; > - > -static void wlr_add_xdg_output_listener(struct xdpw_wlr_output *output, > - struct zxdg_output_v1 *xdg_output) { > - output->xdg_output = xdg_output; > - zxdg_output_v1_add_listener(output->xdg_output, > &wlr_xdg_output_listener, > - output); > -} > - > -static void wlr_init_xdg_output(struct xdpw_screencast_context *ctx, > - struct xdpw_wlr_output *output) { > - struct zxdg_output_v1 *xdg_output = > - zxdg_output_manager_v1_get_xdg_output(ctx->xdg_output_manager, > - output->output); > - wlr_add_xdg_output_listener(output, xdg_output); > +static struct xdpw_wlr_output *xdpw_wlr_output_find_by_name(struct wl_list > *output_list, > + const char *name) { > + struct xdpw_wlr_output *output, *tmp; > + wl_list_for_each_safe(output, tmp, output_list, link) { > + if (strcmp(output->name, name) == 0) { > + return output; > + } > + } > + return NULL; > } > > -static void wlr_init_xdg_outputs(struct xdpw_screencast_context *ctx) { > +static struct xdpw_wlr_output *xdpw_wlr_output_find(struct > xdpw_screencast_context *ctx, > + struct wl_output *out, uint32_t id) { > struct xdpw_wlr_output *output, *tmp; > wl_list_for_each_safe(output, tmp, &ctx->output_list, link) { > - if (output->xdg_output) { > - continue; > + if ((output->output == out) || (output->id == id)) { > + return output; > } > - wlr_init_xdg_output(ctx, output); > } > + return NULL; > } > > static pid_t spawn_chooser(char *cmd, int chooser_in[2], int chooser_out[2]) > { > @@ -493,7 +496,7 @@ > return xdpw_wlr_output_first(output_list); > } > > -struct xdpw_wlr_output *xdpw_wlr_output_chooser(struct > xdpw_screencast_context *ctx) { > +static struct xdpw_wlr_output *xdpw_wlr_output_chooser(struct > xdpw_screencast_context *ctx) { > switch (ctx->state->config->screencast_conf.chooser_type) { > case XDPW_CHOOSER_DEFAULT: > return wlr_output_chooser_default(&ctx->output_list); > @@ -531,41 +534,27 @@ > return NULL; > } > > -struct xdpw_wlr_output *xdpw_wlr_output_first(struct wl_list *output_list) { > - struct xdpw_wlr_output *output, *tmp; > - wl_list_for_each_safe(output, tmp, output_list, link) { > - return output; > - } > - return NULL; > +bool xdpw_wlr_target_chooser(struct xdpw_screencast_context *ctx, struct > xdpw_screencast_target *target) { > + target->output = xdpw_wlr_output_chooser(ctx); > + return target->output != NULL; > } > > -struct xdpw_wlr_output *xdpw_wlr_output_find_by_name(struct wl_list > *output_list, > - const char *name) { > - struct xdpw_wlr_output *output, *tmp; > - wl_list_for_each_safe(output, tmp, output_list, link) { > - if (strcmp(output->name, name) == 0) { > - return output; > - } > - } > - return NULL; > -} > +bool xdpw_wlr_target_from_data(struct xdpw_screencast_context *ctx, struct > xdpw_screencast_target *target, > + struct xdpw_screencast_restore_data *data) { > + struct xdpw_wlr_output *out = NULL; > + out = xdpw_wlr_output_find_by_name(&ctx->output_list, > data->output_name); > > -struct xdpw_wlr_output *xdpw_wlr_output_find(struct xdpw_screencast_context > *ctx, > - struct wl_output *out, uint32_t id) { > - struct xdpw_wlr_output *output, *tmp; > - wl_list_for_each_safe(output, tmp, &ctx->output_list, link) { > - if ((output->output == out) || (output->id == id)) { > - return output; > - } > + if (!out) { > + return false; > } > - return NULL; > + target->output = out; > + return true; > } > > static void wlr_remove_output(struct xdpw_wlr_output *out) { > free(out->name); > free(out->make); > free(out->model); > - zxdg_output_v1_destroy(out->xdg_output); > wl_output_destroy(out->output); > wl_list_remove(&out->link); > free(out); > @@ -598,6 +587,10 @@ > wlr_format_modifier_pair_add(ctx, format, modifier); > } > > +static void noop() { > + // This space intentionally left blank > +} > + > static const struct zwp_linux_dmabuf_v1_listener linux_dmabuf_listener = { > .format = noop, > .modifier = linux_dmabuf_handle_modifier, > @@ -746,9 +739,6 @@ > > wl_output_add_listener(output->output, &wlr_output_listener, > output); > wl_list_insert(&ctx->output_list, &output->link); > - if (ctx->xdg_output_manager) { > - wlr_init_xdg_output(ctx, output); > - } > } > > if (!strcmp(interface, zwlr_screencopy_manager_v1_interface.name)) { > @@ -768,11 +758,6 @@ > 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, XDG_OUTPUT_MANAGER_VERSION); > - } > if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0) { > uint32_t version = ver; > if (LINUX_DMABUF_VERSION < ver) { > @@ -801,7 +786,7 @@ > logprint(DEBUG, "wlroots: output removed (%s)", output->name); > struct xdpw_screencast_instance *cast, *tmp; > wl_list_for_each_safe(cast, tmp, &ctx->screencast_instances, > link) { > - if (cast->target_output == output) { > + if (cast->target->output == output) { > // screencopy might be in process for this > instance > wlr_frame_free(cast); > // instance might be waiting for wakeup by the > frame limiter > @@ -844,18 +829,11 @@ > > logprint(DEBUG, "wayland: registry listeners run"); > > - // make sure our wlroots supports xdg_output_manager > - if (!ctx->xdg_output_manager) { > - logprint(ERROR, "Compositor doesn't support %s!", > - zxdg_output_manager_v1_interface.name); > - return -1; > - } > - > - wlr_init_xdg_outputs(ctx); > + if (ctx->linux_dmabuf_feedback) { > + wl_display_roundtrip(state->wl_display); > > - wl_display_roundtrip(state->wl_display); > - > - logprint(DEBUG, "wayland: xdg output listeners run"); > + logprint(DEBUG, "wayland: dmabuf_feedback listeners run"); > + } > > // make sure our wlroots supports shm protocol > if (!ctx->shm) { > @@ -887,7 +865,6 @@ > struct xdpw_wlr_output *output, *tmp_o; > wl_list_for_each_safe(output, tmp_o, &ctx->output_list, link) { > wl_list_remove(&output->link); > - zxdg_output_v1_destroy(output->xdg_output); > wl_output_destroy(output->output); > } > > @@ -902,9 +879,6 @@ > if (ctx->shm) { > wl_shm_destroy(ctx->shm); > } > - if (ctx->xdg_output_manager) { > - zxdg_output_manager_v1_destroy(ctx->xdg_output_manager); > - } > if (ctx->gbm) { > int fd = gbm_device_get_fd(ctx->gbm); > gbm_device_destroy(ctx->gbm); > diff -Nru xdg-desktop-portal-wlr-0.6.0/src/screenshot/screenshot.c > xdg-desktop-portal-wlr-0.7.0/src/screenshot/screenshot.c > --- xdg-desktop-portal-wlr-0.6.0/src/screenshot/screenshot.c 2022-06-09 > 11:25:25.000000000 +0200 > +++ xdg-desktop-portal-wlr-0.7.0/src/screenshot/screenshot.c 2023-04-15 > 10:32:26.000000000 +0200 > @@ -286,6 +286,9 @@ > SD_BUS_VTABLE_START(0), > SD_BUS_METHOD("Screenshot", "ossa{sv}", "ua{sv}", method_screenshot, > SD_BUS_VTABLE_UNPRIVILEGED), > SD_BUS_METHOD("PickColor", "ossa{sv}", "ua{sv}", method_pick_color, > SD_BUS_VTABLE_UNPRIVILEGED), > + SD_BUS_PROPERTY("version", "u", NULL, > + offsetof(struct xdpw_state, screenshot_version), > + SD_BUS_VTABLE_PROPERTY_CONST), > SD_BUS_VTABLE_END > }; > > @@ -293,5 +296,5 @@ > // TODO: cleanup > sd_bus_slot *slot = NULL; > return sd_bus_add_object_vtable(state->bus, &slot, object_path, > interface_name, > - screenshot_vtable, NULL); > + screenshot_vtable, state); > } > diff -Nru xdg-desktop-portal-wlr-0.6.0/wlr.portal > xdg-desktop-portal-wlr-0.7.0/wlr.portal > --- xdg-desktop-portal-wlr-0.6.0/wlr.portal 2022-06-09 11:25:25.000000000 > +0200 > +++ xdg-desktop-portal-wlr-0.7.0/wlr.portal 2023-04-15 10:32:26.000000000 > +0200 > @@ -1,4 +1,4 @@ > [portal] > DBusName=org.freedesktop.impl.portal.desktop.wlr > > Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.ScreenCast; > -UseIn=wlroots;sway;Wayfire;river;phosh; > +UseIn=wlroots;sway;Wayfire;river;phosh;Hyprland; -- Sebastian Ramacher

