Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
config.c
Go to the documentation of this file.
1 /*
2  * config.c
3  * Copyright 2011 John Lindgren
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <glib.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include <libaudcore/audstrings.h>
26 #include <libaudcore/hook.h>
27 
28 #include "main.h"
29 #include "misc.h"
30 
31 #define DEFAULT_SECTION "audacious"
32 
33 static const char * const core_defaults[] = {
34 
35  /* general */
36  "advance_on_delete", "FALSE",
37  "clear_playlist", "TRUE",
38  "open_to_temporary", "TRUE",
39  "resume_playback_on_startup", "FALSE",
40  "show_interface", "TRUE",
41 
42  /* equalizer */
43  "eqpreset_default_file", "",
44  "eqpreset_extension", "",
45  "equalizer_active", "FALSE",
46  "equalizer_autoload", "FALSE",
47  "equalizer_bands", "0,0,0,0,0,0,0,0,0,0",
48  "equalizer_preamp", "0",
49 
50  /* info popup / info window */
51  "cover_name_exclude", "back",
52  "cover_name_include", "album,cover,front,folder",
53  "filepopup_delay", "5",
54  "filepopup_showprogressbar", "TRUE",
55  "recurse_for_cover", "FALSE",
56  "recurse_for_cover_depth", "0",
57  "show_filepopup_for_tuple", "TRUE",
58  "use_file_cover", "FALSE",
59 
60  /* network */
61  "use_proxy", "FALSE",
62  "use_proxy_auth", "FALSE",
63 
64  /* output */
65  "default_gain", "0",
66  "enable_replay_gain", "TRUE",
67  "enable_clipping_prevention", "TRUE",
68  "output_bit_depth", "16",
69  "output_buffer_size", "500",
70  "replay_gain_album", "FALSE",
71  "replay_gain_preamp", "0",
72  "soft_clipping", "FALSE",
73  "software_volume_control", "FALSE",
74  "sw_volume_left", "100",
75  "sw_volume_right", "100",
76 
77  /* playback */
78  "no_playlist_advance", "FALSE",
79  "repeat", "FALSE",
80  "shuffle", "FALSE",
81  "stop_after_current_song", "FALSE",
82 
83  /* playlist */
84 #ifdef _WIN32
85  "convert_backslash", "TRUE",
86 #else
87  "convert_backslash", "FALSE",
88 #endif
89  "generic_title_format", "${?artist:${artist} - }${?album:${album} - }${title}",
90  "leading_zero", "FALSE",
91  "metadata_on_play", "FALSE",
92  "show_numbers_in_pl", "FALSE",
93 
94  NULL};
95 
96 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
97 static GHashTable * defaults;
98 static GKeyFile * keyfile;
100 
101 void config_load (void)
102 {
103  g_return_if_fail (! defaults && ! keyfile);
104  pthread_mutex_lock (& mutex);
105 
106  defaults = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
107  (GDestroyNotify) g_hash_table_destroy);
108  keyfile = g_key_file_new ();
109 
110  char * path = g_strdup_printf ("%s/config", get_path (AUD_PATH_USER_DIR));
111  if (g_file_test (path, G_FILE_TEST_EXISTS))
112  {
113  GError * error = NULL;
114  if (! g_key_file_load_from_file (keyfile, path, 0, & error))
115  {
116  fprintf (stderr, "Error loading config: %s\n", error->message);
117  g_error_free (error);
118  }
119  }
120  g_free (path);
121 
122  modified = FALSE;
123  pthread_mutex_unlock (& mutex);
124 
126 }
127 
128 void config_save (void)
129 {
130  g_return_if_fail (defaults && keyfile);
131  pthread_mutex_lock (& mutex);
132 
133  if (! modified)
134  {
135  pthread_mutex_unlock (& mutex);
136  return;
137  }
138 
139  char * path = g_strdup_printf ("%s/config", get_path (AUD_PATH_USER_DIR));
140  char * data = g_key_file_to_data (keyfile, NULL, NULL);
141 
142  GError * error = NULL;
143  if (! g_file_set_contents (path, data, -1, & error))
144  {
145  fprintf (stderr, "Error saving config: %s\n", error->message);
146  g_error_free (error);
147  }
148 
149  g_free (data);
150  g_free (path);
151 
152  modified = FALSE;
153  pthread_mutex_unlock (& mutex);
154 }
155 
156 void config_cleanup (void)
157 {
158  g_return_if_fail (defaults && keyfile);
159  pthread_mutex_lock (& mutex);
160 
161  g_key_file_free (keyfile);
162  keyfile = NULL;
163  g_hash_table_destroy (defaults);
164  defaults = NULL;
165 
166  pthread_mutex_unlock (& mutex);
167 }
168 
169 void config_clear_section (const char * section)
170 {
171  g_return_if_fail (defaults && keyfile);
172  pthread_mutex_lock (& mutex);
173 
174  if (! section)
175  section = DEFAULT_SECTION;
176 
177  if (g_key_file_has_group (keyfile, section))
178  {
179  g_key_file_remove_group (keyfile, section, NULL);
180  modified = TRUE;
181  }
182 
183  pthread_mutex_unlock (& mutex);
184 }
185 
186 void config_set_defaults (const char * section, const char * const * entries)
187 {
188  g_return_if_fail (defaults && keyfile);
189  pthread_mutex_lock (& mutex);
190 
191  if (! section)
192  section = DEFAULT_SECTION;
193 
194  GHashTable * table = g_hash_table_lookup (defaults, section);
195  if (! table)
196  {
197  table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) str_unref);
198  g_hash_table_replace (defaults, g_strdup (section), table);
199  }
200 
201  while (1)
202  {
203  const char * name = * entries ++;
204  const char * value = * entries ++;
205  if (! name || ! value)
206  break;
207 
208  g_hash_table_replace (table, g_strdup (name), str_get (value));
209  }
210 
211  pthread_mutex_unlock (& mutex);
212 }
213 
214 static const char * get_default (const char * section, const char * name)
215 {
216  GHashTable * table = g_hash_table_lookup (defaults, section);
217  const char * def = table ? g_hash_table_lookup (table, name) : NULL;
218  return def ? def : "";
219 }
220 
221 void set_string (const char * section, const char * name, const char * value)
222 {
223  g_return_if_fail (defaults && keyfile);
224  g_return_if_fail (name && value);
225  pthread_mutex_lock (& mutex);
226 
227  if (! section)
228  section = DEFAULT_SECTION;
229 
230  const char * def = get_default (section, name);
231  bool_t changed = FALSE;
232 
233  if (! strcmp (value, def))
234  {
235  if (g_key_file_has_key (keyfile, section, name, NULL))
236  {
237  g_key_file_remove_key (keyfile, section, name, NULL);
238  changed = TRUE;
239  }
240  }
241  else
242  {
243  char * old = g_key_file_has_key (keyfile, section, name, NULL) ?
244  g_key_file_get_value (keyfile, section, name, NULL) : NULL;
245 
246  if (! old || strcmp (value, old))
247  {
248  g_key_file_set_value (keyfile, section, name, value);
249  changed = TRUE;
250  }
251 
252  g_free (old);
253  }
254 
255  if (changed)
256  {
257  modified = TRUE;
258 
259  if (! strcmp (section, DEFAULT_SECTION))
260  {
261  char * event = g_strdup_printf ("set %s", name);
262  event_queue (event, NULL);
263  g_free (event);
264  }
265  }
266 
267  pthread_mutex_unlock (& mutex);
268 }
269 
270 char * get_string (const char * section, const char * name)
271 {
272  g_return_val_if_fail (defaults && keyfile, g_strdup (""));
273  g_return_val_if_fail (name, g_strdup (""));
274  pthread_mutex_lock (& mutex);
275 
276  if (! section)
277  section = DEFAULT_SECTION;
278 
279  char * value = g_key_file_has_key (keyfile, section, name, NULL) ?
280  g_key_file_get_value (keyfile, section, name, NULL) : NULL;
281 
282  if (! value)
283  value = g_strdup (get_default (section, name));
284 
285  pthread_mutex_unlock (& mutex);
286  return value;
287 }
288 
289 void set_bool (const char * section, const char * name, bool_t value)
290 {
291  set_string (section, name, value ? "TRUE" : "FALSE");
292 }
293 
294 bool_t get_bool (const char * section, const char * name)
295 {
296  char * string = get_string (section, name);
297  bool_t value = ! strcmp (string, "TRUE");
298  g_free (string);
299  return value;
300 }
301 
302 void set_int (const char * section, const char * name, int value)
303 {
304  char * string = int_to_string (value);
305  g_return_if_fail (string);
306  set_string (section, name, string);
307  g_free (string);
308 }
309 
310 int get_int (const char * section, const char * name)
311 {
312  int value = 0;
313  char * string = get_string (section, name);
314  string_to_int (string, & value);
315  g_free (string);
316  return value;
317 }
318 
319 void set_double (const char * section, const char * name, double value)
320 {
321  char * string = double_to_string (value);
322  g_return_if_fail (string);
323  set_string (section, name, string);
324  g_free (string);
325 }
326 
327 double get_double (const char * section, const char * name)
328 {
329  double value = 0;
330  char * string = get_string (section, name);
331  string_to_double (string, & value);
332  g_free (string);
333  return value;
334 }
EXPORT bool_t string_to_int(const char *string, int *addr)
Definition: audstrings.c:427
static const char * get_default(const char *section, const char *name)
Definition: config.c:214
void config_clear_section(const char *section)
Definition: config.c:169
static bool_t modified
Definition: config.c:99
EXPORT bool_t string_to_double(const char *string, double *addr)
Definition: audstrings.c:454
char * get_string(const char *section, const char *name)
Definition: config.c:270
double get_double(const char *section, const char *name)
Definition: config.c:327
static GKeyFile * keyfile
Definition: config.c:98
void set_string(const char *section, const char *name, const char *value)
Definition: config.c:221
static GHashTable * table
Definition: strpool.c:34
void set_bool(const char *section, const char *name, bool_t value)
Definition: config.c:289
#define FALSE
Definition: core.h:35
Index Index bool_t
Definition: playlist-api.h:122
void config_set_defaults(const char *section, const char *const *entries)
Definition: config.c:186
const char * name
Definition: plugin-init.c:38
static const char *const core_defaults[]
Definition: config.c:33
#define NULL
Definition: core.h:27
static pthread_mutex_t mutex
Definition: config.c:96
void set_int(const char *section, const char *name, int value)
Definition: config.c:302
EXPORT char * int_to_string(int val)
Definition: audstrings.c:508
static GError * error
Definition: audctrl.c:30
void set_double(const char *section, const char *name, double value)
Definition: config.c:319
#define TRUE
Definition: core.h:37
void config_cleanup(void)
Definition: config.c:156
bool_t get_bool(const char *section, const char *name)
Definition: config.c:294
void str_unref(char *str)
Definition: strpool.c:89
const char * get_path(int id)
Definition: main.c:225
EXPORT char * double_to_string(double val)
Definition: audstrings.c:514
#define event_queue(n, d)
Definition: hook.h:44
static GHashTable * defaults
Definition: config.c:97
int get_int(const char *section, const char *name)
Definition: config.c:310
void config_load(void)
Definition: config.c:101
#define DEFAULT_SECTION
Definition: config.c:31
void config_save(void)
Definition: config.c:128
char * str_get(const char *str)
Definition: strpool.c:42