Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions src/stream-chooser/stream-chooser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,19 @@ static void registry_add_object(void *data, wl_registry *registry, uint32_t name
wl_registry_bind(registry, name,
&ext_foreign_toplevel_list_v1_interface,
version);
WayfireStreamChooserApp::getInstance().has_foreign_toplevel_list = true;
WayfireStreamChooserApp::getInstance().set_toplevel_list(list);
ext_foreign_toplevel_list_v1_add_listener(list,
&toplevel_list_v1_impl, NULL);
} else if (strcmp(interface, ext_image_copy_capture_manager_v1_interface.name) == 0)
{
auto manager = (ext_image_copy_capture_manager_v1*)wl_registry_bind(registry, name,
&ext_image_copy_capture_manager_v1_interface, version);
WayfireStreamChooserApp::getInstance().has_image_copy_capture = true;
WayfireStreamChooserApp::getInstance().set_copy_capture_manager(manager);
} else if (strcmp(interface, ext_foreign_toplevel_image_capture_source_manager_v1_interface.name) == 0)
{
auto toplevel_capture_manager =
(ext_foreign_toplevel_image_capture_source_manager_v1*)wl_registry_bind(registry, name,
&ext_foreign_toplevel_image_capture_source_manager_v1_interface, version);
WayfireStreamChooserApp::getInstance().has_image_capture_source = true;
WayfireStreamChooserApp::getInstance().set_toplevel_capture_manager(toplevel_capture_manager);
} else if (strcmp(interface, ext_output_image_capture_source_manager_v1_interface.name) == 0)
{
Expand Down Expand Up @@ -281,24 +278,45 @@ void WayfireStreamChooserApp::activate()
wl_display_roundtrip(display);
wl_registry_destroy(registry);

if (!has_image_copy_capture)
bool toplevel_capture = true;
bool output_capture = true;
if (!this->manager)
{
std::cerr << "Compositor has not advertised ext-image-copy-capture-v1" << std::endl;
toplevel_capture = false;
}

if (!has_foreign_toplevel_list)
if (!this->list)
{
std::cerr << "Compositor has not advertised ext-foreign-toplevel-list-v1" << std::endl;
toplevel_capture = false;
}

if (!has_image_capture_source)
if (!this->output_capture_manager)
{
std::cerr << "Compositor has not advertised ext-image-capture-source-v1" << std::endl;
output_capture = false;
}

window_label.set_sensitive(false);
window_label.set_tooltip_text("This compositor does not currently support sharing individual windows");
notebook.set_current_page(1);
if (!this->toplevel_capture_manager)
{
std::cerr << "Compositor has not advertised ext-foreign-toplevel-image-capture-source-v1" <<
std::endl;
toplevel_capture = false;
}

if (!toplevel_capture)
{
if (!output_capture)
{
std::cerr << "No capture protocols supported, nothing to do." << std::endl;
exit(EXIT_FAILURE);
}

window_label.set_sensitive(false);
window_label.set_tooltip_text("This compositor does not currently support sharing individual windows");
notebook.set_current_page(1);
}

/* Get output list */
auto gtkdisplay = Gdk::Display::get_default();
Expand Down Expand Up @@ -357,7 +375,6 @@ void WayfireStreamChooserApp::activate()
window.present();
}

static bool first_toplevel = true;
void WayfireStreamChooserApp::add_toplevel(ext_foreign_toplevel_handle_v1 *handle)
{
toplevels.emplace(handle, new WayfireChooserTopLevel(handle));
Expand All @@ -367,14 +384,6 @@ void WayfireStreamChooserApp::add_toplevel(ext_foreign_toplevel_handle_v1 *handl
auto child = window_list.get_child_at_index(0);
window_list.select_child(*child);
}

window_label.set_sensitive(true);
window_label.set_tooltip_text("");
if (first_toplevel)
{
first_toplevel = false;
notebook.set_current_page(0);
}
}

void WayfireStreamChooserApp::remove_toplevel(WayfireChooserTopLevel *toplevel)
Expand Down
3 changes: 0 additions & 3 deletions src/stream-chooser/stream-chooser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ class WayfireStreamChooserApp : public Gtk::Application
public:
Gtk::Notebook notebook;
Gtk::FlowBox window_list, screen_list;
bool has_foreign_toplevel_list = false;
bool has_image_copy_capture = false;
bool has_image_capture_source = false;
std::string drm_device_name;
int drm_fd = -1;
gbm_device *gbm_device_ptr = nullptr;
Expand Down
68 changes: 31 additions & 37 deletions src/stream-chooser/toplevelwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,24 @@ static void frame_handle_presentation_time(void*,
{}

static void frame_handle_ready(void *data,
struct ext_image_copy_capture_frame_v1*)
struct ext_image_copy_capture_frame_v1 *frame)
{
WayfireChooserTopLevel *toplevel = (WayfireChooserTopLevel*)data;

toplevel->buffer_ready();
toplevel->frame_in_flight = false;

ext_image_copy_capture_frame_v1_destroy(frame);
toplevel->frame = nullptr;
}

static void frame_handle_failed(void *data,
struct ext_image_copy_capture_frame_v1 *handle,
struct ext_image_copy_capture_frame_v1 *frame,
uint32_t reason)
{
WayfireChooserTopLevel *toplevel = (WayfireChooserTopLevel*)data;
std::cerr << "Failed to copy frame because reason: " << reason << std::endl;
ext_image_copy_capture_frame_v1_destroy(handle);

ext_image_copy_capture_frame_v1_destroy(frame);
toplevel->frame = nullptr;
toplevel->frame_in_flight = false;
}

