diff options
Diffstat (limited to 'src/GsrInfo.cpp')
-rw-r--r-- | src/GsrInfo.cpp | 167 |
1 files changed, 84 insertions, 83 deletions
diff --git a/src/GsrInfo.cpp b/src/GsrInfo.cpp index 276870b..c35ccfb 100644 --- a/src/GsrInfo.cpp +++ b/src/GsrInfo.cpp @@ -1,5 +1,7 @@ #include "../include/GsrInfo.hpp" #include "../include/Utils.hpp" +#include "../include/Process.hpp" + #include <optional> #include <string.h> @@ -38,6 +40,8 @@ namespace gsr { gsr_info->gpu_info.vendor = GpuVendor::INTEL; else if(key_value->value == "nvidia") gsr_info->gpu_info.vendor = GpuVendor::NVIDIA; + } else if(key_value->key == "card_path") { + gsr_info->gpu_info.card_path = key_value->value; } } @@ -64,38 +68,6 @@ namespace gsr { gsr_info->supported_video_codecs.vp9 = true; } - static std::optional<GsrMonitor> capture_option_line_to_monitor(std::string_view line) { - std::optional<GsrMonitor> monitor; - const std::optional<KeyValue> key_value = parse_key_value(line); - if(!key_value) - return monitor; - - char value_buffer[256]; - snprintf(value_buffer, sizeof(value_buffer), "%.*s", (int)key_value->value.size(), key_value->value.data()); - - monitor = GsrMonitor{std::string(key_value->key), mgl::vec2i{0, 0}}; - if(sscanf(value_buffer, "%dx%d", &monitor->size.x, &monitor->size.y) != 2) - monitor->size = {0, 0}; - - return monitor; - } - - static void parse_capture_options_line(GsrInfo *gsr_info, std::string_view line) { - if(line == "window") - gsr_info->supported_capture_options.window = true; - else if(line == "focused") - gsr_info->supported_capture_options.focused = true; - else if(line == "screen") - gsr_info->supported_capture_options.screen = true; - else if(line == "portal") - gsr_info->supported_capture_options.portal = true; - else { - std::optional<GsrMonitor> monitor = capture_option_line_to_monitor(line); - if(monitor) - gsr_info->supported_capture_options.monitors.push_back(std::move(monitor.value())); - } - } - enum class GsrInfoSection { UNKNOWN, SYSTEM_INFO, @@ -112,23 +84,19 @@ namespace gsr { GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info) { *gsr_info = GsrInfo{}; - FILE *f = popen("gpu-screen-recorder --info", "r"); - if(!f) { - fprintf(stderr, "error: 'gpu-screen-recorder --info' failed\n"); - return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND; - } - - char output[8192]; - ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f); - if(bytes_read < 0 || ferror(f)) { - fprintf(stderr, "error: failed to read 'gpu-screen-recorder --info' output\n"); - pclose(f); - return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND; + std::string stdout_str; + const char *args[] = { "gpu-screen-recorder", "--info", nullptr }; + const int exit_status = exec_program_get_stdout(args, stdout_str); + switch(exit_status) { + case 0: break; + case 14: return GsrInfoExitStatus::BROKEN_DRIVERS; + case 22: return GsrInfoExitStatus::OPENGL_FAILED; + case 23: return GsrInfoExitStatus::NO_DRM_CARD; + default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND; } - output[bytes_read] = '\0'; GsrInfoSection section = GsrInfoSection::UNKNOWN; - string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) { + string_split_char(stdout_str, '\n', [&](std::string_view line) { if(starts_with(line, "section=")) { const std::string_view section_name = line.substr(8); if(section_name == "system_info") @@ -161,7 +129,7 @@ namespace gsr { break; } case GsrInfoSection::CAPTURE_OPTIONS: { - parse_capture_options_line(gsr_info, line); + // Intentionally ignore, get capture options with get_supported_capture_options instead break; } } @@ -169,18 +137,7 @@ namespace gsr { return true; }); - int status = pclose(f); - if(WIFEXITED(status)) { - switch(WEXITSTATUS(status)) { - case 0: return GsrInfoExitStatus::OK; - case 14: return GsrInfoExitStatus::BROKEN_DRIVERS; - case 22: return GsrInfoExitStatus::OPENGL_FAILED; - case 23: return GsrInfoExitStatus::NO_DRM_CARD; - default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND; - } - } - - return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND; + return GsrInfoExitStatus::OK; } static std::optional<AudioDevice> parse_audio_device_line(std::string_view line) { @@ -196,22 +153,14 @@ namespace gsr { std::vector<AudioDevice> get_audio_devices() { std::vector<AudioDevice> audio_devices; - FILE *f = popen("gpu-screen-recorder --list-audio-devices", "r"); - if(!f) { + std::string stdout_str; + const char *args[] = { "gpu-screen-recorder", "--list-audio-devices", nullptr }; + if(exec_program_get_stdout(args, stdout_str) != 0) { fprintf(stderr, "error: 'gpu-screen-recorder --list-audio-devices' failed\n"); return audio_devices; } - char output[16384]; - ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f); - if(bytes_read < 0 || ferror(f)) { - fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-audio-devices' output\n"); - pclose(f); - return audio_devices; - } - output[bytes_read] = '\0'; - - string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) { + string_split_char(stdout_str, '\n', [&](std::string_view line) { std::optional<AudioDevice> audio_device = parse_audio_device_line(line); if(audio_device) audio_devices.push_back(std::move(audio_device.value())); @@ -224,26 +173,78 @@ namespace gsr { std::vector<std::string> get_application_audio() { std::vector<std::string> application_audio; - FILE *f = popen("gpu-screen-recorder --list-application-audio", "r"); - if(!f) { + std::string stdout_str; + const char *args[] = { "gpu-screen-recorder", "--list-application-audio", nullptr }; + if(exec_program_get_stdout(args, stdout_str) != 0) { fprintf(stderr, "error: 'gpu-screen-recorder --list-application-audio' failed\n"); return application_audio; } - char output[16384]; - ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f); - if(bytes_read < 0 || ferror(f)) { - fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-application-audio' output\n"); - pclose(f); - return application_audio; - } - output[bytes_read] = '\0'; - - string_split_char({output, (size_t)bytes_read}, '\n', [&](std::string_view line) { + string_split_char(stdout_str, '\n', [&](std::string_view line) { application_audio.emplace_back(line); return true; }); return application_audio; } + + static std::optional<GsrMonitor> capture_option_line_to_monitor(std::string_view line) { + std::optional<GsrMonitor> monitor; + const std::optional<KeyValue> key_value = parse_key_value(line); + if(!key_value) + return monitor; + + char value_buffer[256]; + snprintf(value_buffer, sizeof(value_buffer), "%.*s", (int)key_value->value.size(), key_value->value.data()); + + monitor = GsrMonitor{std::string(key_value->key), mgl::vec2i{0, 0}}; + if(sscanf(value_buffer, "%dx%d", &monitor->size.x, &monitor->size.y) != 2) + monitor->size = {0, 0}; + + return monitor; + } + + static void parse_capture_options_line(SupportedCaptureOptions &capture_options, std::string_view line) { + if(line == "window") + capture_options.window = true; + else if(line == "focused") + capture_options.focused = true; + else if(line == "screen") + capture_options.screen = true; + else if(line == "portal") + capture_options.portal = true; + else { + std::optional<GsrMonitor> monitor = capture_option_line_to_monitor(line); + if(monitor) + capture_options.monitors.push_back(std::move(monitor.value())); + } + } + + static const char* gpu_vendor_to_string(GpuVendor vendor) { + switch(vendor) { + case GpuVendor::UNKNOWN: return "unknown"; + case GpuVendor::AMD: return "amd"; + case GpuVendor::INTEL: return "intel"; + case GpuVendor::NVIDIA: return "nvidia"; + } + return "unknown"; + } + + SupportedCaptureOptions get_supported_capture_options(const GsrInfo &gsr_info) { + SupportedCaptureOptions capture_options; + + std::string stdout_str; + const char *args[] = { "gpu-screen-recorder", "--list-capture-options", gsr_info.gpu_info.card_path.c_str(), gpu_vendor_to_string(gsr_info.gpu_info.vendor), nullptr }; + if(exec_program_get_stdout(args, stdout_str) != 0) { + fprintf(stderr, "error: 'gpu-screen-recorder --list-capture-options' failed\n"); + return capture_options; + } + + string_split_char(stdout_str, '\n', [&](std::string_view line) { + parse_capture_options_line(capture_options, line); + return true; + }); + + return capture_options; + } } |