Ejemplo n.º 1
0
static void
audit_exit (GvaProcess *process,
            gint status,
            GvaAuditData *data)
{
        gchar *sql;
        GError *error = NULL;

        if (process->error != NULL)
                return;

        gva_db_transaction_begin (&error);
        gva_error_handle (&error);

        sql = g_strdup_printf ("UPDATE game SET %s=NULL", data->column);
        gva_db_execute (sql, &error);
        gva_error_handle (&error);
        g_free (sql);

        g_hash_table_foreach (
                data->status_index, (GHFunc) audit_exit_foreach, data);

        gva_db_transaction_commit (&error);
        gva_error_handle (&error);
}
Ejemplo n.º 2
0
/**
 * gva_audit_detect_changes:
 *
 * Attempts to detect ROM and sample file changes since the last program
 * execution by scanning the timestamps on the directories listed in the
 * "rompath" and "samplepath" configuration values.  It returns %TRUE if
 * any of those timestamps are more recent than the game database.
 *
 * Returns: %TRUE if changes were detected
 **/
gboolean
gva_audit_detect_changes (void)
{
        gboolean changes = FALSE;
        gchar **directories;
        struct stat st;
        guint length, ii;
        GError *error = NULL;

        if (g_stat (gva_db_get_filename (), &st) < 0)
                return FALSE;

        directories = gva_mame_get_search_paths ("rompath", &error);
        length = (directories != NULL) ? g_strv_length (directories) : 0;
        gva_error_handle (&error);

        for (ii = 0; ii < length; ii++)
                changes |= gva_db_is_older_than (directories[ii]);

        g_strfreev (directories);

        directories = gva_mame_get_search_paths ("samplepath", &error);
        length = (directories != NULL) ? g_strv_length (directories) : 0;
        gva_error_handle (&error);

        for (ii = 0; ii < length; ii++)
                changes |= gva_db_is_older_than (directories[ii]);

        g_strfreev (directories);

        return changes;
}
Ejemplo n.º 3
0
static void
start (void)
{
        GSettings *settings;
        GError *error = NULL;

        settings = gva_get_settings ();

        if (gva_db_needs_rebuilt ())
        {
                if (!gva_main_build_database (&error))
                {
                        gva_error_handle (&error);
                        return;
                }

                if (!gva_main_analyze_roms (&error))
                {
                        gva_error_handle (&error);
                        return;
                }

                if (!gva_db_mark_complete (&error))
                {
                        gva_error_handle (&error);
                        return;
                }
        }
        else if (gva_audit_detect_changes ())
        {
                if (!gva_main_analyze_roms (&error))
                {
                        gva_error_handle (&error);
                        return;
                }
        }

        /* Do this after ROMs are analyzed. */
        if (!gva_main_init_search_completion (&error))
        {
                gva_error_handle (&error);
                return;
        }

        gva_ui_unlock ();

        g_settings_bind (
                settings, GVA_SETTING_SELECTED_VIEW,
                GVA_ACTION_VIEW_AVAILABLE, "current-value",
                G_SETTINGS_BIND_DEFAULT);

        /* Present a helpful dialog if no ROMs were found. */
        warn_if_no_roms ();

        /* Listen for changes to the 'rompath' directories. */
        setup_file_monitors ();
}
Ejemplo n.º 4
0
static gboolean
wnck_window_timeout_cb (WnckWindow *window)
{
        const gchar *game;
        gint x, y;
        gint width, height;
        gchar *sql;
        GError *error = NULL;

        if (wnck_window_is_fullscreen (window))
                goto exit;

        game = wnck_window_get_game (window);
        wnck_window_get_geometry (window, &x, &y, &width, &height);

        if (wnck_window_is_maximized (window))
                sql = g_strdup_printf (
                        "UPDATE window SET maximized = 1 "
                        "WHERE name = '%s'", game);
        else
                sql = g_strdup_printf (
                        "UPDATE window SET x = %d, y = %d, width = %d, "
                        "height = %d, maximized = 0 WHERE name = '%s'",
                        x, y, width, height, game);

        gva_db_execute (sql, &error);
        gva_error_handle (&error);
        g_free (sql);

exit:
        g_object_set_data (G_OBJECT (window), TIMEOUT_SOURCE_ID_KEY, NULL);

        return FALSE;
}
Ejemplo n.º 5
0
/**
 * gva_mame_get_save_state_file:
 * @name: the name of a game
 *
 * Returns the name of the automatic save state file for @name.
 *
 * Returns: the name of the save state file
 **/
