From d953d0bb363799211d546035e825d248b9b3c2ed Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 16 Apr 2023 22:05:09 +0200 Subject: [PATCH] Use XDG_RUNTIME_DIR (and flatpak specific dir) and /dev/dri/renderD128 instead of /dev/dri/card0 (fixes capture on some systems) --- kms/client/kms_client.c | 47 ++++++++++++++++++++++++++++------------- kms/client/kms_client.h | 3 ++- src/capture/kms_vaapi.c | 4 ++-- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/kms/client/kms_client.c b/kms/client/kms_client.c index 1ab9a69..9c17f80 100644 --- a/kms/client/kms_client.c +++ b/kms/client/kms_client.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -13,10 +12,6 @@ #include #include -static bool is_inside_flatpak(void) { - return getenv("FLATPAK_ID") != NULL; -} - static bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size) { int fd = open("/dev/urandom", O_RDONLY); if(fd == -1) { @@ -84,6 +79,36 @@ static int recv_msg_from_server(int server_fd, gsr_kms_response *response) { return res; } +static bool create_socket_path(char *output_path, size_t output_path_size) { + // Can't use /tmp because of flatpak, but fallback to it if we fail to get a valid runtime dir + char runtime_dir_path[PATH_MAX]; + const char *runtime_dir = getenv("XDG_RUNTIME_DIR"); + const char *flatpak_id = getenv("FLATPAK_ID"); + if(runtime_dir) { + if(flatpak_id) + snprintf(runtime_dir_path, sizeof(runtime_dir_path), "%s/app/%s", runtime_dir, flatpak_id); + else + strcpy(runtime_dir_path, runtime_dir); + } else { + const uint32_t uid = getuid(); + if(flatpak_id) + snprintf(runtime_dir_path, sizeof(runtime_dir_path), "/run/user/%u/app/%s", uid, flatpak_id); + else + snprintf(runtime_dir_path, sizeof(runtime_dir_path), "/run/user/%u", uid); + } + + if(access(runtime_dir_path, F_OK) != 0) + strcpy(runtime_dir_path, "/tmp"); + + char random_characters[11]; + random_characters[10] = '\0'; + if(!generate_random_characters(random_characters, 10, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62)) + return false; + + snprintf(output_path, output_path_size, "%s/gsr-kms-socket-%s", runtime_dir_path, random_characters); + return true; +} + int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) { self->kms_server_pid = -1; self->socket_fd = -1; @@ -92,18 +117,10 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) { struct sockaddr_un local_addr = {0}; struct sockaddr_un remote_addr = {0}; - // Can't use /tmp because of flatpak - const char *home_path = getenv("HOME"); - if(!home_path) - home_path = "/tmp"; - - char random_characters[11]; - random_characters[10] = '\0'; - if(!generate_random_characters(random_characters, 10, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62)) { + if(!create_socket_path(self->socket_path, sizeof(self->socket_path))) { fprintf(stderr, "gsr error: gsr_kms_client_init: failed to create path to kms socket\n"); return -1; } - snprintf(self->socket_path, sizeof(self->socket_path), "%s/.gsr-kms-socket-%s", home_path, random_characters); // This doesn't work on nixos, but we dont want to use $PATH because we want to make this as safe as possible by running pkexec // on a path that only root can modify. If we use "gsr-kms-server" instead then $PATH can be modified in ~/.bashrc for example @@ -111,7 +128,7 @@ int gsr_kms_client_init(gsr_kms_client *self, const char *card_path) { // If there is a safe way to do this on nixos, then please tell me; or use gpu-screen-recorder flatpak instead. const char *server_filepath = "/usr/bin/gsr-kms-server"; bool has_perm = 0; - bool inside_flatpak = is_inside_flatpak(); + const bool inside_flatpak = getenv("FLATPAK_ID") != NULL; if(!inside_flatpak) { if(access("/usr/bin/gsr-kms-server", F_OK) != 0) { fprintf(stderr, "gsr error: gsr_kms_client_init: /usr/bin/gsr-kms-server not found, please install gpu-screen-recorder first\n"); diff --git a/kms/client/kms_client.h b/kms/client/kms_client.h index dceef20..254637b 100644 --- a/kms/client/kms_client.h +++ b/kms/client/kms_client.h @@ -3,12 +3,13 @@ #include "../kms_shared.h" #include +#include typedef struct { pid_t kms_server_pid; int socket_fd; int client_fd; - char socket_path[255]; + char socket_path[PATH_MAX]; } gsr_kms_client; /* |card_path| should be a path to card, for example /dev/dri/card0 */ diff --git a/src/capture/kms_vaapi.c b/src/capture/kms_vaapi.c index 7bc2a0b..74e50f1 100644 --- a/src/capture/kms_vaapi.c +++ b/src/capture/kms_vaapi.c @@ -122,8 +122,8 @@ static void monitor_callback(const XRROutputInfo *output_info, const XRRCrtcInfo static int gsr_capture_kms_vaapi_start(gsr_capture *cap, AVCodecContext *video_codec_context) { gsr_capture_kms_vaapi *cap_kms = cap->priv; - // TODO: Allow specifying another card, and in other places (TODO: Use /dev/dri/renderD128?) - if(gsr_kms_client_init(&cap_kms->kms_client, "/dev/dri/card0") != 0) { + // TODO: Allow specifying another card, and in other places + if(gsr_kms_client_init(&cap_kms->kms_client, "/dev/dri/renderD128") != 0) { return -1; }