diff --git a/include/dmabuf.h b/include/dmabuf.h index a44bcb2..160dfd7 100644 --- a/include/dmabuf.h +++ b/include/dmabuf.h @@ -25,6 +25,7 @@ struct wl_output; enum dmabuf_capture_status { DMABUF_CAPTURE_UNSPEC = 0, + DMABUF_CAPTURE_IN_PROGRESS, DMABUF_CAPTURE_CANCELLED, DMABUF_CAPTURE_FATAL, DMABUF_CAPTURE_DONE @@ -48,16 +49,17 @@ struct dmabuf_frame { }; struct dmabuf_capture { + struct zwlr_export_dmabuf_manager_v1* manager; struct zwlr_export_dmabuf_frame_v1* zwlr_frame; struct dmabuf_frame frame; + bool overlay_cursor; + struct wl_output* output; enum dmabuf_capture_status status; void (*on_done)(struct dmabuf_capture*); + void* userdata; }; -struct dmabuf_capture* -dmabuf_capture_start(struct zwlr_export_dmabuf_manager_v1* manager, - bool overlay_cursor, struct wl_output* output, - void (*on_done)(struct dmabuf_capture*)); +int dmabuf_capture_start(struct dmabuf_capture* self); void dmabuf_capture_stop(struct dmabuf_capture* self); diff --git a/src/dmabuf.c b/src/dmabuf.c index e3f8bfc..8b6c232 100644 --- a/src/dmabuf.c +++ b/src/dmabuf.c @@ -19,15 +19,16 @@ #include #include +#include "logging.h" #include "dmabuf.h" #include "wlr-export-dmabuf-unstable-v1.h" void dmabuf_capture_stop(struct dmabuf_capture* self) { - if (self->zwlr_frame) + if (self->zwlr_frame) { zwlr_export_dmabuf_frame_v1_destroy(self->zwlr_frame); - - free(self); + self->zwlr_frame = NULL; + } } static void dmabuf_frame_start(void* data, @@ -75,10 +76,10 @@ static void dmabuf_frame_ready(void* data, { struct dmabuf_capture* self = data; + dmabuf_capture_stop(self); + self->status = DMABUF_CAPTURE_DONE; self->on_done(self); - - dmabuf_capture_stop(self); } static void dmabuf_frame_cancel(void* data, @@ -89,22 +90,13 @@ static void dmabuf_frame_cancel(void* data, self->status = reason == ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_PERMANENT ? DMABUF_CAPTURE_FATAL : DMABUF_CAPTURE_DONE; - self->on_done(self); dmabuf_capture_stop(self); + self->on_done(self); } -struct dmabuf_capture* -dmabuf_capture_start(struct zwlr_export_dmabuf_manager_v1* manager, - bool overlay_cursor, struct wl_output* output, - void (*on_done)(struct dmabuf_capture*)) +int dmabuf_capture_start(struct dmabuf_capture* self) { - struct dmabuf_capture* self = calloc(1, sizeof(*self)); - if (!self) - return NULL; - - self->on_done = on_done; - static const struct zwlr_export_dmabuf_frame_v1_listener dmabuf_frame_listener = { .frame = dmabuf_frame_start, @@ -114,14 +106,16 @@ dmabuf_capture_start(struct zwlr_export_dmabuf_manager_v1* manager, }; self->zwlr_frame = - zwlr_export_dmabuf_manager_v1_capture_output(manager, - overlay_cursor, - output); + zwlr_export_dmabuf_manager_v1_capture_output(self->manager, + self->overlay_cursor, + self->output); if (!self->zwlr_frame) - return NULL; + return -1; + + self->status = DMABUF_CAPTURE_IN_PROGRESS; zwlr_export_dmabuf_frame_v1_add_listener(self->zwlr_frame, &dmabuf_frame_listener, self); - return self; + return 0; } diff --git a/src/main.c b/src/main.c index 3835eb0..4777dc9 100644 --- a/src/main.c +++ b/src/main.c @@ -53,13 +53,13 @@ struct wayvnc { struct wl_list outputs; struct renderer renderer; - struct zwlr_export_dmabuf_manager_v1* export_manager; const struct output* selected_output; - struct dmabuf_capture* capture; struct wl_shm* wl_shm; struct zwlr_screencopy_manager_v1* screencopy_manager; + struct dmabuf_capture dmabuf_backend; + uv_poll_t wayland_poller; uv_prepare_t flusher; uv_signal_t signal_handler; @@ -172,7 +172,7 @@ static void registry_add(void* data, struct wl_registry* registry, } if (strcmp(interface, zwlr_export_dmabuf_manager_v1_interface.name) == 0) { - self->export_manager = + self->dmabuf_backend.manager = wl_registry_bind(registry, id, &zwlr_export_dmabuf_manager_v1_interface, 1); @@ -205,7 +205,7 @@ static void registry_remove(void* data, struct wl_registry* registry, void wayvnc_destroy(struct wayvnc* self) { output_list_destroy(&self->outputs); - zwlr_export_dmabuf_manager_v1_destroy(self->export_manager); + zwlr_export_dmabuf_manager_v1_destroy(self->dmabuf_backend.manager); wl_display_disconnect(self->display); } @@ -231,12 +231,15 @@ static int init_wayland(struct wayvnc* self) wl_display_roundtrip(self->display); wl_display_dispatch(self->display); - if (!self->export_manager) { + if (!self->dmabuf_backend.manager) { log_error("Compositor does not support %s.\n", zwlr_export_dmabuf_manager_v1_interface.name); goto export_manager_failure; } + self->dmabuf_backend.on_done = on_capture_done; + self->dmabuf_backend.userdata = self; + return 0; export_manager_failure: @@ -252,6 +255,7 @@ int wayvnc_select_first_output(struct wayvnc* self) wl_list_for_each(out, &self->outputs, link) { self->selected_output = out; + self->dmabuf_backend.output = out->wl_output; return 0; } @@ -336,15 +340,7 @@ int init_nvnc(struct wayvnc* self, const char* addr, uint16_t port) int wayvnc_start_capture(struct wayvnc* self) { - self->capture = dmabuf_capture_start(self->export_manager, false, - self->selected_output->wl_output, - on_capture_done); - if (!self->capture) - return -1; - - self->capture->userdata = self; - - return 0; + return dmabuf_capture_start(&self->dmabuf_backend); } void on_damage_check_done(struct pixman_region16* damage, void* userdata) @@ -399,6 +395,8 @@ void on_capture_done(struct dmabuf_capture* capture) struct wayvnc* self = capture->userdata; switch (capture->status) { + case DMABUF_CAPTURE_IN_PROGRESS: + break; case DMABUF_CAPTURE_FATAL: log_error("Fatal error while capturing. Exiting...\n"); wayvnc_exit(); @@ -454,12 +452,9 @@ int main(int argc, char* argv[]) if (wayvnc_start_capture(&self) < 0) goto capture_failure; - self.capture->userdata = &self; - uv_run(uv_default_loop(), UV_RUN_DEFAULT); - if (self.capture) - dmabuf_capture_stop(self.capture); + dmabuf_capture_stop(&self.dmabuf_backend); if (self.current_fb) nvnc_fb_unref(self.current_fb); if (self.last_fb) nvnc_fb_unref(self.last_fb);