Skip to content

Commit

Permalink
Initial session support WIP, pipewire stuck at PAUSED
Browse files Browse the repository at this point in the history
  • Loading branch information
danshick committed Apr 8, 2020
1 parent ccc8a31 commit 1c7e97d
Show file tree
Hide file tree
Showing 15 changed files with 415 additions and 272 deletions.
4 changes: 0 additions & 4 deletions include/logger.h
@@ -1,11 +1,7 @@
#ifndef LOGGER_H
#define LOGGER_H

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

enum LOGLEVEL { QUIET, ERROR, WARN, INFO, DEBUG, TRACE };

Expand Down
12 changes: 2 additions & 10 deletions include/pipewire_screencast.h
@@ -1,20 +1,12 @@
#ifndef PIPEWIRE_SCREENCAST_H
#define PIPEWIRE_SCREENCAST_H

#include <stdio.h>
#include <pipewire/pipewire.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 "wlr_screencast.h"
#include "screencast_common.h"
#include "xdpw.h"

#define BUFFERS 1
#define ALIGN 16

void *pwr_start(struct xdpw_state *state);
void *xdpw_pwr_start(struct xdpw_screencast_instance *cast);
void xdpw_pwr_connect(struct xdpw_state *state);

#endif
13 changes: 2 additions & 11 deletions include/screencast.h
@@ -1,17 +1,8 @@
#ifndef SCREENCAST_H
#define SCREENCAST_H

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/mman.h>

#include "pipewire_screencast.h"
#include "screencast_common.h"
#include "wlr_screencast.h"
#include "xdpw.h"

void xdpw_screencast_instance_destroy(struct xdpw_screencast_instance *cast);

#endif
82 changes: 51 additions & 31 deletions include/screencast_common.h
@@ -1,21 +1,29 @@
#ifndef SCREENCAST_COMMON_H
#define SCREENCAST_COMMON_H

#include <string.h>
#include <pipewire/pipewire.h>
#include <spa/param/video/format-utils.h>
#include <libdrm/drm_fourcc.h>
#include <wayland-client-protocol.h>
#include "logger.h"