gchar *
gva_mame_get_save_state_file (const gchar *name)
{
        const gchar *directory;
        gchar *basename;
        gchar *filename = NULL;
        GError *error = NULL;

        directory = gva_mame_get_state_directory (&error);
        gva_error_handle (&error);
        if (directory == NULL)
                return NULL;

        /* As of 0.115, MAME stores save state files as "name/auto.sta". */
        filename = g_build_filename (directory, name, "auto.sta", NULL);

        if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
                return filename;
        else
                g_free (filename);

        /* Prior to 0.115, MAME stored save state files as "name.sta". */
        basename = g_strdup_printf ("%s.sta", name);
        filename = g_build_filename (directory, basename, NULL);
        g_free (basename);

        if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
                return filename;
        else
                g_free (filename);

        return NULL;  /* file not found */
}
Ejemplo n.º 6
0
/**
 * gva_audit_save_errors:
 *
 * Saves the results of the most recent ROM file audit to a file.
 **/
void
gva_audit_save_errors (void)
{
        GtkTreeView *view;
        GtkTreeModel *model;
        GString *contents;
        gchar *mame_version;
        gchar *filename;
        GError *error = NULL;

        view = GTK_TREE_VIEW (GVA_WIDGET_AUDIT_TREE_VIEW);
        model = gtk_tree_view_get_model (view);
        g_return_if_fail (model != NULL);

        mame_version = gva_mame_get_version (&error);
        gva_error_handle (&error);

        /* Build the contents of the file. */
        contents = g_string_sized_new (4096);
        g_string_append_printf (
                contents, "%s - ROM Audit Results\n", PACKAGE_STRING);
        if (mame_version != NULL)
                g_string_append_printf (contents, "Using %s\n", mame_version);
        else
                g_string_append (contents, "Using unknown M.A.M.E. version\n");
        g_string_append_c (contents, '\n');
        gtk_tree_model_foreach (
                model, (GtkTreeModelForeachFunc)
                audit_save_errors_foreach, contents);

        /* Prompt the user for a filename. */
        filename = audit_run_save_dialog ();
        if (filename != NULL)
        {
                g_file_set_contents (filename, contents->str, -1, &error);
                gva_error_handle (&error);
                g_free (filename);
        }

        g_free (mame_version);
        g_string_free (contents, TRUE);
}
Ejemplo n.º 7
0
/**
 * gva_main_set_last_search_text:
 * @text: the search entry text
 *
 * Writes @text to GConf key
 * <filename>/apps/gnome-video-arcade/search</filename>.
 *
 * This is used to remember the search entry text from the previous session
 * of <emphasis>GNOME Video Arcade</emphasis> so that the same text can be
 * preset in the search entry at startup.
 **/
void
gva_main_set_last_search_text (const gchar *text)
{
        GConfClient *client;
        GError *error = NULL;

        g_return_if_fail (text != NULL);

        client = gconf_client_get_default ();
        gconf_client_set_string (client, GVA_GCONF_SEARCH_KEY, text, &error);
        gva_error_handle (&error);
        g_object_unref (client);
}
Ejemplo n.º 8
0
static void
warn_if_no_roms (void)
{
        const gchar *sql = SQL_COUNT_ROMS;
        GtkWidget *dialog;
        gchar **result;
        glong n_roms;
        GError *error = NULL;

        if (!gva_db_get_table (sql, &result, NULL, NULL, &error))
        {
                gva_error_handle (&error);
                return;
        }

        errno = 0;
        g_return_if_fail (g_strv_length (result) > 1);
        n_roms = strtol (result[1], NULL, 10);
        g_strfreev (result);

        if (errno != 0)
        {
                g_warning ("%s", g_strerror (errno));
                return;
        }

        if (n_roms > 0)
                return;

        dialog = gtk_message_dialog_new_with_markup (
                GTK_WINDOW (GVA_WIDGET_MAIN_WINDOW),
                GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
                "<big><b>%s</b></big>",
                _("No ROM files found"));

        gtk_message_dialog_format_secondary_markup (
                GTK_MESSAGE_DIALOG (dialog),
                _("GNOME Video Arcade was unable to locate any ROM files. "
                  "It could be that MAME is misconfigured or that no ROM "
                  "files are installed. Click <b>Help</b> for more details "
                  "and troubleshooting tips."));

        gtk_dialog_add_button (
                GTK_DIALOG (dialog), GTK_STOCK_HELP, GTK_RESPONSE_HELP);

        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_HELP)
                gva_help_display (GTK_WINDOW (dialog), "troubleshooting");

        gtk_widget_destroy (dialog);
}
Ejemplo n.º 9
0
/**
 * gva_main_get_last_search_text:
 *
 * Returns the most recent search entry text from either the current or
 * previous session of <emphasis>GNOME Video Arcade</emphasis>.
 *
 * Returns: the most recent search text
 **/
