2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <booh@altern.org>
21 /***********************
22 * Configuration file. *
23 ***********************/
25 #include <unistd.h> /* R_OK */
26 #include <stdio.h> /* FILE, f*(), perror(), getline() */
27 #include <string.h> /* strlen(), memcpy() */
31 #include "../lib/getline.h"
34 static GHashTable
*table
= NULL
;
36 /* The link between options and the rcfile. */
37 static options_struct opts
= {
43 .zoom_pointer
= FALSE
,
54 const gboolean is_bool
;
58 static option_struct option_names
[] = {
59 /* To fill the hash table and the configuration file. */
60 { "full-screen", &opts
.fullscreen
, "Start in full screen mode", 1 },
61 { "maximize", &opts
.maximize
, "Maximize image to fit window", 1 },
62 { "menu", &opts
.menu_bar
, "Display the menu bar", 1 },
63 { "info", &opts
.status_bar
, "Show infos about current image", 1 },
64 { "zoom-pointer", &opts
.zoom_pointer
, "Zoom centered on pointer", 1 },
65 { "alpha_checks", &opts
.alpha_checks
, "Alpha checks in the background", 1 },
66 { "dither", &opts
.dither
, "Dithering", 1 },
67 { "delay", &opts
.delay
, "Delay before hiding the cursor", 0 },
68 { "history", &opts
.history_size
, "Length of history", 0 },
69 { NULL
, NULL
, NULL
, 0 }
74 * Maximum length of the option names, currently
75 * it is strlen("zoom-pointer") == 12.
76 * Used to indent the option file.
78 #define MAX_OPT_LEN 12
80 static gchar
*find_rcfile(gboolean test
)
84 path
= g_build_filename(g_get_home_dir(), ".glivrc", NULL
);
86 if (test
== FALSE
|| g_file_test(path
, G_FILE_TEST_EXISTS
) == TRUE
)
87 /* When loading the file, we really try to access it. */
88 /* When saving, we just need the filename. */
95 /*** Loading options. ***/
97 static void init_hash_table(void)
101 table
= g_hash_table_new(g_str_hash
, g_str_equal
);
103 /* (i + 1), because 0 is when no option is found, not the first option. */
104 for (i
= 0; option_names
[i
].name
!= NULL
; i
++)
105 g_hash_table_insert(table
, (gchar
*) option_names
[i
].name
,
106 GINT_TO_POINTER(i
+ 1));
109 /* Processes spaces and '#'. */
110 static gchar
*clean_str(gchar
* str
)
115 new_str
= g_new(gchar
, strlen(str
) + 1);
117 for (ptr
= new_str
; *str
!= '\n'; str
++) {
131 new_str
= g_renew(gchar
, new_str
, ptr
- new_str
+ 1);
135 static void process_line(gchar
* str
)
142 /* Skip this line. */
145 clean
= clean_str(str
);
147 /* This line is a '#' comment. */
150 /* res[0] : option name ; res[1] : value */
151 res
= g_strsplit(clean
, "=", 2);
155 if (res
[0] != NULL
&& res
[1] != NULL
&& res
[2] == NULL
) {
156 /* No error during split. */
157 hash_index
= GPOINTER_TO_INT(g_hash_table_lookup(table
, res
[0]));
159 if (hash_index
!= 0) {
163 if (option_names
[hash_index
].is_bool
== TRUE
) {
165 if (g_strcasecmp(res
[1], "true") == 0)
166 *(option_names
[hash_index
].option
) = TRUE
;
168 else if (g_strcasecmp(res
[1], "false") == 0)
169 *(option_names
[hash_index
].option
) = FALSE
;
172 /* option_names[hash_index].is_bool == FALSE */
173 *(option_names
[hash_index
].option
) =
174 (gint
) g_strtod(res
[1], NULL
);
181 options_struct
*load_rc(gboolean from_file
)
188 if (from_file
== FALSE
)
193 filename
= find_rcfile(TRUE
);
194 if (filename
== NULL
)
197 file
= fopen(filename
, "r");
200 * Not very frequent because find_rcfile(TRUE)
201 * should have made us return.
208 getline(&line
, &nb
, file
);
220 g_hash_table_destroy(table
);
225 /*** Saving options. ***/
227 static void write_option_line(FILE * f
, gint index
)
232 fputs(option_names
[index
].name
, f
);
234 for (i
= strlen(option_names
[index
].name
); i
< MAX_OPT_LEN
; i
++)
237 value
= *(option_names
[index
].option
);
239 if (value
!= 0 && option_names
[index
].is_bool
== FALSE
)
240 fprintf(f
, " = %d\n\n", value
);
242 fprintf(f
, " = %s\n\n", (value
== TRUE
? "True" : "False"));
245 static void write_rc(gchar
* filename
)
250 file
= fopen(filename
, "w");
256 fprintf(file
, "# Configuration file for GLiv %s\n\n", VERSION
);
257 fputs("# Option names are case sensitive.\n", file
);
258 fputs("# Option values are case insensitive.\n", file
);
259 fputs("# Note : 'maximize = True' implies 'full-screen = True'.\n\n", file
);
261 for (i
= 0; option_names
[i
].name
!= NULL
; i
++) {
262 /* The comment line. */
263 fprintf(file
, "# %s\n", option_names
[i
].comment
);
265 /* The option line. */
266 write_option_line(file
, i
);
273 void save_rc(options_struct
* opt
)
275 memcpy(&opts
, opt
, sizeof(options_struct
));
276 write_rc(find_rcfile(FALSE
));