static const struct ext_image_copy_capture_frame_v1_listener frame_listener = {
Expand All @@ -149,36 +151,31 @@ static const struct ext_image_copy_capture_frame_v1_listener frame_listener = {
.failed = frame_handle_failed,
};

static void dmabuf_created(void *data, struct zwp_linux_buffer_params_v1*,
struct wl_buffer *wl_buffer)
{
auto toplevel = (WayfireChooserTopLevel*)data;
toplevel->buffer->buffer = wl_buffer;
}

static void dmabuf_failed(void*, struct zwp_linux_buffer_params_v1*)
{
std::cerr << "Failed to create dmabuf" << std::endl;
}

static const struct zwp_linux_buffer_params_v1_listener params_listener = {
.created = dmabuf_created,
.failed = dmabuf_failed,
};

static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireChooserTopLevel *toplevel)
{
auto format = (toplevel->current_buffer_format == WL_SHM_FORMAT_XRGB8888) ?
GBM_FORMAT_XRGB8888 : GBM_FORMAT_ARGB8888;

auto buffer = toplevel->buffer;

if (buffer->gbm_fd > 0)
{
close(buffer->gbm_fd);
buffer->gbm_fd = -1;
}

if (buffer->bo)
{
gbm_bo_destroy(buffer->bo);
buffer->bo = nullptr;
}

if (buffer->buffer)
{
wl_buffer_destroy(buffer->buffer);
buffer->buffer = nullptr;
}

if (buffer->params)
{
zwp_linux_buffer_params_v1_destroy(buffer->params);
Expand Down Expand Up @@ -209,14 +206,14 @@ static void frame_handle_linux_dmabuf(uint32_t width, uint32_t height, WayfireCh
buffer->params = zwp_linux_dmabuf_v1_create_params(WayfireStreamChooserApp::getInstance().dmabuf);

uint64_t mod = gbm_bo_get_modifier(buffer->bo);
buffer->gbm_fd = gbm_bo_get_fd(buffer->bo);
zwp_linux_buffer_params_v1_add(buffer->params,
gbm_bo_get_fd(buffer->bo), 0,
buffer->gbm_fd, 0,
gbm_bo_get_offset(buffer->bo, 0),
gbm_bo_get_stride(buffer->bo),
mod >> 32, mod & 0xffffffff);

zwp_linux_buffer_params_v1_add_listener(buffer->params, &params_listener, toplevel);
zwp_linux_buffer_params_v1_create(buffer->params, w, h, format, 0);
buffer->buffer = zwp_linux_buffer_params_v1_create_immed(buffer->params, w, h, format, 0);
}

void WayfireChooserTopLevel::start_toplevel_source_ssession()
Expand Down Expand Up @@ -265,11 +262,6 @@ void WayfireChooserTopLevel::frame_request()
return;
}

if (frame_in_flight)
{
return;
}

if (frame)
{
ext_image_copy_capture_frame_v1_destroy(frame);
Expand All @@ -283,7 +275,6 @@ void WayfireChooserTopLevel::frame_request()
ext_image_copy_capture_frame_v1_attach_buffer(buffer->frame, buffer->buffer);
ext_image_copy_capture_frame_v1_damage_buffer(buffer->frame, 0, 0, buffer->width, buffer->height);
ext_image_copy_capture_frame_v1_capture(buffer->frame);
frame_in_flight = true;
}

void WayfireChooserTopLevel::buffer_ready()
Expand All @@ -309,10 +300,10 @@ void WayfireChooserTopLevel::buffer_ready()
std::shared_ptr<Glib::Bytes> bytes = 0;
size_t size = stride * buffer->height;
bytes = Glib::Bytes::create((unsigned char*)data, size);
gbm_bo_unmap(buffer->bo, map_data);

if (!bytes)
{
gbm_bo_unmap(buffer->bo, map_data);
return;
}

Expand All @@ -326,8 +317,6 @@ void WayfireChooserTopLevel::buffer_ready()
auto texture = builder->build();

screenshot.set_paintable(texture);

gbm_bo_unmap(buffer->bo, map_data);
}

void WayfireChooserTopLevel::stream()
Expand Down Expand Up @@ -486,16 +475,21 @@ WayfireChooserTopLevel::~WayfireChooserTopLevel()
ext_image_copy_capture_session_v1_destroy(recording_session);
}

if (buffer->buffer)
if (buffer->gbm_fd > 0)
{
wl_buffer_destroy(buffer->buffer);
close(buffer->gbm_fd);
}

if (buffer->bo)
{
gbm_bo_destroy(buffer->bo);
}

if (buffer->buffer)
{
wl_buffer_destroy(buffer->buffer);
}

if (buffer->params)
{
zwp_linux_buffer_params_v1_destroy(buffer->params);
Expand Down
2 changes: 1 addition & 1 deletion src/stream-chooser/toplevelwidget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct toplevel_buffer
int height = 0;
int stride = 0;
gbm_bo *bo = nullptr;
int gbm_fd = -1;
wl_buffer *buffer = nullptr;
zwp_linux_buffer_params_v1 *params = nullptr;
ext_image_copy_capture_frame_v1 *frame = NULL;
Expand Down Expand Up @@ -47,7 +48,6 @@ class WayfireChooserTopLevel : public Gtk::Box
ext_foreign_toplevel_handle_v1 *handle = nullptr;
std::shared_ptr<toplevel_buffer> buffer = nullptr;
ext_image_copy_capture_frame_v1 *frame = NULL;
bool frame_in_flight = false;
WayfireChooserTopLevel(ext_foreign_toplevel_handle_v1 *handle);
~WayfireChooserTopLevel();
void commit();
Expand Down
Loading