diff --git a/gtk3/main.c b/gtk3/main.c index 6cdfddc..4d3ea40 100644 --- a/gtk3/main.c +++ b/gtk3/main.c @@ -54,6 +54,7 @@ typedef struct GuiData { GFile *file; gint sample_rate; + GDateTime *config_modification_date; char *battery_save_path; char *cheats_save_path; @@ -1615,7 +1616,14 @@ static void run(void) { // // TODO: Make sure we have a way to quit our emulation loop before `shutdown` gets called static void quit(void) { + g_debug("quit(void);"); + stop(); + while (gui_data.stopping); + + GtkWindow *window = gui_data.main_window ? GTK_WINDOW(gui_data.main_window) : NULL; + save_settings(window, gui_data.config_modification_date); + free_settings(); for (unsigned i = 0; i < gui_data.controller_count; i++) { struct Controller_t *s = &gui_data.controllers[i]; @@ -1630,12 +1638,16 @@ static void quit(void) { } static void quit_interrupt(int ignored) { + g_debug("quit_interrupt(%d);", ignored); + quit(); } // `destroy` signal GCallback // Exits the application static void on_quit(GtkWidget *w, gpointer app) { + g_debug("on_quit(%p, %p);", w, &app); + quit(); } @@ -1994,7 +2006,7 @@ static void startup(GApplication *app, gpointer null_ptr) { gui_data.preferences = GTK_WINDOW(get_object("preferences")); g_signal_connect(gui_data.preferences, "realize", G_CALLBACK(on_preferences_realize), (gpointer) gui_data.builder); - init_settings(app, gui_data.cli_options.config_path, gui_data.preferences); + init_settings(app, gui_data.cli_options.config_path, &gui_data.config_modification_date, gui_data.preferences); gui_data.vram_viewer = GTK_WINDOW(get_object("vram_viewer")); gui_data.memory_viewer = GTK_WINDOW(get_object("memory_viewer")); @@ -2311,11 +2323,6 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar stop(); while (gui_data.stopping); - - g_object_unref(gui_data.builder); - - save_settings(); - free_settings(); SDL_Quit(); if (gui_data.image_buffers[0]) g_free(gui_data.image_buffers[0]); @@ -2325,6 +2332,8 @@ static void shutdown(GApplication *app, GFile **files, gint n_files, const gchar free_master_shader(); GB_free(&gb); + + g_object_unref(gui_data.builder); } // This function gets called when there are files to open. diff --git a/gtk3/settings.c b/gtk3/settings.c index f763828..c399b45 100644 --- a/gtk3/settings.c +++ b/gtk3/settings.c @@ -3,6 +3,9 @@ #define get_object(id) gtk_builder_get_object(builder, id) #define builder_get(type, id) type(get_object(id)) +gchar* settings_file_path; +GKeyFile *key_file; + static void print_config_error(GError *error) { if (error == NULL) return; @@ -108,6 +111,13 @@ void save_config_to_key_file(config_t *config, GKeyFile *key_file) { #undef EXPAND_GROUP_MEMBER_IF_EVAL #undef EXPAND_GROUP_MEMBER_IF_0 #undef EXPAND_GROUP_MEMBER_IF_1 + + // Save config to disk + if (!g_key_file_save_to_file(key_file, settings_file_path, &error)) { + g_warning ("Failed to save %s: %s", settings_file_path, error->message); + g_error_free(error); + return; + } } void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { @@ -147,7 +157,7 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr) { #endif } -void init_settings(GApplication *app, gchar *path, GtkWindow *preferences) { +void init_settings(GApplication *app, gchar *path, GDateTime **modification_date, GtkWindow *preferences) { free_settings(); key_file = g_key_file_new(); @@ -158,14 +168,18 @@ void init_settings(GApplication *app, gchar *path, GtkWindow *preferences) { settings_file_path = g_build_filename(g_get_user_config_dir(), SETTINGS_FILE, NULL); } - load_settings(app); + load_settings(app, modification_date); } -int load_settings(GApplication *app) { +int load_settings(GApplication *app, GDateTime **modification_date) { GError *error = NULL; g_message("Trying to load settings from %s", settings_file_path); + g_autoptr(GFile) file = g_file_new_for_path(settings_file_path); + g_autoptr(GFileInfo) file_info = g_file_query_info(file, "time::*", G_FILE_QUERY_INFO_NONE, NULL, NULL); + *modification_date = g_file_info_get_modification_date_time(file_info); + if (!g_key_file_load_from_file(key_file, settings_file_path, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)) { if (error->domain == G_FILE_ERROR) { g_warning("Unable to load %s: %s", settings_file_path, error->message); @@ -186,17 +200,40 @@ int load_settings(GApplication *app) { return 0; } -void save_settings(void) { +void save_settings(GtkWindow *main_window, GDateTime *saved_modification_date) { GError *error = NULL; g_message("Trying to save settings to %s", settings_file_path); - save_config_to_key_file(&config, key_file); + g_autoptr(GFile) file = g_file_new_for_path(settings_file_path); + g_autoptr(GFileInfo) file_info = g_file_query_info(file, "time::*", G_FILE_QUERY_INFO_NONE, NULL, NULL); + GDateTime *modification_date = g_file_info_get_modification_date_time(file_info); - if (!g_key_file_save_to_file(key_file, settings_file_path, &error)) { - g_warning ("Failed to save %s: %s", settings_file_path, error->message); - g_error_free(error); - return; + if (!g_date_time_equal(saved_modification_date, modification_date)) { + GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new( + main_window, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "It looks like the configuration has changed on disk. Overwrite?" + )); + + gtk_window_set_title(GTK_WINDOW(dialog), "SameBoy"); + + gint result = gtk_dialog_run(GTK_DIALOG(dialog)); + + switch (result) { + case GTK_RESPONSE_YES: + save_config_to_key_file(&config, key_file); + break; + + default: + // Action has been canceled + break; + } + } + else { + save_config_to_key_file(&config, key_file); } } diff --git a/gtk3/settings.h b/gtk3/settings.h index 60e153f..0caf1a4 100644 --- a/gtk3/settings.h +++ b/gtk3/settings.h @@ -76,8 +76,6 @@ enum menubar_type_t { MENUBAR_SHOW_HAMBURGER }; -gchar* settings_file_path; -GKeyFile *key_file; config_t config; void on_preferences_realize(GtkWidget *w, gpointer builder_ptr); @@ -85,9 +83,9 @@ void on_preferences_realize(GtkWidget *w, gpointer builder_ptr); void print_config(config_t *config); void load_config_from_key_file(config_t *config, GKeyFile *key_file); -void init_settings(GApplication *app, gchar *path, GtkWindow *preferences); -int load_settings(GApplication *app); -void save_settings(void); +void init_settings(GApplication *app, gchar *path, GDateTime **modification_date, GtkWindow *preferences); +int load_settings(GApplication *app, GDateTime **modification_date); +void save_settings(GtkWindow *main_window, GDateTime *saved_modification_date); void free_settings(void); void update_boot_rom_selector(GtkBuilder *builder);