00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <glib.h>
00023 #include <stdio.h>
00024
00025 #include <libaudcore/audstrings.h>
00026 #include <libaudcore/eventqueue.h>
00027 #include <libaudcore/stringpool.h>
00028
00029 #include "main.h"
00030 #include "misc.h"
00031
00032 #define DEFAULT_SECTION "audacious"
00033
00034 static const gchar * const core_defaults[] = {
00035
00036
00037 "advance_on_delete", "FALSE",
00038 "clear_playlist", "TRUE",
00039 "open_to_temporary", "FALSE",
00040 "resume_playback_on_startup", "FALSE",
00041
00042
00043 "eqpreset_default_file", "",
00044 "eqpreset_extension", "",
00045 "equalizer_active", "FALSE",
00046 "equalizer_autoload", "FALSE",
00047 "equalizer_bands", "0,0,0,0,0,0,0,0,0,0",
00048 "equalizer_preamp", "0",
00049
00050
00051 "cover_name_exclude", "back",
00052 "cover_name_include", "album,folder",
00053 "filepopup_delay", "5",
00054 "filepopup_showprogressbar", "TRUE",
00055 "recurse_for_cover", "FALSE",
00056 "recurse_for_cover_depth", "0",
00057 "show_filepopup_for_tuple", "TRUE",
00058 "use_file_cover", "FALSE",
00059
00060
00061 "use_proxy", "FALSE",
00062 "use_proxy_auth", "FALSE",
00063
00064
00065 "default_gain", "0",
00066 "enable_replay_gain", "TRUE",
00067 "enable_clipping_prevention", "TRUE",
00068 "output_bit_depth", "16",
00069 "output_buffer_size", "500",
00070 "replay_gain_album", "FALSE",
00071 "replay_gain_preamp", "0",
00072 "software_volume_control", "FALSE",
00073 "sw_volume_left", "100",
00074 "sw_volume_right", "100",
00075
00076
00077 "no_playlist_advance", "FALSE",
00078 "repeat", "FALSE",
00079 "shuffle", "FALSE",
00080 "stop_after_current_song", "FALSE",
00081
00082
00083 "generic_title_format", "${?artist:${artist} - }${?album:${album} - }${title}",
00084 "leading_zero", "FALSE",
00085 "metadata_on_play", "FALSE",
00086 "show_numbers_in_pl", "TRUE",
00087
00088 NULL};
00089
00090 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
00091 static GHashTable * defaults;
00092 static GKeyFile * keyfile;
00093 static gboolean modified;
00094
00095 void config_load (void)
00096 {
00097 g_return_if_fail (! defaults && ! keyfile);
00098 g_static_mutex_lock (& mutex);
00099
00100 defaults = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
00101 (GDestroyNotify) g_hash_table_destroy);
00102 keyfile = g_key_file_new ();
00103
00104 gchar * path = g_strdup_printf ("%s/config", get_path (AUD_PATH_USER_DIR));
00105 if (g_file_test (path, G_FILE_TEST_EXISTS))
00106 {
00107 GError * error = NULL;
00108 if (! g_key_file_load_from_file (keyfile, path, 0, & error))
00109 {
00110 fprintf (stderr, "Error loading config: %s\n", error->message);
00111 g_error_free (error);
00112 }
00113 }
00114 g_free (path);
00115
00116 modified = FALSE;
00117 g_static_mutex_unlock (& mutex);
00118
00119 config_set_defaults (NULL, core_defaults);
00120 }
00121
00122 void config_save (void)
00123 {
00124 g_return_if_fail (defaults && keyfile);
00125 g_static_mutex_lock (& mutex);
00126
00127 if (! modified)
00128 {
00129 g_static_mutex_unlock (& mutex);
00130 return;
00131 }
00132
00133 gchar * path = g_strdup_printf ("%s/config", get_path (AUD_PATH_USER_DIR));
00134 gchar * data = g_key_file_to_data (keyfile, NULL, NULL);
00135
00136 GError * error = NULL;
00137 if (! g_file_set_contents (path, data, -1, & error))
00138 {
00139 fprintf (stderr, "Error saving config: %s\n", error->message);
00140 g_error_free (error);
00141 }
00142
00143 g_free (data);
00144 g_free (path);
00145
00146 modified = FALSE;
00147 g_static_mutex_unlock (& mutex);
00148 }
00149
00150 void config_cleanup (void)
00151 {
00152 g_return_if_fail (defaults && keyfile);
00153 g_static_mutex_lock (& mutex);
00154
00155 g_key_file_free (keyfile);
00156 keyfile = NULL;
00157 g_hash_table_destroy (defaults);
00158 defaults = NULL;
00159
00160 g_static_mutex_unlock (& mutex);
00161 }
00162
00163 void config_clear_section (const gchar * section)
00164 {
00165 g_return_if_fail (defaults && keyfile);
00166 g_static_mutex_lock (& mutex);
00167
00168 if (! section)
00169 section = DEFAULT_SECTION;
00170
00171 if (g_key_file_has_group (keyfile, section))
00172 {
00173 g_key_file_remove_group (keyfile, section, NULL);
00174 modified = TRUE;
00175 }
00176
00177 g_static_mutex_unlock (& mutex);
00178 }
00179
00180 void config_set_defaults (const gchar * section, const gchar * const * entries)
00181 {
00182 g_return_if_fail (defaults && keyfile);
00183 g_static_mutex_lock (& mutex);
00184
00185 if (! section)
00186 section = DEFAULT_SECTION;
00187
00188 GHashTable * table = g_hash_table_lookup (defaults, section);
00189 if (! table)
00190 {
00191 table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
00192 (GDestroyNotify) stringpool_unref);
00193 g_hash_table_replace (defaults, g_strdup (section), table);
00194 }
00195
00196 while (1)
00197 {
00198 const gchar * name = * entries ++;
00199 const gchar * value = * entries ++;
00200 if (! name || ! value)
00201 break;
00202
00203 g_hash_table_replace (table, g_strdup (name), stringpool_get ((gchar *) value, FALSE));
00204 }
00205
00206 g_static_mutex_unlock (& mutex);
00207 }
00208
00209 static const gchar * get_default (const gchar * section, const gchar * name)
00210 {
00211 GHashTable * table = g_hash_table_lookup (defaults, section);
00212 const gchar * def = table ? g_hash_table_lookup (table, name) : NULL;
00213 return def ? def : "";
00214 }
00215
00216 void set_string (const gchar * section, const gchar * name, const gchar * value)
00217 {
00218 g_return_if_fail (defaults && keyfile);
00219 g_return_if_fail (name && value);
00220 g_static_mutex_lock (& mutex);
00221
00222 if (! section)
00223 section = DEFAULT_SECTION;
00224
00225 const gchar * def = get_default (section, name);
00226 gboolean changed = FALSE;
00227
00228 if (! strcmp (value, def))
00229 {
00230 if (g_key_file_has_key (keyfile, section, name, NULL))
00231 {
00232 g_key_file_remove_key (keyfile, section, name, NULL);
00233 changed = TRUE;
00234 }
00235 }
00236 else
00237 {
00238 gchar * old = g_key_file_has_key (keyfile, section, name, NULL) ?
00239 g_key_file_get_value (keyfile, section, name, NULL) : NULL;
00240
00241 if (! old || strcmp (value, old))
00242 {
00243 g_key_file_set_value (keyfile, section, name, value);
00244 changed = TRUE;
00245 }
00246
00247 g_free (old);
00248 }
00249
00250 if (changed)
00251 {
00252 modified = TRUE;
00253
00254 if (! strcmp (section, DEFAULT_SECTION))
00255 {
00256 gchar * event = g_strdup_printf ("set %s", name);
00257 event_queue (event, NULL);
00258 g_free (event);
00259 }
00260 }
00261
00262 g_static_mutex_unlock (& mutex);
00263 }
00264
00265 gchar * get_string (const gchar * section, const gchar * name)
00266 {
00267 g_return_val_if_fail (defaults && keyfile, g_strdup (""));
00268 g_return_val_if_fail (name, g_strdup (""));
00269 g_static_mutex_lock (& mutex);
00270
00271 if (! section)
00272 section = DEFAULT_SECTION;
00273
00274 gchar * value = g_key_file_has_key (keyfile, section, name, NULL) ?
00275 g_key_file_get_value (keyfile, section, name, NULL) : NULL;
00276
00277 if (! value)
00278 value = g_strdup (get_default (section, name));
00279
00280 g_static_mutex_unlock (& mutex);
00281 return value;
00282 }
00283
00284 void set_bool (const gchar * section, const gchar * name, gboolean value)
00285 {
00286 set_string (section, name, value ? "TRUE" : "FALSE");
00287 }
00288
00289 gboolean get_bool (const gchar * section, const gchar * name)
00290 {
00291 gchar * string = get_string (section, name);
00292 gboolean value = ! strcmp (string, "TRUE");
00293 g_free (string);
00294 return value;
00295 }
00296
00297 void set_int (const gchar * section, const gchar * name, gint value)
00298 {
00299 gchar * string = int_to_string (value);
00300 g_return_if_fail (string);
00301 set_string (section, name, string);
00302 g_free (string);
00303 }
00304
00305 gint get_int (const gchar * section, const gchar * name)
00306 {
00307 gint value = 0;
00308 gchar * string = get_string (section, name);
00309 string_to_int (string, & value);
00310 g_free (string);
00311 return value;
00312 }
00313
00314 void set_double (const gchar * section, const gchar * name, gdouble value)
00315 {
00316 gchar * string = double_to_string (value);
00317 g_return_if_fail (string);
00318 set_string (section, name, string);
00319 g_free (string);
00320 }
00321
00322 gdouble get_double (const gchar * section, const gchar * name)
00323 {
00324 gdouble value = 0;
00325 gchar * string = get_string (section, name);
00326 string_to_double (string, & value);
00327 g_free (string);
00328 return value;
00329 }