diff --git a/.build.yml b/.build.yml index 614d6e8..5e8bff3 100644 --- a/.build.yml +++ b/.build.yml @@ -5,6 +5,7 @@ packages: - meson - wayland - wayland-protocols + - pipewire sources: - https://github.com/emersion/xdg-desktop-portal-wlr tasks: diff --git a/.gitignore b/.gitignore index 6b8824a..54f6d86 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ dkms.conf # build folder build/ +build-*/ \ No newline at end of file diff --git a/include/pipewire_screencast.h b/include/pipewire_screencast.h index 4eb1711..3105f88 100644 --- a/include/pipewire_screencast.h +++ b/include/pipewire_screencast.h @@ -9,11 +9,11 @@ #include #include "wlr_screencast.h" #include "screencast_common.h" +#include "xdpw.h" #define BUFFERS 1 #define ALIGN 16 -void *pwr_start(void *data); -int pwr_dispatch(struct pw_loop *loop); +void *pwr_start(struct xdpw_state *state); #endif diff --git a/include/screencast.h b/include/screencast.h index 6a9aeda..5f6a8eb 100644 --- a/include/screencast.h +++ b/include/screencast.h @@ -8,7 +8,6 @@ #include #include #include -#include #include "pipewire_screencast.h" #include "screencast_common.h" diff --git a/include/wlr_screencast.h b/include/wlr_screencast.h index 4b45ce2..b5ab873 100644 --- a/include/wlr_screencast.h +++ b/include/wlr_screencast.h @@ -21,8 +21,10 @@ #define SC_MANAGER_VERSION 2 -void wlr_frame_free(struct screencast_context *ctx); -int wlr_screencopy_init(struct screencast_context *ctx); +struct xdpw_state; + +void wlr_frame_free(struct xdpw_state *state); +int wlr_screencopy_init(struct xdpw_state *state); void wlr_screencopy_uninit(struct screencast_context *ctx); struct wayland_output *wlr_output_find_by_name(struct wl_list *output_list, const char* name); @@ -30,6 +32,6 @@ struct wayland_output *wlr_output_find(struct screencast_context *ctx, struct wl_output *out, uint32_t id); struct wayland_output *wlr_output_first(struct wl_list *output_list); -void wlr_register_cb(struct screencast_context *ctx); +void wlr_register_cb(struct xdpw_state *state); #endif diff --git a/include/xdpw.h b/include/xdpw.h index e6b0c12..786d240 100644 --- a/include/xdpw.h +++ b/include/xdpw.h @@ -8,6 +8,15 @@ #include #endif #include "logger.h" +#include "screencast.h" + +struct xdpw_state { + sd_bus *bus; + struct wl_display *wl_display; + struct pw_loop *pw_loop; + + struct screencast_context screencast; +}; struct xdpw_request { sd_bus_slot *slot; @@ -23,8 +32,9 @@ enum { PORTAL_RESPONSE_ENDED = 2 }; -int init_screenshot(sd_bus *bus); -int init_screencast(sd_bus *bus, const char *output_name, const char *forced_pixelformat); +int init_screenshot(struct xdpw_state *state); +int init_screencast(struct xdpw_state *state, const char *output_name, + const char *forced_pixelformat); struct xdpw_request *request_create(sd_bus *bus, const char *object_path); void request_destroy(struct xdpw_request *req); diff --git a/meson.build b/meson.build index 55fc326..e46e472 100644 --- a/meson.build +++ b/meson.build @@ -22,7 +22,6 @@ add_project_arguments(cc.get_supported_arguments([ inc = include_directories('include') -threads = dependency('threads') rt = cc.find_library('rt') pipewire = dependency('libpipewire-0.2') spa = dependency('libspa-0.1') @@ -58,7 +57,6 @@ executable( logind, pipewire, spa, - threads, rt ], include_directories: [inc], diff --git a/src/core/main.c b/src/core/main.c index 117a24c..655a4c3 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1,8 +1,17 @@ +#include #include #include #include +#include +#include #include "xdpw.h" +enum event_loop_fd { + EVENT_LOOP_DBUS, + EVENT_LOOP_WAYLAND, + EVENT_LOOP_PIPEWIRE, +}; + static const char service_name[] = "org.freedesktop.impl.portal.desktop.wlr"; int xdpw_usage(FILE* stream, int rc) @@ -71,8 +80,27 @@ int main(int argc, char *argv[]) { goto error; } - init_screenshot(bus); - init_screencast(bus, output_name, forced_pixelformat); + struct wl_display *wl_display = wl_display_connect(NULL); + if (!wl_display) { + logprint(ERROR, "wayland: failed to connect to display"); + goto error; + } + + pw_init(NULL, NULL); + struct pw_loop *pw_loop = pw_loop_new(NULL); + if (!pw_loop) { + logprint(ERROR, "pipewire: failed to create loop"); + goto error; + } + + struct xdpw_state state = { + .bus = bus, + .wl_display = wl_display, + .pw_loop = pw_loop, + }; + + init_screenshot(&state); + init_screencast(&state, output_name, forced_pixelformat); ret = sd_bus_request_name(bus, service_name, 0); if (ret < 0) { @@ -80,21 +108,63 @@ int main(int argc, char *argv[]) { goto error; } + struct pollfd pollfds[] = { + [EVENT_LOOP_DBUS] = { + .fd = sd_bus_get_fd(state.bus), + .events = POLLIN, + }, + [EVENT_LOOP_WAYLAND] = { + .fd = wl_display_get_fd(state.wl_display), + .events = POLLIN, + }, + [EVENT_LOOP_PIPEWIRE] = { + .fd = pw_loop_get_fd(state.pw_loop), + .events = POLLIN, + }, + }; + while (1) { - ret = sd_bus_process(bus, NULL); + ret = poll(pollfds, sizeof(pollfds) / sizeof(pollfds[0]), -1); if (ret < 0) { - logprint(ERROR, "dbus: sd_bus_process failed: %s", strerror(-ret)); + logprint(ERROR, "poll failed: %s", strerror(errno)); goto error; - } else if (ret > 0) { - // We processed a request, try to process another one, right-away - continue; } - ret = sd_bus_wait(bus, (uint64_t)-1); - if (ret < 0) { - logprint(ERROR, "dbus: sd_bus_wait failed: %s", strerror(-ret)); - goto error; + if (pollfds[EVENT_LOOP_DBUS].revents & POLLIN) { + logprint(TRACE, "event-loop: got dbus event"); + do { + ret = sd_bus_process(state.bus, NULL); + } while (ret > 0); + if (ret < 0) { + logprint(ERROR, "sd_bus_process failed: %s", strerror(-ret)); + goto error; + } } + + if (pollfds[EVENT_LOOP_WAYLAND].revents & POLLIN) { + logprint(TRACE, "event-loop: got wayland event"); + ret = wl_display_dispatch(state.wl_display); + if (ret < 0) { + logprint(ERROR, "wl_display_dispatch failed: %s", strerror(errno)); + goto error; + } + } + + if (pollfds[EVENT_LOOP_PIPEWIRE].revents & POLLIN) { + logprint(TRACE, "event-loop: got pipewire event"); + ret = pw_loop_iterate(state.pw_loop, 0); + if (ret < 0) { + logprint(ERROR, "pw_loop_iterate failed: %s", spa_strerror(ret)); + goto error; + } + } + + do { + ret = wl_display_dispatch_pending(state.wl_display); + wl_display_flush(state.wl_display); + } while (ret > 0); + + sd_bus_flush(state.bus); } // TODO: cleanup @@ -103,5 +173,7 @@ int main(int argc, char *argv[]) { error: sd_bus_unref(bus); + pw_loop_leave(state.pw_loop); + pw_loop_destroy(state.pw_loop); return EXIT_FAILURE; } diff --git a/src/screencast/pipewire_screencast.c b/src/screencast/pipewire_screencast.c index 8259310..0e28909 100644 --- a/src/screencast/pipewire_screencast.c +++ b/src/screencast/pipewire_screencast.c @@ -25,17 +25,13 @@ static void writeFrameData(void *pwFramePointer, void *wlrFramePointer, } static void pwr_on_event(void *data, uint64_t expirations) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; struct pw_buffer *pw_buf; struct spa_buffer *spa_buf; struct spa_meta_header *h; struct spa_data *d; - if (!ctx->stream_state) { - wlr_frame_free(ctx); - return; - } - logprint(TRACE, "********************"); logprint(TRACE, "pipewire: event fired"); @@ -46,8 +42,10 @@ static void pwr_on_event(void *data, uint64_t expirations) { spa_buf = pw_buf->buffer; d = spa_buf->datas; - if ((d[0].data) == NULL) + if ((d[0].data) == NULL) { + logprint(TRACE, "pipewire: data pointer undefined"); return; + } if ((h = spa_buffer_find_meta(spa_buf, ctx->t->meta.Header))) { h->pts = -1; h->flags = 0; @@ -77,7 +75,8 @@ static void pwr_on_event(void *data, uint64_t expirations) { pw_stream_queue_buffer(ctx->stream, pw_buf); - wlr_frame_free(ctx); + wlr_frame_free(state); + } static void pwr_handle_stream_state_changed(void *data, @@ -91,9 +90,6 @@ static void pwr_handle_stream_state_changed(void *data, logprint(INFO, "pipewire: node id is %d", ctx->node_id); switch (state) { - case PW_STREAM_STATE_PAUSED: - ctx->stream_state = false; - break; case PW_STREAM_STATE_STREAMING: ctx->stream_state = true; break; @@ -141,18 +137,20 @@ static const struct pw_stream_events pwr_stream_events = { }; static void pwr_handle_state_changed(void *data, enum pw_remote_state old, - enum pw_remote_state state, + enum pw_remote_state pwr_remote_state, const char *error) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; struct pw_remote *remote = ctx->remote; - switch (state) { + switch (pwr_remote_state) { case PW_REMOTE_STATE_ERROR: logprint(INFO, "pipewire: remote state changed to \"%s\"", - pw_remote_state_as_string(state)); + pw_remote_state_as_string(pwr_remote_state)); logprint(ERROR, "pipewire: remote error: %s", error); - pw_loop_leave(ctx->loop); - pw_loop_destroy(ctx->loop); + pw_loop_leave(state->pw_loop); + pw_loop_destroy(state->pw_loop); + ctx->err = true; break; case PW_REMOTE_STATE_CONNECTED: { @@ -161,7 +159,7 @@ static void pwr_handle_state_changed(void *data, enum pw_remote_state old, struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); logprint(INFO, "pipewire: remote state changed to \"%s\"", - pw_remote_state_as_string(state)); + pw_remote_state_as_string(pwr_remote_state)); ctx->stream = pw_stream_new( remote, "wlr_screeencopy", @@ -194,7 +192,7 @@ static void pwr_handle_state_changed(void *data, enum pw_remote_state old, } default: logprint(INFO, "pipewire: remote state changed to \"%s\"", - pw_remote_state_as_string(state)); + pw_remote_state_as_string(pwr_remote_state)); break; } } @@ -204,18 +202,13 @@ static const struct pw_remote_events pwr_remote_events = { .state_changed = pwr_handle_state_changed, }; -void *pwr_start(void *data) { +void *pwr_start(struct xdpw_state *state) { - struct screencast_context *ctx = data; - - pw_init(NULL, NULL); - - /* create a loop */ - ctx->loop = pw_loop_new(NULL); - pw_loop_enter(ctx->loop); + struct screencast_context *ctx = &state->screencast; + pw_loop_enter(state->pw_loop); /* create a core, a remote, and initialize types */ - ctx->core = pw_core_new(ctx->loop, NULL); + ctx->core = pw_core_new(state->pw_loop, NULL); ctx->t = pw_core_get_type(ctx->core); ctx->remote = pw_remote_new(ctx->core, NULL, 0); @@ -223,22 +216,11 @@ void *pwr_start(void *data) { /* make an event to signal frame ready */ ctx->event = - pw_loop_add_event(ctx->loop, pwr_on_event, ctx); + pw_loop_add_event(state->pw_loop, pwr_on_event, state); pw_remote_add_listener(ctx->remote, &ctx->remote_listener, &pwr_remote_events, - ctx); + state); pw_remote_connect(ctx->remote); return NULL; } - -int pwr_dispatch(struct pw_loop *loop) { - - logprint(TRACE, "pipewire: dispatch"); - int res; - res = pw_loop_iterate(loop, 0); - if (res < 0) - logprint(ERROR, "pw_loop_iterate failed: %s", spa_strerror(res)); - return res; - -} diff --git a/src/screencast/screencast.c b/src/screencast/screencast.c index 18e7e8e..a5c0dfa 100644 --- a/src/screencast/screencast.c +++ b/src/screencast/screencast.c @@ -1,11 +1,11 @@ #include "screencast.h" -static struct screencast_context ctx; - static const char object_path[] = "/org/freedesktop/portal/desktop"; static const char interface_name[] = "org.freedesktop.impl.portal.ScreenCast"; -int setup_outputs(struct screencast_context *ctx) { +int setup_outputs(struct xdpw_state *state) { + + struct screencast_context *ctx = &state->screencast; struct wayland_output *output, *tmp_o; wl_list_for_each_reverse_safe(output, tmp_o, &ctx->output_list, link) { @@ -32,22 +32,26 @@ int setup_outputs(struct screencast_context *ctx) { ctx->framerate = out->framerate; ctx->with_cursor = true; - logprint(INFO, "wlroots: wl_display fd: %d", wl_display_get_fd(ctx->display)); - + logprint(INFO, "wlroots: output: %s", ctx->target_output->name); + logprint(INFO, "wlroots: wl_display fd: %d", wl_display_get_fd(state->wl_display)); + return 0; } void *start_screencast(void *data){ - struct screencast_context *ctx = data; + struct xdpw_state *state = data; - wlr_register_cb(ctx); + wlr_register_cb(state); + + // process at least one frame so that we know + // some of the metadata required for the pipewire + // remote state connected event + wl_display_dispatch(state->wl_display); + wl_display_roundtrip(state->wl_display); - pwr_start((void *) ctx); - - /* Run capture */ - while (wl_display_dispatch(ctx->display) != -1 && !ctx->err && !ctx->quit); + pwr_start(state); return NULL; @@ -140,13 +144,13 @@ static int method_screencast_create_session(sd_bus_message *msg, void *data, static int method_screencast_select_sources(sd_bus_message *msg, void *data, sd_bus_error *ret_error) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; int ret = 0; logprint(INFO, "dbus: select sources method invoked"); - setup_outputs(ctx); + setup_outputs(state); char *request_handle, *session_handle, *app_id; ret = sd_bus_message_read(msg, "oos", &request_handle, &session_handle, &app_id); @@ -161,7 +165,7 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data, sd_ logprint(INFO, "dbus: request_handle: %s", request_handle); logprint(INFO, "dbus: session_handle: %s", session_handle); logprint(INFO, "dbus: app_id: %s", app_id); - + char* key; int innerRet = 0; while((ret = sd_bus_message_enter_container(msg, 'e', "sv")) > 0) { @@ -217,14 +221,14 @@ static int method_screencast_select_sources(sd_bus_message *msg, void *data, sd_ static int method_screencast_start(sd_bus_message *msg, void *data, sd_bus_error *ret_error) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; int ret = 0; - + logprint(INFO, "dbus: start method invoked"); - pthread_t screencast_thread; - pthread_create(&screencast_thread, NULL, start_screencast, ctx); + start_screencast(state); char *request_handle, *session_handle, *app_id, *parent_window; ret = sd_bus_message_read(msg, "ooss", &request_handle, &session_handle, &app_id, &parent_window); @@ -240,7 +244,7 @@ static int method_screencast_start(sd_bus_message *msg, void *data, sd_bus_error logprint(INFO, "dbus: session_handle: %s", session_handle); logprint(INFO, "dbus: app_id: %s", app_id); logprint(INFO, "dbus: parent_window: %s", parent_window); - + char* key; int innerRet = 0; while((ret = sd_bus_message_enter_container(msg, 'e', "sv")) > 0) { @@ -271,7 +275,13 @@ static int method_screencast_start(sd_bus_message *msg, void *data, sd_bus_error return ret; } - while(ctx->node_id == 0); + while(ctx->node_id == 0){ + int ret = pw_loop_iterate(state->pw_loop, 0); + if (ret < 0) { + logprint(ERROR, "pipewire_loop_iterate failed: %s", + spa_strerror(ret)); + } + } ret = sd_bus_message_append(reply, "ua{sv}", PORTAL_RESPONSE_SUCCESS, 1, "streams", "a(ua{sv})", 1, @@ -288,9 +298,6 @@ static int method_screencast_start(sd_bus_message *msg, void *data, sd_bus_error } sd_bus_message_unref(reply); - while (wl_display_dispatch(ctx->display) != -1 && !ctx->err && !ctx->quit); - pthread_join(screencast_thread, NULL); - return 0; } @@ -302,25 +309,26 @@ static const sd_bus_vtable screencast_vtable[] = { SD_BUS_VTABLE_END }; -int init_screencast(sd_bus *bus, const char *output_name, const char *forced_pixelformat) { +int init_screencast(struct xdpw_state *state, const char *output_name, const char *forced_pixelformat) { // TODO: cleanup sd_bus_slot *slot = NULL; - ctx.forced_pixelformat = forced_pixelformat; - ctx.output_name = output_name; - ctx.simple_frame = (struct simple_frame){0}; - ctx.simple_frame.damage = &(struct damage){0}; + state->screencast = (struct screencast_context) { 0 }; + state->screencast.forced_pixelformat = forced_pixelformat; + state->screencast.output_name = output_name; + state->screencast.simple_frame = (struct simple_frame){0}; + state->screencast.simple_frame.damage = &(struct damage){0}; int err; - err = wlr_screencopy_init(&ctx); + err = wlr_screencopy_init(state); if (err) { goto end; } - return sd_bus_add_object_vtable(bus, &slot, object_path, interface_name, - screencast_vtable, &ctx); + return sd_bus_add_object_vtable(state->bus, &slot, object_path, interface_name, + screencast_vtable, state); end: - wlr_screencopy_uninit(&ctx); + wlr_screencopy_uninit(&state->screencast); return err; } diff --git a/src/screencast/wlr_screencast.c b/src/screencast/wlr_screencast.c index c7350e2..3300006 100644 --- a/src/screencast/wlr_screencast.c +++ b/src/screencast/wlr_screencast.c @@ -1,12 +1,17 @@ #include "wlr_screencast.h" +#include "xdpw.h" -void wlr_frame_free(struct screencast_context *ctx) { +void wlr_frame_free(struct xdpw_state *state) { - zwlr_screencopy_frame_v1_destroy(ctx->wlr_frame); - munmap(ctx->simple_frame.data, ctx->simple_frame.size); - wl_buffer_destroy(ctx->simple_frame.buffer); + zwlr_screencopy_frame_v1_destroy(state->screencast.wlr_frame); + munmap(state->screencast.simple_frame.data, state->screencast.simple_frame.size); + wl_buffer_destroy(state->screencast.simple_frame.buffer); logprint(TRACE, "wlroots: frame destroyed"); + if(!state->screencast.quit && !state->screencast.err){ + wlr_register_cb(state); + } + } static struct wl_buffer *create_shm_buffer(struct screencast_context *ctx, @@ -24,9 +29,8 @@ static struct wl_buffer *create_shm_buffer(struct screencast_context *ctx, shm_unlink(shm_name); int ret; - while ((ret = ftruncate(fd, size)) == EINTR) { - // No-op - } + while ((ret = ftruncate(fd, size)) == EINTR); + if (ret < 0) { close(fd); logprint(ERROR, "wlroots: ftruncate failed"); @@ -53,7 +57,8 @@ static struct wl_buffer *create_shm_buffer(struct screencast_context *ctx, 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 screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; logprint(TRACE, "wlroots: buffer event handler"); ctx->wlr_frame = frame; @@ -70,11 +75,13 @@ static void wlr_frame_buffer(void *data, struct zwlr_screencopy_frame_v1 *frame, } zwlr_screencopy_frame_v1_copy_with_damage(frame, ctx->simple_frame.buffer); + logprint(TRACE, "wlroots: frame copied"); } static void wlr_frame_flags(void *data, struct zwlr_screencopy_frame_v1 *frame, uint32_t flags) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; logprint(TRACE, "wlroots: flags event handler"); ctx->simple_frame.y_invert = flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT; @@ -84,37 +91,41 @@ static void wlr_frame_flags(void *data, struct zwlr_screencopy_frame_v1 *frame, static void wlr_frame_ready(void *data, struct zwlr_screencopy_frame_v1 *frame, uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; logprint(TRACE, "wlroots: ready event handler"); ctx->simple_frame.tv_sec = ((((uint64_t)tv_sec_hi) << 32) | tv_sec_lo); ctx->simple_frame.tv_nsec = tv_nsec; - if (!ctx->quit && !ctx->err) { - pw_loop_signal_event(ctx->loop, ctx->event); - - if(ctx->loop) - if(pwr_dispatch(ctx->loop) < 0) ctx->err = true; - - wlr_register_cb(ctx); + if (!ctx->quit && !ctx->err && ctx->stream_state) { + pw_loop_signal_event(state->pw_loop, ctx->event); + return ; } + + wlr_frame_free(state); + } static void wlr_frame_failed(void *data, struct zwlr_screencopy_frame_v1 *frame) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; logprint(TRACE, "wlroots: failed event handler"); - - wlr_frame_free(ctx); ctx->err = true; + + wlr_frame_free(state); } static void wlr_frame_damage(void *data, struct zwlr_screencopy_frame_v1 *frame, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { - struct screencast_context *ctx = data; + struct xdpw_state *state = data; + struct screencast_context *ctx = &state->screencast; + + logprint(TRACE, "wlroots: damage event handler"); ctx->simple_frame.damage->x = x; ctx->simple_frame.damage->y = y; @@ -130,12 +141,15 @@ static const struct zwlr_screencopy_frame_v1_listener wlr_frame_listener = { .damage = wlr_frame_damage, }; -void wlr_register_cb(struct screencast_context *ctx) { +void wlr_register_cb(struct xdpw_state *state) { + + struct screencast_context *ctx = &state->screencast; + ctx->frame_callback = zwlr_screencopy_manager_v1_capture_output( ctx->screencopy_manager, ctx->with_cursor, ctx->target_output->output); zwlr_screencopy_frame_v1_add_listener(ctx->frame_callback, - &wlr_frame_listener, ctx); + &wlr_frame_listener, state); logprint(TRACE, "wlroots: callbacks registered"); } @@ -285,30 +299,29 @@ static const struct wl_registry_listener wlr_registry_listener = { .global_remove = wlr_registry_handle_remove, }; -int wlr_screencopy_init(struct screencast_context *ctx) { - // connect to wayland display WAYLAND_DISPLAY or 'wayland-0' if not set - ctx->display = wl_display_connect(NULL); - if (!ctx->display) { - logprint(ERROR, "Failed to connect to display!"); - return -1; - } +int wlr_screencopy_init(struct xdpw_state *state) { + struct screencast_context *ctx = &state->screencast; // retrieve list of outputs wl_list_init(&ctx->output_list); // retrieve registry - ctx->registry = wl_display_get_registry(ctx->display); + ctx->registry = wl_display_get_registry(state->wl_display); wl_registry_add_listener(ctx->registry, &wlr_registry_listener, ctx); - wl_display_dispatch(ctx->display); - wl_display_roundtrip(ctx->display); + wl_display_dispatch(state->wl_display); + wl_display_roundtrip(state->wl_display); + + logprint(TRACE, "wayland: registry listeners run"); wlr_init_xdg_outputs(ctx); - wl_display_dispatch(ctx->display); - wl_display_roundtrip(ctx->display); + wl_display_dispatch(state->wl_display); + wl_display_roundtrip(state->wl_display); - // make sure our wlroots supports screencopy protocol + logprint(TRACE, "wayland: xdg output listeners run"); + + // make sure our wlroots supports shm protocol if (!ctx->shm) { logprint(ERROR, "Compositor doesn't support %s!", "wl_shm"); return -1; diff --git a/src/screenshot/screenshot.c b/src/screenshot/screenshot.c index 22bfdcc..b504e21 100644 --- a/src/screenshot/screenshot.c +++ b/src/screenshot/screenshot.c @@ -90,9 +90,9 @@ static const sd_bus_vtable screenshot_vtable[] = { SD_BUS_VTABLE_END }; -int init_screenshot(sd_bus *bus) { +int init_screenshot(struct xdpw_state *state) { // TODO: cleanup sd_bus_slot *slot = NULL; - return sd_bus_add_object_vtable(bus, &slot, object_path, interface_name, + return sd_bus_add_object_vtable(state->bus, &slot, object_path, interface_name, screenshot_vtable, NULL); }