struct damage {
enum cursor_modes {
HIDDEN = 1,
EMBEDDED = 2,
METADATA = 4,
};

enum source_types {
MONITOR = 1,
WINDOW = 2,
};

struct xdpw_frame_damage {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
};

struct simple_frame {
struct xdpw_frame {
uint32_t width;
uint32_t height;
uint32_t size;
Expand All @@ -24,22 +32,19 @@ struct simple_frame {
uint64_t tv_sec;
uint32_t tv_nsec;
enum wl_shm_format format;
struct damage *damage;
struct xdpw_frame_damage damage;
struct wl_buffer *buffer;
void *data;
};

struct screencast_context {
struct xdpw_screencast_context {

// xdpw
struct xdpw_state *state;

// pipewire
struct pw_context *pwr_context;
struct pw_core *core;
struct spa_source *event;
struct pw_stream *stream;
struct spa_hook stream_listener;
struct spa_video_info_raw pwr_format;
uint32_t seq;
uint32_t node_id;
bool stream_state;

// wlroots
struct wl_display *display;
Expand All @@ -49,28 +54,43 @@ struct screencast_context {
struct zxdg_output_manager_v1* xdg_output_manager;
struct wl_shm *shm;

// main frame callback
struct zwlr_screencopy_frame_v1 *frame_callback;

// target output
struct wayland_output *target_output;
uint32_t framerate;
bool with_cursor;

// frame
struct zwlr_screencopy_frame_v1 *wlr_frame;
struct simple_frame simple_frame;

// cli options
const char *output_name;
const char *forced_pixelformat;

// if something happens during capture
int err;
bool quit;
// sessions
struct wl_list screencast_instances;
};

struct xdpw_screencast_instance {
// list
struct wl_list link;

// xdpw
uint32_t refcount;
struct xdpw_screencast_context *ctx;

// pipewire
struct spa_source *event; //stream specific
struct pw_stream *stream; //stream specific
struct spa_hook stream_listener; //stream specific
struct spa_video_info_raw pwr_format; //stream specific
uint32_t seq; //stream specific
uint32_t node_id; //stream specific
bool stream_state; //stream specific

// wlroots
struct zwlr_screencopy_frame_v1 *frame_callback; //stream specific
struct xdpw_wlr_output *target_output; //stream specific
uint32_t framerate; //stream specific
struct zwlr_screencopy_frame_v1 *wlr_frame; //stream specific
struct xdpw_frame simple_frame; //stream specific
bool with_cursor; //stream specific
int err; //stream specific
bool quit; //stream specific
};

struct wayland_output {
struct xdpw_wlr_output {
struct wl_list link;
uint32_t id;
struct wl_output *output;
Expand All @@ -83,6 +103,6 @@ struct wayland_output {
float framerate;
};

uint32_t pipewire_from_wl_shm(void *data);
uint32_t xdpw_format_pw_from_wl_shm(void *data);

#endif /* SCREENCAST_COMMON_H */
29 changes: 7 additions & 22 deletions include/wlr_screencast.h
@@ -1,37 +1,22 @@
#ifndef WLR_SCREENCAST_H
#define WLR_SCREENCAST_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>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <wayland-client-protocol.h>

#include "pipewire_screencast.h"
#include "screencast_common.h"

#define SC_MANAGER_VERSION 2

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);
int xdpw_wlr_screencopy_init(struct xdpw_state *state);
void xdpw_wlr_screencopy_finish(struct xdpw_screencast_context *ctx);

struct wayland_output *wlr_output_find_by_name(struct wl_list *output_list,
struct xdpw_wlr_output *xdpw_wlr_output_find_by_name(struct wl_list *output_list,
const char *name);
struct wayland_output *wlr_output_find(struct screencast_context *ctx,
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 wayland_output *wlr_output_first(struct wl_list *output_list);

void wlr_register_cb(struct xdpw_state *state);
void xdpw_wlr_frame_free(struct xdpw_screencast_instance *cast);
void xdpw_wlr_register_cb(struct xdpw_screencast_instance *cast);

#endif
25 changes: 15 additions & 10 deletions include/xdpw.h
Expand Up @@ -7,23 +7,28 @@
#elif HAVE_ELOGIND
#include <elogind/sd-bus.h>
#endif
#include "logger.h"
#include "screencast.h"

#include "screencast_common.h"

struct xdpw_state {
struct wl_list xdpw_sessions;
sd_bus *bus;
struct wl_display *wl_display;
struct pw_loop *pw_loop;

struct screencast_context screencast;
struct xdpw_screencast_context screencast;
enum source_types screencast_source_types;
enum cursor_modes screencast_cursor_modes;
};

struct xdpw_request {
sd_bus_slot *slot;
};

struct xdpw_session {
struct wl_list link;
sd_bus_slot *slot;
const char *session_handle;
struct xdpw_screencast_instance *screencast_instance;
};

enum {
Expand All @@ -32,14 +37,14 @@ enum {
PORTAL_RESPONSE_ENDED = 2
};

int init_screenshot(struct xdpw_state *state);
int init_screencast(struct xdpw_state *state, const char *output_name,
int xdpw_screenshot_init(struct xdpw_state *state);
int xdpw_screencast_init(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);
struct xdpw_request *xdpw_request_create(sd_bus *bus, const char *object_path);
void xdpw_request_destroy(struct xdpw_request *req);

struct xdpw_session *session_create(sd_bus *bus, const char *object_path);
void session_destroy(struct xdpw_session *req);
struct xdpw_session *xdpw_session_create(struct xdpw_state *state, sd_bus *bus, const char *object_path);
void xdpw_session_destroy(struct xdpw_session *req);

#endif
5 changes: 5 additions & 0 deletions src/core/logger.c
@@ -1,5 +1,10 @@
#include "logger.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

static int NUM_LEVELS = 6;

static const char *loglevels[] = {
Expand Down
12 changes: 10 additions & 2 deletions src/core/main.c
Expand Up @@ -6,6 +6,8 @@
#include <pipewire/pipewire.h>
#include <spa/utils/result.h>
#include "xdpw.h"
#include "screencast_common.h"
#include "logger.h"

enum event_loop_fd {
EVENT_LOOP_DBUS,
Expand Down Expand Up @@ -83,6 +85,7 @@ int main(int argc, char *argv[]) {
logprint(ERROR, "wayland: failed to connect to display");
goto error;
}
logprint(INFO, "wlroots: wl_display fd: %d", wl_display_get_fd(wl_display));

pw_init(NULL, NULL);
struct pw_loop *pw_loop = pw_loop_new(NULL);
Expand All @@ -92,13 +95,18 @@ int main(int argc, char *argv[]) {
}

struct xdpw_state state = {
.xdpw_sessions = (struct wl_list) { 0 },
.bus = bus,
.wl_display = wl_display,
.pw_loop = pw_loop,
.screencast_source_types = MONITOR,
.screencast_cursor_modes = HIDDEN | EMBEDDED,
};

init_screenshot(&state);
init_screencast(&state, output_name, forced_pixelformat);
wl_list_init(&state.xdpw_sessions);

xdpw_screenshot_init(&state);
xdpw_screencast_init(&state, output_name, forced_pixelformat);

ret = sd_bus_request_name(bus, service_name, 0);
if (ret < 0) {
Expand Down
11 changes: 6 additions & 5 deletions src/core/request.c
Expand Up @@ -3,13 +3,14 @@
#include <stdlib.h>
#include <string.h>
#include "xdpw.h"
#include "logger.h"

static const char interface_name[] = "org.freedesktop.impl.portal.Request";

static int method_close(sd_bus_message *msg, void *data,
sd_bus_error *ret_error) {
int ret = 0;

int ret = 0;
// struct xdpw_request *req = data;
// TODO
logprint(INFO, "dbus: request closed");
Expand All @@ -25,7 +26,7 @@ static int method_close(sd_bus_message *msg, void *data,
return ret;
}

sd_bus_message_unref(reply);
sd_bus_message_unref(reply);

return 0;
}
Expand All @@ -36,7 +37,7 @@ static const sd_bus_vtable request_vtable[] = {
SD_BUS_VTABLE_END
};

struct xdpw_request *request_create(sd_bus *bus, const char *object_path) {
struct xdpw_request *xdpw_request_create(sd_bus *bus, const char *object_path) {
struct xdpw_request *req = calloc(1, sizeof(struct xdpw_request));

if (sd_bus_add_object_vtable(bus, &req->slot, object_path, interface_name,
Expand All @@ -50,7 +51,7 @@ struct xdpw_request *request_create(sd_bus *bus, const char *object_path) {
return req;
}

void request_destroy(struct xdpw_request *req) {
void xdpw_request_destroy(struct xdpw_request *req) {
if (req == NULL) {
return;
}
Expand Down

0 comments on commit 1c7e97d

Please sign in to comment.