gchar *
gva_main_get_last_search_text (void)
{
        GConfClient *client;
        gchar *text;
        GError *error = NULL;

        client = gconf_client_get_default ();
        text = gconf_client_get_string (client, GVA_GCONF_SEARCH_KEY, &error);
        gva_error_handle (&error);
        g_object_unref (client);

        return (text != NULL) ? g_strstrip (text) : g_strdup ("");
}
Ejemplo n.º 10
0
/**
 * gva_main_execute_search:
 *
 * Executes a game database search and configures the main window to
 * display the results.  More precisely, the function saves the search
 * entry contents to GConf, switches to the Search Results view, forces
 * an update, ensures a row in the resulting game list is selected, and
 * gives focus to the main tree view.
 *
 * The SQL expression used in the database search is retrieved from
 * gva_main_get_search_expression().  It is applied while updating the
 * Search Results view.
 **/
void
gva_main_execute_search (void)
{
        GtkTreeSelection *selection;
        GtkTreeModel *model;
        GtkTreeView *view;
        GtkTreeIter iter;
        GtkEntry *entry;
        gchar *text;

        entry = GTK_ENTRY (GVA_WIDGET_MAIN_SEARCH_ENTRY);
        view = GTK_TREE_VIEW (GVA_WIDGET_MAIN_TREE_VIEW);
        selection = gtk_tree_view_get_selection (view);

        /* Save the search entry text. */
        text = g_strdup (gtk_entry_get_text (entry));
        gtk_entry_set_text (entry, g_strstrip (text));
        gva_main_set_last_search_text (text);
        g_free (text);

        /* Force a tree view update. */
        if (gva_tree_view_get_selected_view () != 2)
                gva_tree_view_set_selected_view (2);
        else
        {
                GError *error = NULL;

                gva_tree_view_update (&error);
                gva_error_handle (&error);
        }

        /* Select something in the tree view.  Parts of this are
         * copied from gva_tree_view_set_selected_game(). */
        if (!gtk_tree_selection_get_selected (selection, &model, &iter))
        {
                if (gtk_tree_model_get_iter_first (model, &iter))
                {
                        GtkTreePath *path;

                        path = gtk_tree_model_get_path (model, &iter);
                        gtk_tree_view_set_cursor (view, path, NULL, FALSE);
                        gtk_tree_view_scroll_to_cell (
                                view, path, NULL, TRUE, 0.5, 0.0);
                        gtk_tree_path_free (path);
                }
        }

        gtk_widget_grab_focus (GTK_WIDGET (view));
}
Ejemplo n.º 11
0
/* Helper for audit_exit() */
static void
audit_exit_foreach (gchar *status,
                    GString *names,
                    GvaAuditData *data)
{
        gchar *sql;
        GError *error = NULL;

        sql = g_strdup_printf (
                "UPDATE game SET %s=\"%s\" WHERE name IN (%s)",
                data->column, status, names->str);
        gva_db_execute (sql, &error);
        gva_error_handle (&error);
        g_free (sql);
}
Ejemplo n.º 12
0
/**
 * gva_main_get_last_selected_match:
 * @column_name: return location for the column name
 * @search_text: return location for the search text
 *
 * Returns the most recently selected match in a search completion list
 * from either the current or previous session of <emphasis>GNOME Video
 * Arcade</emphasis>.  If the completion feature was not used in the
 * most recent search, @column_name and @search_text are set to %NULL
 * and the function returns %FALSE.
 *
 * Returns: %TRUE if match values were successfully retrieved from GConf,
 *          %FALSE otherwise
 **/
