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 <gfc@altern.org>
21 /***********************
22 * Configuration file. *
23 ***********************/
28 # include "../lib/getline.h"
31 #include <unistd.h> /* R_OK */
32 #include <stdio.h> /* FILE, f*(), perror(), getline() */
33 #include <string.h> /* strlen(), memcpy() */
35 static GHashTable
*table
= NULL
;
36 static gboolean options_read
= FALSE
;
38 /* The link between options and the rcfile. */
39 static options_struct opts
= {
47 .zoom_pointer
= FALSE
,
59 .alpha1
= {0x6666, 0x6666, 0x6666},
60 .alpha2
= {0x9999, 0x9999, 0x9999}
67 const gboolean is_bool
;
71 static option_struct option_names
[] = {
72 /* To fill the hash table and the configuration file. */
73 { "full-screen", &opts
.fullscreen
, N_("Start in full screen mode"), 1 },
74 { "maximize", &opts
.maximize
, N_("Maximize small images"), 1 },
75 { "scale-down", &opts
.scaledown
, N_("Scale down larges images"), 1 },
76 { "menu", &opts
.menu_bar
, N_("Display the menu bar"), 1 },
77 { "info", &opts
.status_bar
, N_("Display infos about the image"), 1 },
78 { "scrollbars", &opts
.scrollbars
, N_("Display scrollbars"), 1 },
79 { "zoom-pointer", &opts
.zoom_pointer
, N_("Zoom centered on pointer"), 1 },
80 { "alpha-checks", &opts
.alpha_checks
, N_("Alpha checks in the background"), 1 },
81 { "dither", &opts
.dither
, N_("Dithering"), 1 },
82 { "force-load", &opts
.force
, N_("Try to load every file"), 1 },
83 { "build-menus", &opts
.build_menus
, N_("Build images menus at startup"), 1 },
84 { "mipmap", &opts
.mipmap
, N_("Build Mipmaps"), 1 },
85 { "mnemonics", &opts
.mnemonics
, N_("Make mnemonics for images menus"),1 },
86 { "loop", &opts
.loop
, N_("Make the slide show loop"), 1 },
87 { "delay", &opts
.delay
, N_("Delay before hiding the cursor"), 0 },
88 { "history", &opts
.history_size
, N_("History length"), 0 },
89 { "slide-show", &opts
.duration
, N_("Delay between images"), 0 },
90 { "bg_col_red", opts
.bg_col
, N_("background: red channel"), 0 },
91 { "bg_col_green", opts
.bg_col
+ 1, N_("background: green channel"), 0 },
92 { "bg_col_blue", opts
.bg_col
+ 2, N_("background: blue channel"), 0 },
93 { "alpha1_red", opts
.alpha1
, N_("alpha1 tile: red channel"), 0 },
94 { "alpha1_green", opts
.alpha1
+ 1, N_("alpha1 tile: green channel"), 0 },
95 { "alpha1_blue", opts
.alpha1
+ 2, N_("alpha1 tile: blue channel"), 0 },
96 { "alpha2_red", opts
.alpha2
, N_("alpha2 tile: red channel"), 0 },
97 { "alpha2_green", opts
.alpha2
+ 1, N_("alpha2 tile: green channel"), 0 },
98 { "alpha2_blue", opts
.alpha2
+ 2, N_("alpha2 tile: blue channel"), 0 },
99 { NULL
, NULL
, NULL
, 0 }
104 * Maximum length of the option names, currently
105 * it is strlen("zoom-pointer") == 12.
106 * Used to indent the option file.
108 #define MAX_OPT_LEN 12
110 /* Between the options and the keyboard accelerators. */
111 #define SEPARATOR "==========\n"
113 static gchar
*find_rcfile(gboolean test
)
117 filename
= g_build_filename(g_get_home_dir(), ".glivrc", NULL
);
119 if (test
== FALSE
|| g_file_test(filename
, G_FILE_TEST_EXISTS
))
120 /* When loading the file, we really try to access it. */
121 /* When saving, we just need the filename. */
128 /*** Loading options. ***/
130 static void init_hash_table(void)
134 table
= g_hash_table_new(g_str_hash
, g_str_equal
);
136 for (i
= 0; option_names
[i
].name
!= NULL
; i
++)
137 g_hash_table_insert(table
, (gchar
*) option_names
[i
].name
,
141 /* Processes spaces and '#'. */
142 static gchar
*clean_str(const gchar
* str
)
147 new_str
= g_new(gchar
, strlen(str
) + 1);
149 for (ptr
= new_str
; *str
!= '\n' && *str
!= '\0'; str
++) {
163 new_str
= g_renew(gchar
, new_str
, ptr
- new_str
+ 1);
167 static void process_line(const gchar
* line
)
173 if (*line
== '\n' || *line
== '\0')
174 /* Skip this line. */
177 clean
= clean_str(line
);
179 /* This line is a '#' comment. */
182 /* res[0]: option name ; res[1]: value */
183 res
= g_strsplit(clean
, "=", 2);
187 if (res
[0] != NULL
&& res
[1] != NULL
&& res
[2] == NULL
) {
188 /* No error during split. */
189 opt
= g_hash_table_lookup(table
, res
[0]);
197 bool = (gboolean
*) opt
->option
;
198 *bool = g_strcasecmp(res
[1], "true") ? FALSE
: TRUE
;
200 /* opt->is_bool == FALSE */
201 *opt
->option
= (gint
) g_strtod(res
[1], NULL
);
208 options_struct
*load_rc(gboolean from_file
)
215 if (from_file
== FALSE
)
220 filename
= find_rcfile(TRUE
);
221 if (filename
== NULL
)
224 file
= fopen(filename
, "r");
227 * Not very frequent because find_rcfile(TRUE)
228 * should have made us return.
234 while (feof(file
) == 0) {
235 getline(&line
, &nb
, file
);
236 if (g_str_equal(line
, SEPARATOR
))
245 g_hash_table_destroy(table
);
251 void load_accelerators(void)
258 if (options_read
== FALSE
)
261 filename
= find_rcfile(TRUE
);
262 if (filename
== NULL
)
265 file
= fopen(filename
, "r");
271 while (getline(&line
, &nb
, file
) != -1 &&
272 g_str_equal(line
, SEPARATOR
) == FALSE
);
276 gtk_accel_map_load_fd(fileno(file
));
282 /*** Saving options. ***/
284 static void write_option_line(FILE * f
, gint index
)
288 fputs(option_names
[index
].name
, f
);
290 for (i
= strlen(option_names
[index
].name
); i
< MAX_OPT_LEN
; i
++)
293 value
= *(option_names
[index
].option
);
295 if (option_names
[index
].is_bool
)
296 fprintf(f
, " = %s\n\n", value
? "True" : "False");
298 fprintf(f
, " = %d\n\n", value
);
301 static void write_rc(gchar
* filename
)
306 file
= fopen(filename
, "w");
312 fprintf(file
, _("# Configuration file for GLiv %s\n\n"), VERSION
);
313 fputs(_("# Option names are case sensitive.\n"), file
);
314 fputs(_("# Option values are case insensitive.\n\n"), file
);
315 fputs(_("# Note: 'maximize = True' or 'scale-down = True'"
316 " implies 'full-screen = True'.\n\n"), file
);
318 for (i
= 0; option_names
[i
].name
!= NULL
; i
++) {
319 /* The comment line. */
320 fprintf(file
, "# %s\n", _(option_names
[i
].comment
));
322 /* The option line. */
323 write_option_line(file
, i
);
326 /* The separation between options and keyboard accelerators. */
327 fprintf(file
, "%s\n", SEPARATOR
);
330 gtk_accel_map_save_fd(fileno(file
));
336 void save_rc(options_struct
* opt
)
338 memcpy(&opts
, opt
, sizeof(options_struct
));
339 write_rc(find_rcfile(FALSE
));