You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

183 lines
5.5 KiB

#include "settings-window.hpp"
#include "settings-manager.hpp"
#include <linux/videodev2.h>
#include <iostream>
#include <filesystem>
#include <stdexcept>
#include <fcntl.h>
#include <libv4l2.h>
#include <sys/dir.h>
using namespace std;
SettingsWindow::SettingsWindow(OBSManager* obs)
: mBox(Gtk::Orientation::ORIENTATION_VERTICAL, 2),
mBoxSettings(Gtk::Orientation::ORIENTATION_VERTICAL, 2),
mBoxPluginDir(Gtk::Orientation::ORIENTATION_HORIZONTAL, 2),
mLabelPluginDir("Plugin Dir: "),
mBoxOutputDir(Gtk::Orientation::ORIENTATION_HORIZONTAL, 2),
mLabelOutputDir("Saved Files Dir: "),
mCheckButtonDesktop("Enable desktop recording"),
mBoxWebcam(Gtk::Orientation::ORIENTATION_VERTICAL, 2),
mCheckButtonWebcam("Enable webcam recording"),
mCheckButtonAudio("Enable audio recording"),
mButtonClose("Close"),
mButtonSave("Save")
{
set_title("Settings");
set_default_size(640, 480);
set_border_width(10);
set_modal(true);
set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_DIALOG);
settings = new SettingsManager();
signal_key_press_event().connect(
sigc::mem_fun(*this, &SettingsWindow::onKeyPressed));
mButtonClose.signal_clicked().connect(
sigc::mem_fun(*this, &SettingsWindow::onClosePressed));
mButtonSave.signal_clicked().connect(
sigc::mem_fun(*this, &SettingsWindow::onSavePressed));
mBoxSettings.set_border_width(10);
mEntryPluginDir.set_hexpand(true);
mEntryPluginDir.set_text(settings->GetWithDefault(SETTINGS_KEY_PLUGIN_DIR, SETTINGS_DEFAULT_PLUGIN_DIR));
mBoxPluginDir.set_border_width(10);
mBoxPluginDir.add(mLabelPluginDir);
mBoxPluginDir.add(mEntryPluginDir);
mEntryOutputDir.set_hexpand(true);
mEntryOutputDir.set_text(settings->GetWithDefault(SETTINGS_KEY_OUTPUT_DIR, std::filesystem::current_path()));
mBoxOutputDir.set_border_width(10);
mBoxOutputDir.add(mLabelOutputDir);
mBoxOutputDir.add(mEntryOutputDir);
mFrameDesktop.set_label("Desktop");
mFrameDesktop.set_border_width(10);
mCheckButtonDesktop.set_border_width(10);
mCheckButtonDesktop.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_SCREEN_ENABLED, true));
mFrameDesktop.add(mCheckButtonDesktop);
mComboBoxVideoDevice.set_border_width(10);
mFrameWebcam.set_label("Webcam");
mFrameWebcam.set_border_width(10);
mBoxWebcam.set_border_width(10);
mCheckButtonWebcam.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_WEBCAM_ENABLED, true));
mBoxWebcam.add(mCheckButtonWebcam);
mBoxWebcam.add(mComboBoxVideoDevice);
mFrameWebcam.add(mBoxWebcam);
mFrameAudio.set_label("Microphone");
mFrameAudio.set_border_width(10);
mCheckButtonAudio.set_border_width(10);
mCheckButtonAudio.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_AUDIO_ENABLED, true));
mFrameAudio.add(mCheckButtonAudio);
mBoxSettings.add(mBoxPluginDir);
mBoxSettings.add(mBoxOutputDir);
mBoxSettings.add(mFrameDesktop);
mBoxSettings.add(mFrameWebcam);
mBoxSettings.add(mFrameAudio);
mFrameSettings.set_label("Settings");
mFrameSettings.set_border_width(10);
mFrameSettings.add(mBoxSettings);
mActionBar.pack_end(mButtonSave);
mActionBar.pack_end(mButtonClose);
mBox.add(mFrameSettings);
mBox.add(mActionBar);
mBox.show_all();
add(mBox);
}
SettingsWindow::~SettingsWindow()
{
}
void SettingsWindow::on_show()
{
Gtk::Window::on_show();
populateVideoDevices();
}
bool SettingsWindow::onKeyPressed(GdkEventKey *event)
{
if (event->keyval == GDK_KEY_Escape)
{
close();
return true;
}
return false;
}
void SettingsWindow::onClosePressed()
{
close();
}
void SettingsWindow::onSavePressed()
{
settings->Update(SETTINGS_KEY_PLUGIN_DIR, mEntryPluginDir.get_text());
settings->Update(SETTINGS_KEY_OUTPUT_DIR, mEntryOutputDir.get_text());
settings->UpdateBool(SETTINGS_KEY_SCREEN_ENABLED, mCheckButtonDesktop.get_active());
settings->UpdateBool(SETTINGS_KEY_WEBCAM_ENABLED, mCheckButtonWebcam.get_active());
settings->Update(SETTINGS_KEY_VIDEO_DEVICE_ID, mComboBoxVideoDevice.get_active_id());
settings->UpdateBool(SETTINGS_KEY_AUDIO_ENABLED, mCheckButtonAudio.get_active());
settings->SaveAll();
close();
}
void SettingsWindow::populateVideoDevices()
{
v4l2_capability cap;
dirent *dp;
auto dirp = opendir("/sys/class/video4linux");
if (!dirp)
throw runtime_error("Failed to get video devices");
while ((dp = readdir(dirp)) != nullptr)
{
int fd;
if (dp->d_type == DT_DIR)
continue;
auto name = string(dp->d_name);
if (name.find("video") == string::npos)
continue;
auto device = "/dev/" + name;
if ((fd = v4l2_open(device.c_str(), O_RDWR | O_NONBLOCK)) == -1)
{
cout << "Failed to open device: " << device << endl;
continue;
}
if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)
{
cout << "Failed to query device: " << device << endl;
v4l2_close(fd);
continue;
}
auto n = string(reinterpret_cast<char*>(cap.card));
n += " (" + device + ")";
mComboBoxVideoDevice.append(device, n);
if (settings->Get(SETTINGS_KEY_VIDEO_DEVICE_ID) == device)
mComboBoxVideoDevice.set_active_id(device);
v4l2_close(fd);
}
}