gboolean
gva_main_get_last_selected_match (gchar **column_name,
                                  gchar **search_text)
{
        GConfClient *client;
        gboolean success;
        GError *error = NULL;

        g_return_val_if_fail (column_name != NULL, FALSE);
        g_return_val_if_fail (search_text != NULL, FALSE);

        *column_name = *search_text = NULL;

        client = gconf_client_get_default ();
        success = gconf_client_get_pair (
                client, GVA_GCONF_SELECTED_MATCH_KEY,
                GCONF_VALUE_STRING, GCONF_VALUE_STRING,
                column_name, search_text, &error);
        gva_error_handle (&error);
        g_object_unref (client);

        if (!success)
                return FALSE;

        /* The value may be unset.  Treat it as a failure. */
        if (*column_name == NULL || *search_text == NULL)
                goto fail;

        g_strstrip (*column_name);
        g_strstrip (*search_text);

        /* Both strings must be non-empty. */
        if (**column_name == '\0' || **search_text == '\0')
                goto fail;

        return TRUE;

fail:
        g_free (*column_name);
        g_free (*search_text);

        *column_name = *search_text = NULL;

        return FALSE;
}
Ejemplo n.º 13
0
/**
 * gva_play_back_show:
 * @inpname: an input filename or %NULL
 *
 * Refreshes the contents of the Recorded Games window, attempts to
 * select the row corresponding to @inpname (if @inpname is not %NULL),
 * and finally shows the window.
 **/
void
gva_play_back_show (const gchar *inpname)
{
        GHashTable *hash_table;
        GvaGameStore *game_store;
        GtkTreeView *view;
        GError *error = NULL;

        view = GTK_TREE_VIEW (GVA_WIDGET_PLAY_BACK_TREE_VIEW);
        game_store = GVA_GAME_STORE (gtk_tree_view_get_model (view));

        hash_table = gva_mame_get_input_files (&error);
        gva_error_handle (&error);

        if (hash_table != NULL)
        {
                gva_game_store_clear (game_store);
                g_hash_table_foreach (
                        hash_table, (GHFunc) play_back_add_input_file,
                        game_store);
                g_hash_table_destroy (hash_table);
        }

        if (inpname != NULL)
        {
                GtkTreePath *path;

                path = gva_game_store_index_lookup (game_store, inpname);

                if (path != NULL)
                {
                        gtk_tree_view_set_cursor (view, path, NULL, FALSE);
                        gtk_tree_view_scroll_to_cell (
                                view, path, NULL, TRUE, 0.5, 0.0);
                        gtk_widget_grab_focus (GTK_WIDGET (view));
                        gtk_tree_path_free (path);
                }
        }

        gtk_window_present (GTK_WINDOW (GVA_WIDGET_PLAY_BACK_WINDOW));
}
Ejemplo n.º 14
0
/**
 * gva_main_set_last_selected_match:
 * @column_name: the column name of the completion match
 * @search_text: the search text of the completion match
 *
 * Writes @column_name and @search_text to GConf key
 * <filename>/apps/gnome-video-arcade/sql-expression</filename> as a
 * string pair.
 *
 * This is used to remember whether the search results from the previous
 * session of <emphasis>GNOME Video Arcade</emphasis> were the result of
 * selecting a match from the search completion list.  If so, the values
 * are also used to restore the contents of the Search Results view.
 **/
void
gva_main_set_last_selected_match (const gchar *column_name,
                                  const gchar *search_text)
{
        GConfClient *client;
        GError *error = NULL;

        if (column_name == NULL)
                column_name = "";

        if (search_text == NULL)
                search_text = "";

        client = gconf_client_get_default ();
        gconf_client_set_pair (
                client, GVA_GCONF_SELECTED_MATCH_KEY,
                GCONF_VALUE_STRING, GCONF_VALUE_STRING,
                &column_name, &search_text, &error);
        gva_error_handle (&error);
        g_object_unref (client);
}
Ejemplo n.º 15
0
/**
 * gva_mame_get_version_int:
 *
 * Returns the MAME version as a whole number for easy comparison.
 * For example, MAME version 0.123 is returned as 123.
 *
 * Returns: the MAME version as an integer
 **/
