diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 175 |
1 files changed, 123 insertions, 52 deletions
diff --git a/src/main.cpp b/src/main.cpp index 4d38ad1..53c733b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "config.hpp" #include <gtk/gtk.h> #include <gdk/gdkx.h> #include <X11/Xlib.h> @@ -13,8 +14,6 @@ #include <sys/stat.h> #include <fcntl.h> #include <dlfcn.h> -#include <pwd.h> -#include <libgen.h> #include <functional> #include <vector> @@ -65,16 +64,15 @@ static bool replaying = false; static bool recording = false; static bool streaming = false; static pid_t gpu_screen_recorder_process = -1; - -static const char* get_home_dir() { - const char *home_dir = getenv("HOME"); - if(!home_dir) { - passwd *pw = getpwuid(getuid()); - home_dir = pw->pw_dir; - } - if(!home_dir) - home_dir = "/tmp"; - return home_dir; +static Config config; + +static bool is_directory(const char *filepath) { + struct stat file_stat; + memset(&file_stat, 0, sizeof(file_stat)); + int ret = stat(filepath, &file_stat); + if(ret == 0) + return S_ISDIR(file_stat.st_mode); + return false; } static std::string get_date_str() { @@ -85,38 +83,6 @@ static std::string get_date_str() { return str; } -static int create_directory_recursive(char *path) { - int path_len = strlen(path); - char *p = path; - char *end = path + path_len; - for(;;) { - char *slash_p = strchr(p, '/'); - - // Skips first '/', we don't want to try and create the root directory - if(slash_p == path) { - ++p; - continue; - } - - if(!slash_p) - slash_p = end; - - char prev_char = *slash_p; - *slash_p = '\0'; - int err = mkdir(path, S_IRWXU); - *slash_p = prev_char; - - if(err == -1 && errno != EEXIST) - return err; - - if(slash_p == end) - break; - else - p = slash_p + 1; - } - return 0; -} - static const XRRModeInfo* get_mode_info(const XRRScreenResources *sr, RRMode id) { for(int i = 0; i < sr->nmode; ++i) { if(sr->modes[i].id == id) @@ -358,8 +324,8 @@ static gboolean on_start_recording_click(GtkButton *button, gpointer userdata) { PageNavigationUserdata *page_navigation_userdata = (PageNavigationUserdata*)userdata; gtk_stack_set_visible_child(page_navigation_userdata->stack, page_navigation_userdata->recording_page); - std::string video_filepath = get_home_dir(); - video_filepath += "/Videos/Video_" + get_date_str() + ".mp4"; + std::string video_filepath = config.record_config.save_directory; + video_filepath += "/Video_" + get_date_str() + ".mp4"; gtk_button_set_label(file_chooser_button, video_filepath.c_str()); return true; } @@ -788,14 +754,21 @@ static void pa_state_cb(pa_context *c, void *userdata) { } } +struct AudioInput { + std::string name; + std::string description; +}; + static void pa_sourcelist_cb(pa_context *ctx, const pa_source_info *source_info, int eol, void *userdata) { if(eol > 0) return; - gtk_combo_box_text_append(audio_input_menu, source_info->name, source_info->description); + std::vector<AudioInput> *inputs = (std::vector<AudioInput>*)userdata; + inputs->push_back({ source_info->name, source_info->description }); } -static void populate_audio_input_menu_with_pulseaudio_monitors() { +static std::vector<AudioInput> get_pulseaudio_inputs() { + std::vector<AudioInput> inputs; pa_mainloop *main_loop = pa_mainloop_new(); pa_context *ctx = pa_context_new(pa_mainloop_get_api(main_loop), "gpu-screen-recorder-gtk"); @@ -815,7 +788,7 @@ static void populate_audio_input_menu_with_pulseaudio_monitors() { switch(state) { case 0: { - pa_op = pa_context_get_source_info_list(ctx, pa_sourcelist_cb, nullptr); + pa_op = pa_context_get_source_info_list(ctx, pa_sourcelist_cb, &inputs); ++state; break; } @@ -828,7 +801,7 @@ static void populate_audio_input_menu_with_pulseaudio_monitors() { pa_context_disconnect(ctx); pa_context_unref(ctx); pa_mainloop_free(main_loop); - return; + return inputs; } pa_mainloop_iterate(main_loop, 1, NULL); @@ -970,7 +943,9 @@ static GtkWidget* create_common_settings_page(GtkStack *stack, GtkApplication *a gtk_grid_attach(audio_grid, gtk_label_new("Audio input: "), 0, 0, 1, 1); audio_input_menu = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new()); gtk_combo_box_text_append(audio_input_menu, "None", "None"); - populate_audio_input_menu_with_pulseaudio_monitors(); + for(const AudioInput &audio_input : get_pulseaudio_inputs()) { + gtk_combo_box_text_append(audio_input_menu, audio_input.name.c_str(), audio_input.description.c_str()); + } g_signal_connect(audio_input_menu, "changed", G_CALLBACK(audio_input_change_callback), nullptr); gtk_widget_set_hexpand(GTK_WIDGET(audio_input_menu), true); gtk_grid_attach(audio_grid, GTK_WIDGET(audio_input_menu), 1, 0, 1, 1); @@ -1168,6 +1143,28 @@ static gboolean on_destroy_window(GtkWidget *widget, GdkEvent *event, gpointer d /* Ignore... */ } } + + const gchar *record_filename = gtk_button_get_label(file_chooser_button); + + char dir_tmp[PATH_MAX]; + strcpy(dir_tmp, record_filename); + char *record_dir = dirname(dir_tmp); + + config.main_config.record_area_option = gtk_combo_box_get_active_id(GTK_COMBO_BOX(record_area_selection_menu)); + config.main_config.fps = gtk_spin_button_get_value_as_int(fps_entry); + config.main_config.audio_input = gtk_combo_box_get_active_id(GTK_COMBO_BOX(audio_input_menu)); + config.main_config.quality = gtk_combo_box_get_active_id(GTK_COMBO_BOX(quality_input_menu)); + + config.streaming_config.streaming_service = gtk_combo_box_get_active_id(GTK_COMBO_BOX(stream_service_input_menu)); + config.streaming_config.stream_key = gtk_entry_get_text(stream_id_entry); + + config.record_config.save_directory = record_dir; + + config.replay_config.save_directory = gtk_button_get_label(replay_file_chooser_button); + config.replay_config.replay_time = gtk_spin_button_get_value_as_int(replay_time_entry); + + save_config(config); + return true; } @@ -1258,7 +1255,80 @@ static gboolean handle_child_process_death(gpointer userdata) { return G_SOURCE_CONTINUE; } -static void activate(GtkApplication *app, gpointer userdata) { +static void load_config() { + config = read_config(); + + if(strcmp(config.main_config.record_area_option.c_str(), "window") == 0) { + // + } else if(strcmp(config.main_config.record_area_option.c_str(), "focused") == 0) { + // + } else if(strcmp(config.main_config.record_area_option.c_str(), "screen") == 0 || strcmp(config.main_config.record_area_option.c_str(), "screen-direct") == 0) { + // + } else { + bool found_monitor = false; + int monitor_name_size = strlen(config.main_config.record_area_option.c_str()); + for_each_active_monitor_output(gdk_x11_get_default_xdisplay(), [&](const XRROutputInfo *output_info, const XRRCrtcInfo *crtc_info, const XRRModeInfo*) { + if(monitor_name_size == output_info->nameLen && strncmp(config.main_config.record_area_option.c_str(), output_info->name, output_info->nameLen) == 0) { + found_monitor = true; + } + }); + + if(!found_monitor) + config.main_config.record_area_option = "window"; + } + + if(config.main_config.fps < 1) + config.main_config.fps = 1; + else if(config.main_config.fps > 5000) + config.main_config.fps = 5000; + + if(config.main_config.audio_input != "None") { + bool found_audio_input = false; + for(const AudioInput &audio_input : get_pulseaudio_inputs()) { + if(config.main_config.audio_input == audio_input.name) { + found_audio_input = true; + break; + } + } + + if(!found_audio_input) + config.main_config.audio_input = "None"; + } + + if(config.main_config.quality != "medium" && config.main_config.quality != "high" && config.main_config.quality != "ultra") + config.main_config.quality = "medium"; + + if(config.streaming_config.streaming_service != "twitch" && config.streaming_config.streaming_service != "youtube") + config.streaming_config.streaming_service = "twitch"; + + if(config.record_config.save_directory.empty() || !is_directory(config.record_config.save_directory.c_str())) + config.record_config.save_directory = get_home_dir() + "/Videos"; + + if(config.replay_config.save_directory.empty() || !is_directory(config.replay_config.save_directory.c_str())) + config.replay_config.save_directory = get_home_dir() + "/Videos"; + + if(config.replay_config.replay_time < 5) + config.replay_config.replay_time = 5; + else if(config.replay_config.replay_time> 1200) + config.replay_config.replay_time = 1200; + + gtk_combo_box_set_active_id(GTK_COMBO_BOX(record_area_selection_menu), config.main_config.record_area_option.c_str()); + gtk_spin_button_set_value(fps_entry, config.main_config.fps); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(audio_input_menu), config.main_config.audio_input.c_str()); + gtk_combo_box_set_active_id(GTK_COMBO_BOX(quality_input_menu), config.main_config.quality.c_str()); + + gtk_combo_box_set_active_id(GTK_COMBO_BOX(stream_service_input_menu), config.streaming_config.streaming_service.c_str()); + gtk_entry_set_text(stream_id_entry, config.streaming_config.stream_key.c_str()); + + std::string video_filepath = config.record_config.save_directory; + video_filepath += "/Video_" + get_date_str() + ".mp4"; + gtk_button_set_label(file_chooser_button, video_filepath.c_str()); + + gtk_button_set_label(replay_file_chooser_button, config.replay_config.save_directory.c_str()); + gtk_spin_button_set_value(replay_time_entry, config.replay_config.replay_time); +} + +static void activate(GtkApplication *app, gpointer userdata) { GtkWidget *window = gtk_application_window_new(app); g_signal_connect(window, "destroy", G_CALLBACK(on_destroy_window), nullptr); gtk_window_set_title(GTK_WINDOW(window), "GPU Screen Recorder"); @@ -1304,6 +1374,7 @@ static void activate(GtkApplication *app, gpointer userdata) { g_timeout_add(1000, handle_child_process_death, app); + load_config(); gtk_widget_show_all(window); } |