#include "../../include/gui/SettingsPage.hpp" #include "../../include/gui/GsrPage.hpp" #include "../../include/gui/Label.hpp" #include "../../include/gui/PageStack.hpp" #include "../../include/gui/FileChooser.hpp" #include "../../include/gui/Subsection.hpp" #include "../../include/gui/CustomRendererWidget.hpp" #include "../../include/gui/Image.hpp" #include "../../include/gui/Utils.hpp" #include "../../include/Theme.hpp" #include "../../include/GsrInfo.hpp" #include "../../include/Utils.hpp" #include "../../include/Translation.hpp" #include #include #include #include #include #include #include #include namespace gsr { static const char *custom_app_audio_tag = "[custom]"; enum class AudioTrackType { DEVICE, APPLICATION, APPLICATION_CUSTOM }; static const char* settings_page_type_to_title_text(SettingsPage::Type type) { switch(type) { case SettingsPage::Type::REPLAY: return TR("Instant Replay"); case SettingsPage::Type::RECORD: return TR("Record"); case SettingsPage::Type::STREAM: return TR("Livestream"); } return ""; } template static T sv_to_int(std::string_view str) { T result = 0; std::from_chars(str.data(), str.data() + str.size(), result); return result; } static bool supports_vulkan_video_encoding(const SupportedVideoCodecs &supported_video_codecs) { return supported_video_codecs.h264_vulkan || supported_video_codecs.hevc_vulkan || supported_video_codecs.hevc_hdr_vulkan || supported_video_codecs.hevc_10bit_vulkan || supported_video_codecs.av1_vulkan || supported_video_codecs.av1_hdr_vulkan || supported_video_codecs.av1_10bit_vulkan; } static std::optional webcam_get_name(std::string_view webcam_path) { std::optional v4l2_device_name; if(!starts_with(webcam_path, "/dev/video")) return v4l2_device_name; const std::string_view path_filename = webcam_path.substr(5); char v4l2_device_name_path[64]; snprintf(v4l2_device_name_path, sizeof(v4l2_device_name_path), "/sys/class/video4linux/%.*s/name", (int)path_filename.size(), path_filename.data()); const int fd = open(v4l2_device_name_path, O_RDONLY); if(fd < 0) return v4l2_device_name; char webcam_name_buf[256]; const ssize_t bytes_read = read(fd, webcam_name_buf, sizeof(webcam_name_buf)); if(bytes_read > 0) { v4l2_device_name = std::string(webcam_name_buf, bytes_read); if(v4l2_device_name->back() == '\n') v4l2_device_name->pop_back(); v4l2_device_name.value() += " (" + std::string(webcam_path) + ")"; } close(fd); return v4l2_device_name; } SettingsPage::SettingsPage(Type type, const GsrInfo *gsr_info, Config &config, PageStack *page_stack, bool supports_window_title) : StaticPage(mgl::vec2f(get_theme().window_width, get_theme().window_height).floor()), type(type), config(config), gsr_info(gsr_info), page_stack(page_stack), supports_window_title(supports_window_title) { audio_devices = get_audio_devices(); application_audio = get_application_audio(); capture_options = get_supported_capture_options(*gsr_info); auto content_page = std::make_unique(settings_page_type_to_title_text(type), TR("Settings")); content_page->add_button(TR("Back"), "back", get_color_theme().page_bg_color); content_page->on_click = [page_stack](const std::string &id) { if(id == "back") page_stack->pop(); }; content_page_ptr = content_page.get(); add_widget(std::move(content_page)); add_widgets(); add_page_specific_widgets(); load(); } std::unique_ptr SettingsPage::create_view_radio_button() { auto view_radio_button = std::make_unique(get_theme().body_font_desc.c_str(), RadioButton::Orientation::HORIZONTAL); view_radio_button->add_item(TR("Simple view"), "simple"); view_radio_button->add_item(TR("Advanced view"), "advanced"); view_radio_button->set_horizontal_alignment(Widget::Alignment::CENTER); view_radio_button_ptr = view_radio_button.get(); return view_radio_button; } std::unique_ptr SettingsPage::create_record_area_box() { auto record_area_box = std::make_unique(get_theme().body_font_desc.c_str()); // TODO: Show options not supported but disable them if(capture_options.window) record_area_box->add_item(TR("Window"), "window"); if(capture_options.focused) record_area_box->add_item(TR("Follow focused window"), "focused"); if(capture_options.region) record_area_box->add_item(TR("Region"), "region"); if(!capture_options.monitors.empty()) record_area_box->add_item(TR("Focused monitor"), "focused_monitor"); for(const auto &monitor : capture_options.monitors) { char name[256]; snprintf(name, sizeof(name), TR("Monitor %s (%dx%d)"), monitor.name.c_str(), monitor.size.x, monitor.size.y); record_area_box->add_item(name, monitor.name); } if(capture_options.portal) record_area_box->add_item(TR("Desktop portal"), "portal"); record_area_box_ptr = record_area_box.get(); return record_area_box; } std::unique_ptr SettingsPage::create_record_area() { auto record_area_list = std::make_unique(List::Orientation::VERTICAL); record_area_list->add_widget(std::make_unique