guint
gva_mame_get_version_int (void)
{
        static gsize regex_initialized;
        static GRegex *regex;
        GMatchInfo *match = NULL;
        gchar *string;
        guint version_int = 0;
        GError *error = NULL;

        if (g_once_init_enter (&regex_initialized))
        {
                /* MAME versions have been 0.xxx for nearly 20 years,
                 * so I think it's safe to disregard the leading zero. */
                regex = g_regex_new ("0\\.(\\d\\d\\d)", 0, 0, NULL);
                g_assert (regex != NULL);
                g_once_init_leave (&regex_initialized, 1);
        }

        string = gva_mame_get_version (&error);
        gva_error_handle (&error);

        if (string != NULL)
        {
                if (g_regex_match (regex, string, 0, &match))
                {
                        gchar *substring;

                        substring = g_match_info_fetch (match, 1);
                        version_int = (guint) strtoul (substring, NULL, 10);
                        g_free (substring);
                }

                g_free (string);
        }

        return version_int;
}
Ejemplo n.º 16
0
/**
 * gva_mame_has_config_value:
 * @config_key: a configuration key
 *
 * Returns %TRUE if the MAME configuration has a configuration value for
 * @config_key.  The function does not report errors that occur in the
 * course of spawning MAME, so false negatives are possible.
 *
 * Returns: %TRUE if a value for @config_key exists, %FALSE if no such
 *          value exists or if an error occurred
 **/
