1
2 /*
3 * The Real SoundTracker - Preferences handling
4 *
5 * Copyright (C) 1998-2019 Michael Krause
6 * Copyright (C) 2000 Fabian Giesen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #include <config.h>
24
25 #if !defined(_WIN32)
26
27 #include <sys/stat.h>
28
29 #include <glib/gi18n.h>
30
31 #include "gui-subs.h"
32 #include "preferences.h"
33
34 static GKeyFile* kf = NULL;
35 static gchar* config;
36
37 gchar*
prefs_get_prefsdir(void)38 prefs_get_prefsdir(void)
39 {
40 static gchar xdir[PATH_MAX]; /* Assume that $HOME is sane */
41 const gchar* homedir = g_getenv("HOME");
42
43 if (!homedir)
44 homedir = g_get_home_dir();
45 sprintf(xdir, "%s/.soundtracker", homedir);
46 return (xdir);
47 }
48
49 static void
prefs_check_prefs_dir(void)50 prefs_check_prefs_dir(void)
51 {
52 struct stat st;
53 static GtkWidget* dialog = NULL;
54 gchar* dir = prefs_get_prefsdir();
55
56 if (stat(dir, &st) < 0) {
57 mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR);
58 strcat(dir, "/tmp");
59 mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR);
60 gui_info_dialog(&dialog, _("A directory called \".soundtracker\" has been created in your\nhome directory to store configuration files.\n"), FALSE);
61 }
62 }
63
64 gchar*
prefs_get_filename(const gchar * name)65 prefs_get_filename(const gchar* name)
66 {
67 gchar* buf;
68
69 prefs_check_prefs_dir();
70 buf = g_strdup_printf("%s/%s", prefs_get_prefsdir(), name);
71 return buf;
72 }
73
prefs_init(void)74 void prefs_init(void)
75 {
76 GError* error;
77
78 config = prefs_get_filename("config");
79 kf = g_key_file_new();
80
81 /* Don't panic, this loop will be executed no more than 2 times */
82 while (1) {
83 error = NULL;
84 g_key_file_load_from_file(kf, config, G_KEY_FILE_NONE, &error);
85 if (error) {
86 if (error->code == G_FILE_ERROR_NOENT) {
87 gchar* buf = prefs_get_filename("settings"); /* maybe ST-gtk1 configs exist */
88
89 if (g_file_test(buf, G_FILE_TEST_EXISTS)) {
90 if (gui_ok_cancel_modal(NULL, _("Would you like to import settings from old version of Soundtracker?"))) {
91 GError* err = NULL;
92
93 if (!g_spawn_command_line_sync("soundtracker_convert_config -f", NULL, NULL, NULL, &err)) {
94 gchar* buff = g_strdup_printf(_("An error is occured during converting config:\n%s"), error->message);
95 static GtkWidget* dialog = NULL;
96
97 gui_error_dialog(&dialog, buff, TRUE);
98 g_free(buff);
99 g_error_free(err);
100 } else {
101 g_free(buf);
102 g_error_free(error);
103 continue; /* Try to load config after the conversion */
104 }
105 }
106 }
107 g_free(buf);
108 } else {
109 gchar* buf = g_strdup_printf(_("An error is occured during reading or parsing config:\n%s"), error->message);
110 static GtkWidget* dialog = NULL;
111
112 gui_error_dialog(&dialog, buf, TRUE);
113 g_free(buf);
114 }
115 g_error_free(error);
116 }
117 /* The second attempt is not required */
118 break;
119 }
120 }
121
prefs_save(void)122 void prefs_save(void)
123 {
124 gchar* contents;
125 gsize length;
126 GError* error = NULL;
127
128 g_assert(kf != NULL);
129
130 contents = g_key_file_to_data(kf, &length, NULL);
131 g_file_set_contents(config, contents, length, &error);
132 if (error) {
133 gchar* buf = g_strdup_printf(_("An error is occured during saving config:\n%s"), error->message);
134 static GtkWidget* dialog = NULL;
135
136 gui_error_dialog(&dialog, buf, TRUE);
137 g_free(buf);
138 g_error_free(error);
139 }
140
141 g_free(contents);
142 }
143
prefs_close(void)144 void prefs_close(void)
145 {
146 g_assert(kf != NULL);
147
148 g_key_file_free(kf);
149 kf = NULL;
150 g_free(config);
151 }
152
153 gboolean
prefs_remove_key(const gchar * section,const gchar * key)154 prefs_remove_key(const gchar* section, const gchar* key)
155 {
156 g_assert(kf != NULL);
157
158 return g_key_file_remove_key(kf, section, key, NULL);
159 }
160
161 gchar**
prefs_get_str_array(const gchar * section,const gchar * key,gsize * length)162 prefs_get_str_array(const gchar* section,
163 const gchar* key,
164 gsize* length)
165 {
166 gchar** ret;
167 GError* error = NULL;
168
169 g_assert(kf != NULL);
170
171 ret = g_key_file_get_string_list(kf, section, key, length, &error);
172 if (error) {
173 ret = NULL;
174 g_error_free(error);
175 }
176
177 return ret;
178 }
179
prefs_get_int_array(const gchar * section,const gchar * key,gsize * length)180 gint* prefs_get_int_array(const gchar* section,
181 const gchar* key,
182 gsize* length)
183 {
184 gint* ret;
185 GError* error = NULL;
186
187 g_assert(kf != NULL);
188
189 ret = g_key_file_get_integer_list(kf, section, key, length, &error);
190 if (error) {
191 ret = NULL;
192 g_error_free(error);
193 }
194
195 return ret;
196 }
197
198 gboolean*
prefs_get_bool_array(const gchar * section,const gchar * key,gsize * length)199 prefs_get_bool_array(const gchar* section,
200 const gchar* key,
201 gsize* length)
202 {
203 gboolean* ret;
204 GError* error = NULL;
205
206 g_assert(kf != NULL);
207
208 ret = g_key_file_get_boolean_list(kf, section, key, length, &error);
209 if (error) {
210 g_error_free(error);
211 error = NULL;
212 /* Try to read values as integer list; maybe the config is from elder version */
213 ret = (gboolean*)g_key_file_get_integer_list(kf, section, key, length, &error);
214 if (error) {
215 ret = NULL;
216 g_error_free(error);
217 }
218 }
219
220 return ret;
221 }
222
prefs_get_int(const gchar * section,const gchar * key,const gint dflt)223 gint prefs_get_int(const gchar* section,
224 const gchar* key,
225 const gint dflt)
226 {
227 gint retval;
228
229 GError* error = NULL;
230
231 g_assert(kf != NULL);
232
233 retval = g_key_file_get_integer(kf, section, key, &error);
234 if (error) {
235 retval = dflt;
236 g_error_free(error);
237 }
238
239 return retval;
240 }
241
prefs_get_double(const gchar * section,const gchar * key,const gdouble dflt)242 gdouble prefs_get_double(const gchar* section,
243 const gchar* key,
244 const gdouble dflt)
245 {
246 gdouble retval;
247
248 GError* error = NULL;
249
250 g_assert(kf != NULL);
251
252 retval = g_key_file_get_double(kf, section, key, &error);
253 if (error) {
254 retval = dflt;
255 g_error_free(error);
256 }
257
258 return retval;
259 }
260
261 gboolean
prefs_get_bool(const gchar * section,const gchar * key,const gboolean dflt)262 prefs_get_bool(const gchar* section,
263 const gchar* key,
264 const gboolean dflt)
265 {
266 gboolean retval;
267
268 GError* error = NULL;
269
270 g_assert(kf != NULL);
271
272 retval = g_key_file_get_boolean(kf, section, key, &error);
273 if (error) {
274 g_error_free(error);
275 error = NULL;
276 /* Try to read values as integer; maybe the config is from elder version */
277 retval = g_key_file_get_integer(kf, section, key, &error);
278 if (error) {
279 retval = dflt;
280 g_error_free(error);
281 }
282 }
283
284 return retval;
285 }
286
287 GdkColor
prefs_get_color(const gchar * section,const gchar * key,const GdkColor dflt)288 prefs_get_color(const gchar* section,
289 const gchar* key,
290 const GdkColor dflt)
291 {
292 gint* retval;
293 GdkColor ret;
294 gsize size;
295
296 GError* error = NULL;
297
298 g_assert(kf != NULL);
299
300 retval = g_key_file_get_integer_list(kf, section, key, &size, &error);
301 if (error || size < 3) {
302 ret.red = dflt.red;
303 ret.green = dflt.green;
304 ret.blue = dflt.blue;
305 g_error_free(error);
306 } else {
307 ret.red = retval[0];
308 ret.green = retval[1];
309 ret.blue = retval[2];
310 g_free(retval);
311 }
312
313 ret.pixel = 0;
314 return ret;
315 }
316
317 gchar*
prefs_get_string(const gchar * section,const gchar * key,const gchar * dflt)318 prefs_get_string(const gchar* section,
319 const gchar* key,
320 const gchar* dflt)
321 {
322 gchar* retval;
323
324 GError* error = NULL;
325
326 g_assert(kf != NULL);
327
328 retval = g_key_file_get_string(kf, section, key, &error);
329 if (error) {
330 if (dflt)
331 retval = g_strdup(dflt);
332 else
333 retval = NULL;
334
335 g_error_free(error);
336 }
337
338 return retval;
339 }
340
prefs_get_pairs(const gchar * section,gchar *** keys,gchar *** values)341 gsize prefs_get_pairs(const gchar* section,
342 gchar*** keys,
343 gchar*** values)
344 {
345 gsize lgth;
346 guint i;
347 GError* error = NULL;
348 gchar **ks, **vs;
349
350 g_assert(kf != NULL);
351
352 ks = g_key_file_get_keys(kf, section, &lgth, &error);
353 if (error) {
354 g_error_free(error);
355 return 0;
356 }
357
358 vs = g_new0(gchar*, lgth + 1); /* +1 for terminating NULL */
359
360 for (i = 0; i < lgth; i++) {
361 vs[i] = g_key_file_get_string(kf, section, ks[i], &error);
362 if (error) {
363 g_strfreev(ks);
364 g_strfreev(vs);
365 g_error_free(error);
366 return 0;
367 }
368 }
369
370 *keys = ks;
371 *values = vs;
372 return lgth;
373 }
374
prefs_put_int(const gchar * section,const gchar * key,const gint value)375 void prefs_put_int(const gchar* section,
376 const gchar* key,
377 const gint value)
378 {
379 g_assert(kf != NULL);
380
381 g_key_file_set_integer(kf, section, key, value);
382 }
383
prefs_put_double(const gchar * section,const gchar * key,const gdouble value)384 void prefs_put_double(const gchar* section,
385 const gchar* key,
386 const gdouble value)
387 {
388 g_assert(kf != NULL);
389
390 g_key_file_set_double(kf, section, key, value);
391 }
392
prefs_put_bool(const gchar * section,const gchar * key,const gboolean value)393 void prefs_put_bool(const gchar* section,
394 const gchar* key,
395 const gboolean value)
396 {
397 g_assert(kf != NULL);
398
399 g_key_file_set_boolean(kf, section, key, value);
400 }
401
prefs_put_color(const gchar * section,const gchar * key,const GdkColor value)402 void prefs_put_color(const gchar* section,
403 const gchar* key,
404 const GdkColor value)
405 {
406 gint val[3];
407
408 g_assert(kf != NULL);
409
410 val[0] = value.red;
411 val[1] = value.green;
412 val[2] = value.blue;
413
414 g_key_file_set_integer_list(kf, section, key, val, 3);
415 }
416
prefs_put_string(const gchar * section,const gchar * key,const gchar * value)417 void prefs_put_string(const gchar* section,
418 const gchar* key,
419 const gchar* value)
420 {
421 g_assert(kf != NULL);
422
423 g_key_file_set_string(kf, section, key, value);
424 }
425 /*
426 void
427 prefs_put_str_array (const gchar *section,
428 const gchar *key,
429 const gchar * const *value,
430 gsize length)
431 {
432 g_assert(kf != NULL);
433
434 g_key_file_set_string_list(kf, section, key, value, length);
435 }
436 */
prefs_put_int_array(const gchar * section,const gchar * key,gint * value,gsize length)437 void prefs_put_int_array(const gchar* section,
438 const gchar* key,
439 gint* value,
440 gsize length)
441 {
442 g_assert(kf != NULL);
443
444 g_key_file_set_integer_list(kf, section, key, value, length);
445 }
446
prefs_put_bool_array(const gchar * section,const gchar * key,gboolean * value,gsize length)447 void prefs_put_bool_array(const gchar* section,
448 const gchar* key,
449 gboolean* value,
450 gsize length)
451 {
452 g_assert(kf != NULL);
453
454 g_key_file_set_boolean_list(kf, section, key, value, length);
455 }
456
457 #else /* defined(_WIN32) */
458
459 /*
460
461 Attention!
462
463 These don't work in their current form; what needs to be done is:
464
465 a, change void* into prefs_node*
466 b, add prefs_get_file_pointer() - if this is used by the caller
467 after opening, use a real file instead of the registry.
468
469 */
470
471 #include <glib/gi18n.h>
472 #include <stdio.h>
473 #include <stdlib.h>
474 #include <string.h>
475
476 #include <sys/stat.h>
477 #include <sys/types.h>
478
479 #define WIN32_LEAN_AND_MEAN
480 #include <windows.h>
481
482 #include "errors.h"
483 #include "gui-subs.h"
484 #include "preferences.h"
485 #include "scope-group.h"
486 #include "track-editor.h"
487
prefs_open_read(const char * name)488 void* prefs_open_read(const char* name)
489 {
490 char buf[256];
491 HKEY hk;
492
493 sprintf(buf, "Software/Soundtracker/Soundtracker/%s", name);
494
495 while (strchr(buf, '/'))
496 *strchr(buf, '/') = '\\';
497
498 if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, KEY_ALL_ACCESS, &hk))
499 hk = 0;
500
501 return (void*)hk;
502 }
503
prefs_open_write(const char * name)504 void* prefs_open_write(const char* name)
505 {
506 char buf[256];
507 HKEY hk;
508 DWORD bla;
509
510 sprintf(buf, "Software/Soundtracker/Soundtracker/%s", name);
511
512 while (strchr(buf, '/'))
513 *strchr(buf, '/') = '\\';
514
515 if (!RegCreateKeyEx(HKEY_LOCAL_MACHINE, buf, 0, 0, 0, KEY_ALL_ACCESS, 0, &hk, &bla))
516 hk = 0;
517
518 return (void*)hk;
519 }
520
prefs_close(void * node)521 void prefs_close(void* node)
522 {
523 HKEY hk;
524
525 hk = (HKEY)node;
526
527 RegFlushKey(hk);
528 RegCloseKey(hk);
529 }
530
531 static int
prefs_query_reg(HKEY hk,const char * key,char ** buf,DWORD * size,DWORD * type)532 prefs_query_reg(HKEY hk,
533 const char* key,
534 char** buf,
535 DWORD* size,
536 DWORD* type)
537 {
538 if (RegQueryValueEx(hk, key, 0, type, 0, size) == ERROR_SUCCESS) {
539 *buf = (char*)malloc(*size + 1);
540
541 if (RegQueryValueEx(hk, key, 0, type, *buf, size) == ERROR_SUCCESS)
542 return 1;
543 else {
544 free(*buf);
545 return 0;
546 }
547 } else
548 return 0;
549 }
550
551 static void
prefs_set_reg(HKEY hk,const char * key,char * buf,DWORD size,DWORD type)552 prefs_set_reg(HKEY hk,
553 const char* key,
554 char* buf,
555 DWORD size,
556 DWORD type)
557 {
558 RegSetValueEx(hk, key, 0, type, buf, size);
559 }
560
561 gboolean
prefs_get_int(void * f,const char * key,int * dest)562 prefs_get_int(void* f,
563 const char* key,
564 int* dest)
565 {
566 char* buf;
567 DWORD sz, type;
568 HKEY hk;
569
570 hk = (HKEY)f;
571
572 if (prefs_query_reg(hk, key, &buf, &sz, &type)) {
573 if (type == REG_DWORD) {
574 *dest = *((DWORD*)buf);
575 free(buf);
576 return 1;
577 }
578 }
579
580 return 0;
581 }
582
583 gboolean
prefs_get_string(void * f,const char * key,char * dest)584 prefs_get_string(void* f,
585 const char* key,
586 char* dest)
587 {
588 char* buf;
589 DWORD sz, type;
590 HKEY hk;
591
592 hk = (HKEY)f;
593
594 if (prefs_query_reg(hk, key, &buf, &sz, &type)) {
595 if (type == REG_SZ) {
596 buf[127] = 0;
597 strcpy(dest, buf);
598 free(buf);
599 return 1;
600 }
601 }
602
603 return 0;
604 }
605
prefs_put_int(void * f,const char * key,int value)606 void prefs_put_int(void* f,
607 const char* key,
608 int value)
609 {
610 prefs_set_reg((HKEY)f, key, &value, 4, REG_DWORD);
611 }
612
prefs_put_string(void * f,const char * key,const char * value)613 void prefs_put_string(void* f,
614 const char* key,
615 const char* value)
616 {
617 prefs_set_reg((HKEY)f, key, value, strlen(value + 1), REG_SZ);
618 }
619
620 #endif /* defined(_WIN32) */
621