gboolean
gva_mame_has_config_value (const gchar *config_key)
{
        gchar *config_value;
        gboolean result;
        GError *error = NULL;

        config_value = gva_mame_get_config_value (config_key, &error);
        result = (config_value != NULL && *config_value != '\0');
        g_free (config_value);

        if (error != NULL)
        {
                /* Suppress warnings about unknown configuration
                 * keys, since that's what we're testing for. */
                if (error->code == GVA_ERROR_MAME)
                        g_clear_error (&error);
                else
                        gva_error_handle (&error);
        }

        return result;
}
Ejemplo n.º 17
0
static void
audit_show_dialog (GvaProcess *process,
                   gint status,
                   GvaAuditData *data)
{
    GtkTreeView *view;
    GtkTreeModel *model;
    GError *error = NULL;

    if (process->error != NULL)
        return;

    model = audit_build_model (data, &error);
    gva_error_handle (&error);
    if (model == NULL)
        return;

    view = GTK_TREE_VIEW (GVA_WIDGET_AUDIT_TREE_VIEW);
    gtk_tree_view_set_model (view, model);

    if (gtk_tree_model_iter_n_children (model, NULL) > 0)
        gtk_window_present (GTK_WINDOW (GVA_WIDGET_AUDIT_WINDOW));
}
Ejemplo n.º 18
0
gint
main (gint argc, gchar **argv)
{
        GtkApplication *application;
        GApplicationFlags flags;
        gchar *path;
        GError *error = NULL;

        bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);

        gtk_init_with_args (
                &argc, &argv, NULL, entries, GETTEXT_PACKAGE, &error);
        if (error != NULL)
                g_error ("%s", error->message);

        /* This installs handlers for our custom debug log levels. */
        gva_get_debug_flags ();

        /* Change the working directory to that of the MAME executable.
         * Why?  Because SDLMAME's default configuration uses relative
         * search paths such as "rompath = roms".  The paths are relative
         * to the directory containing the MAME executable, so we must run
         * from that directory in order for SDLMAME's default configuration
         * to work.  Annoying, but a common problem for users. */
        path = g_path_get_dirname (MAME_PROGRAM);
        g_chdir (path);
        g_free (path);

        if (opt_inspect != NULL)
        {
                gchar *value;

                value = gva_mame_get_config_value (opt_inspect, &error);
                if (value != NULL)
                {
                        g_print ("%s\n", value);
                        g_free (value);
                }
                else
                {
                        g_printerr ("%s\n", error->message);
                        g_clear_error (&error);
                }
                exit (EXIT_SUCCESS);
        }

        if (opt_version)
        {
                g_print ("%s\n", PACKAGE_STRING);
                exit (EXIT_SUCCESS);
        }

        if (opt_which_emulator)
        {
                g_print ("%s\n", MAME_PROGRAM);
                exit (EXIT_SUCCESS);
        }

        /* Register the application with the session bus. */
        flags = G_APPLICATION_FLAGS_NONE;
        application = gtk_application_new (APPLICATION_ID, flags);
        g_application_register (G_APPLICATION (application), NULL, &error);

        if (error != NULL)
                g_error ("%s", error->message);

        /* If another instance is running, exit now. */
        if (g_application_get_is_remote (G_APPLICATION (application)))
        {
                gint exit_status;

                if (opt_build_database)
                {
                        g_printerr (
                                "Cannot build database: "
                                PACKAGE_NAME " is already running\n");
                        exit_status = EXIT_FAILURE;
                }
                else
                {
                        g_application_activate (G_APPLICATION (application));
                        exit_status = EXIT_SUCCESS;
                }

                g_object_unref (application);

                exit (exit_status);
        }
        else
        {
                GtkWindow *window;

                window = GTK_WINDOW (GVA_WIDGET_MAIN_WINDOW);
                gtk_application_add_window (application, window);
        }

        gtk_window_set_default_icon_name (PACKAGE);

        if (!gva_db_init (&error))
                g_error ("%s", error->message);

        gva_main_init ();
        gva_play_back_init ();
        gva_preferences_init ();
        gva_properties_init ();
        gva_ui_init ();

        gva_categories_init (&error);
        gva_error_handle (&error);

        gva_history_init (&error);
        gva_error_handle (&error);

        gva_nplayers_init (&error);
        gva_error_handle (&error);

        g_idle_add (idle_start, NULL);

        g_idle_add (tweak_css, NULL);

        gtk_main ();

        g_object_unref (application);

        return EXIT_SUCCESS;
}
Ejemplo n.º 19
0
static gchar *
audit_run_save_dialog (void)
{
    const gchar *key = GVA_GCONF_ERROR_FILE_KEY;
    GtkFileChooser *file_chooser;
    GtkWidget *dialog;
    GConfClient *client;
    gchar *filename;
    gchar *folder;
    gchar *name;
    GError *error = NULL;

    client = gconf_client_get_default ();

    dialog = gtk_file_chooser_dialog_new (
                 _("Save As"),
                 GTK_WINDOW (GVA_WIDGET_AUDIT_WINDOW),
                 GTK_FILE_CHOOSER_ACTION_SAVE,
                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                 NULL);

    file_chooser = GTK_FILE_CHOOSER (dialog);

    /* Suggest the previous filename, if available. */

    filename = gconf_client_get_string (client, key, &error);
    gva_error_handle (&error);

    if (filename != NULL && *filename != '\0')
    {
        name = g_path_get_basename (filename);
        folder = g_path_get_dirname (filename);
    }
    else
    {
        name = g_strdup ("rom-errors.txt");
        folder = g_strdup (g_get_home_dir ());
    }

    gtk_file_chooser_set_current_folder (file_chooser, folder);
    gtk_file_chooser_set_current_name (file_chooser, name);
    gtk_file_chooser_set_do_overwrite_confirmation (file_chooser, TRUE);

    g_free (name);
    g_free (folder);
    g_free (filename);

    filename = NULL;

    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
    {
        filename = gtk_file_chooser_get_filename (file_chooser);
        gconf_client_set_string (client, key, filename, &error);
        gva_error_handle (&error);
    }

    gtk_widget_destroy (dialog);
    g_object_unref (client);

    return filename;
}
Ejemplo n.º 20
0
static void
play_back_add_input_file (const gchar *inpfile,
                          const gchar *name,
                          GvaGameStore *game_store)
{
        GtkTreeIter iter;
        gchar *comment = NULL;
        gchar **result = NULL;
        gchar *inpname;
        gchar *sql;
        gint rows;
        struct stat st;
        time_t *time;
        GError *error = NULL;

        if (g_stat (inpfile, &st) != 0)
        {
                g_warning ("%s: %s", inpfile, g_strerror (errno));
                return;
        }

        time = &st.st_ctime;

        /* Try to fetch the comment from the database. */
        sql = g_strdup_printf (
                "SELECT comment FROM playback WHERE "
                "name == '%s' AND inode == %" G_GINT64_FORMAT,
                name, (gint64) st.st_ino);
        if (gva_db_get_table (sql, &result, &rows, NULL, &error))
        {
                if (rows > 0)
                        comment = g_strdup (result[1]);
                g_strfreev (result);
        }
        gva_error_handle (&error);
        g_free (sql);

        /* If that fails, use the game title. */
        if (comment == NULL)
        {
                sql = g_strdup_printf (
                        "SELECT description FROM available "
                        "WHERE name == '%s'", name);
                if (gva_db_get_table (sql, &result, &rows, NULL, &error))
                {
                        if (rows > 0)
                                comment = g_strdup (result[1]);
                        g_strfreev (result);
                }
                gva_error_handle (&error);
                g_free (sql);
        }

        /* The game may not be available anymore. */
        if (comment == NULL)
        {
                g_warning ("%s: Game '%s' not found", inpfile, name);
                return;
        }

        gtk_tree_store_append (GTK_TREE_STORE (game_store), &iter, NULL);

        gtk_tree_store_set (
                GTK_TREE_STORE (game_store), &iter,
                GVA_GAME_STORE_COLUMN_NAME, name,
                GVA_GAME_STORE_COLUMN_COMMENT, comment,
                GVA_GAME_STORE_COLUMN_INODE, (gint64) st.st_ino,
                GVA_GAME_STORE_COLUMN_INPFILE, inpfile,
                GVA_GAME_STORE_COLUMN_TIME, time,
                -1);

        inpname = g_strdelimit (g_path_get_basename (inpfile), ".", '\0');
        gva_game_store_index_insert (game_store, inpname, &iter);
        g_free (inpname);

        g_free (comment);
}
Ejemplo n.º 21
0
static void
wnck_window_initialize (WnckWindow *window)
{
        const gchar *game;
        sqlite3_stmt *stmt;
        gchar *sql;
        gint errcode;
        gboolean success;
        GError *error = NULL;

        game = wnck_window_get_game (window);

        sql = g_strdup_printf (SQL_SELECT_GAME_WINDOW, game);
        success = gva_db_prepare (sql, &stmt, &error);
        gva_error_handle (&error);
        g_free (sql);

        if (!success)
                return;

        errcode = sqlite3_step (stmt);

        /* Restore the window's previous geometry. */
        if (errcode == SQLITE_ROW)
        {
                gint x, y;
                gint width, height;
                gboolean maximized;

                x = sqlite3_column_int (stmt, COLUMN_X);
                y = sqlite3_column_int (stmt, COLUMN_Y);
                width = sqlite3_column_int (stmt, COLUMN_WIDTH);
                height = sqlite3_column_int (stmt, COLUMN_HEIGHT);
                maximized = sqlite3_column_int (stmt, COLUMN_MAXIMIZED);

                wnck_window_set_geometry (
                        window, WNCK_WINDOW_GRAVITY_CURRENT,
                        WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y |
                        WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
                        x, y, width, height);

                if (maximized)
                        wnck_window_maximize (window);
                else
                        wnck_window_unmaximize (window);
        }

        /* Create a new record using the current geometry. */
        else if (errcode == SQLITE_DONE)
        {
                gint x, y;
                gint width, height;
                gboolean maximized;

                maximized = wnck_window_is_maximized (window);
                wnck_window_get_geometry (window, &x, &y, &width, &height);

                sql = g_strdup_printf (
                        "INSERT INTO window VALUES "
                        "('%s', %d, %d, %d, %d, %d)",
                        game, x, y, width, height, maximized);
                gva_db_execute (sql, &error);
                gva_error_handle (&error);
                g_free (sql);
        }

        /* Something went wrong. */
        else
        {
                gva_db_set_error (&error, 0, NULL);
                gva_error_handle (&error);
        }

        sqlite3_finalize (stmt);
}
Ejemplo n.º 22
0
/**
 * gva_play_back_window_hide_cb:
 * @window: the "Recorded Games" window
 *
 * Handler for #GtkWidget::hide signals to the "Recorded Games" window.
 *
 * Saves the contents of the "Recorded Games" tree view to the game database.
 **/
void
gva_play_back_window_hide_cb (GtkWindow *window)
{
        GtkTreeView *view;
        GtkTreeModel *model;
        GtkTreeIter iter;
        sqlite3_stmt *stmt;
        gboolean valid;
        GError *error = NULL;

        view = GTK_TREE_VIEW (GVA_WIDGET_PLAY_BACK_TREE_VIEW);
        model = gtk_tree_view_get_model (view);
        valid = gtk_tree_model_get_iter_first (model, &iter);

        if (!gva_db_transaction_begin (&error))
                goto exit;

        if (!gva_db_execute (SQL_DELETE_PLAY_BACK, &error))
                goto rollback;

        if (!gva_db_prepare (SQL_INSERT_PLAY_BACK, &stmt, &error))
                goto rollback;

        while (valid)
        {
                gchar *comment;
                gchar *name;
                gchar *utf8;
                gint64 inode;
                gint index;
                gint errcode;

                gtk_tree_model_get (
                        model, &iter,
                        GVA_GAME_STORE_COLUMN_NAME, &name,
                        GVA_GAME_STORE_COLUMN_INODE, &inode,
                        GVA_GAME_STORE_COLUMN_COMMENT, &comment,
                        -1);

                index = sqlite3_bind_parameter_index (stmt, "@name");
                utf8 = g_locale_to_utf8 (name, -1, NULL, NULL, &error);
                gva_error_handle (&error);

                if (utf8 == NULL)
                {
                        g_free (name);
                        g_free (comment);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                errcode = sqlite3_bind_text (stmt, index, utf8, -1, g_free);

                if (errcode != SQLITE_OK)
                {
                        g_free (name);
                        g_free (comment);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                index = sqlite3_bind_parameter_index (stmt, "@inode");
                errcode = sqlite3_bind_int64 (stmt, index, inode);

                if (errcode != SQLITE_OK)
                {
                        g_free (name);
                        g_free (comment);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                index = sqlite3_bind_parameter_index (stmt, "@comment");
                utf8 = g_locale_to_utf8 (comment, -1, NULL, NULL, &error);
                gva_error_handle (&error);

                if (utf8 == NULL)
                {
                        g_free (name);
                        g_free (comment);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                errcode = sqlite3_bind_text (stmt, index, utf8, -1, g_free);

                if (errcode != SQLITE_OK)
                {
                        g_free (name);
                        g_free (comment);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                g_free (name);
                g_free (comment);

                if (sqlite3_step (stmt) != SQLITE_DONE)
                {
                        gva_db_set_error (&error, 0, NULL);
                        gva_error_handle (&error);
                        sqlite3_finalize (stmt);
                        goto rollback;
                }

                sqlite3_reset (stmt);
                sqlite3_clear_bindings (stmt);

                valid = gtk_tree_model_iter_next (model, &iter);
        }

        sqlite3_finalize (stmt);

        if (!gva_db_transaction_commit (&error))
                goto rollback;

        goto exit;

rollback:
        gva_error_handle (&error);
        gva_db_transaction_rollback (&error);

exit:
        gva_error_handle (&error);
}
Ejemplo n.º 23
0
static void
rompath_changed_cb (GFileMonitor *monitor,
                    GFile *file,
                    GFile *other_file,
                    GFileMonitorEvent event_type)
{
        static GtkWidget *dialog = NULL;
        gint response;

        if (dialog != NULL)
                return;

        /* Filter out events we don't care about. */
        switch (event_type)
        {
                case G_FILE_MONITOR_EVENT_CHANGED:
                case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
                case G_FILE_MONITOR_EVENT_DELETED:
                case G_FILE_MONITOR_EVENT_CREATED:
                        break;
                default:
                        return;
        }

        dialog = gtk_message_dialog_new_with_markup (
                GTK_WINDOW (GVA_WIDGET_MAIN_WINDOW),
                GTK_DIALOG_DESTROY_WITH_PARENT,
                GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
                "<big><b>%s</b></big>",
                _("Changes detected in ROM files"));

        gtk_message_dialog_format_secondary_text (
                GTK_MESSAGE_DIALOG (dialog),
                _("GNOME Video Arcade has detected changes in your "
                  "ROM files and will need to audit them in order to "
                  "update the game list. However the audit may take "
                  "several minutes to complete. Would you like to "
                  "perform the audit now?\n\nIf you skip the audit now, "
                  "it will be performed automatically the next time you "
                  "start GNOME Video Arcade."));

        gtk_dialog_add_buttons (
                GTK_DIALOG (dialog),
                _("_Skip Audit"), GTK_RESPONSE_NO,
                _("_Audit ROM Files"), GTK_RESPONSE_YES,
                NULL);

        response = gtk_dialog_run (GTK_DIALOG (dialog));

        /* Don't destroy the dialog just yet.  If the file monitor
         * trips again while we're analyzing ROMs, we want the NULL
         * check at the top of the function to evaluate TRUE so we
         * return immediately. */
        gtk_widget_hide (dialog);

        if (response == GTK_RESPONSE_YES)
        {
                GError *error = NULL;

                gva_ui_lock ();

                gva_main_analyze_roms (&error);
                gva_error_handle (&error);

                gva_tree_view_update (&error);
                gva_error_handle (&error);

                gva_ui_unlock ();

                /* Present a helpful dialog if no ROMs were found. */
                warn_if_no_roms ();
        }
        else
        {
                /* Don't bother the user again during this session. */
                g_signal_handlers_disconnect_by_func (
                        monitor, rompath_changed_cb, NULL);
        }

        gtk_widget_destroy (dialog);
        dialog = NULL;
}