chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mupmate / Preferences.C
CommitLineData
69695f33
MW
1/* Copyright (c) 2006 by Arkkra Enterprises */
2/* All rights reserved */
3
4// This file contains code for defining and using things
5// related to user configuration settings and preferences.
6
7#include <stdio.h>
8#include <string.h>
9#include <unistd.h>
10#include "globals.H"
11#include "utils.H"
12#include "Preferences.H"
13#include <FL/filename.H>
14
15// Access to the user preferences file
16Fl_Preferences * Preferences_p;
17
18// Preference names and default values
19const char * const Editor_font_preference = "editor_font";
20const char * const Default_editor_font = "Courier";
21
22const char * const Editor_size_preference = "editor_size";
23const char * const Default_editor_size = "12";
24
25const char * const Auto_display_preference = "auto_display";
26const int Default_auto_display = 0;
27
28const char * const Auto_save_preference = "auto_save";
29const int Default_auto_save = 1;
30
31const char * const Tooltips_delay_preference = "tooltips_delay";
32const double Default_tooltips_delay = 1.0;
33
34const char * const Mup_program_location = "Mup_program";
35const char * const Default_Mup_program_location = "mup";
36
37const char * const Mup_documentation_location = "Mup_documentation";
38#if defined(__WIN32)
39const char * const Default_Mup_documentation_location = "c:\\Program Files\\mupmate";
40#else
41const char * const Default_Mup_documentation_location = "/usr/share/doc/packages/mup";
42#endif
43
44const char * const Music_files_location = "Music_folder";
45const char * const Default_music_files_location = ".";
46
47const char * const MUPPATH_location = "MUPPATH";
48const char * const Default_MUPPATH_location = ".";
49
50const char * const Viewer_location = "Viewer";
51#if defined(__WIN32)
52const char * const Default_viewer_location = "c:\\Program Files\\Ghostgum\\gsview\\gsview32.exe";
53#else
54const char * const Default_viewer_location = "gv";
55#endif
56
57const char * const MIDI_player_location = "MIDI_player";
58#if defined(__WIN32)
59const char * const Default_MIDI_player_location = "c:\\Program Files\\Windows Media Player\\wmplayer.exe";
60#else
61const char * const Default_MIDI_player_location = "xplaymidi";
62#endif
63
64const char * const Showed_startup_hints = "showed_startup_hints";
65const int Default_startup_hints_flag = 0;
66
67// Name of User's Guide directory and index file
68// relative to Mup documentation directory.
69const char * uguide_directory = "uguide";
70#ifdef OS_LIKE_WIN32
71const char * uguide_filename = "index.htm";
72#else
73const char * uguide_filename = "index.html";
74#endif
75
76// Don't use un-readable tiny font, but especially avoid size of zero,
77// which could happen if preferences file contains a bad number, so that
78// atoi() returns zero. Keep max small enough to fit reasonable number
79// of characters in a window.
80const unsigned char Min_size = 5;
81const unsigned char Max_size = 30;
82
83// Minimum and default sizes for Main and Help browser windows.
84const int Min_width = 600;
85const int Default_width = 720;
86const int Min_height = 400;
87const int Default_height = 480;
88
89
90// If user hasn't specified any program yet to use for PostScript viewer
91// and/or MIDI file player, we try to deduce what they have available
92// that could be used, and set one of those as the default.
93
94// List of likely programs to use as PostScript viewers
95static const char * const viewer_candidates[] = {
96#if defined(__WIN32)
97 "GSview32",
98 "GSview",
99#else
100#ifdef OS_LIKE_UNIX
101 "gv",
102 "ghostview",
103#endif
104#endif
105 0
106};
107
108// List of likely programs to use as MIDI file players
109static const char * const player_candidates[] = {
110#if defined(__WIN32)
111 "wmplayer",
112 "mplayer",
113#else
114#ifdef OS_LIKE_UNIX
115 "xplaymidi",
116 "timidity",
117 "pmidi",
118 "playmidi",
119#endif
120#endif
121 0
122};
123
124
125// If the default preference value for a program location is no good,
126// try to find where it is.
127// pgm_location = the preference name of the program of interest
128// default_location = the default path to the program
129// file_suffix = .ps or .mod or .mup
130// Returns true if the preference value was updated.
131
132static bool
133deduce_location(const char * pgm_location, const char * default_location,
134 const char * file_suffix, const char * const * candidates)
135{
136 char * place; // a path to try for finding the pgm
137 char location[FL_PATH_MAX]; // full path to pgm when it is found
138
139 if (Preferences_p->get(pgm_location, place, default_location) != 0) {
140 // There was a value already set. Make sure it is good.
141 if (find_executable(place, location)) {
142 if (strcmp(place, location) != 0) {
143 // Must have started as relative path
144 // and now we know the full path.
145 (void) Preferences_p->set(pgm_location, location);
146 return(true);
147 }
148 else {
149 // Existing setting was okay as is.
150 return(false);
151 }
152 }
153 }
154
155#ifdef OS_LIKE_WIN32
156 // Try looking in the registry for what to use for
157 // files of this type.
158 if ((place = lookup_pgm_for_file_suffix(file_suffix)) != 0) {
159 (void) Preferences_p->set(place, default_location);
160 return(true);
161 }
162#endif
163
164 // If there had been nothing set, see if the default location is good.
165 if (find_executable(default_location, location)) {
166 (void) Preferences_p->set(pgm_location, location);
167 return(true);
168 }
169
170 // Try looking in the various educated guess locations.
171 if (candidates != 0) {
172 int i;
173 for (i = 0; candidates[i] != 0; i++) {
174 if (find_executable(candidates[i], location)) {
175 (void) Preferences_p->set(pgm_location, location);
176 return(true);
177 }
178 }
179 }
180
181 return(false);
182}
183
184
185// Returns true is the Mup User's Guide can be found at the given location.
186
187static bool
188doc_found(const char * location)
189{
190 return(access(users_guide_index_file(location), F_OK) == 0);
191}
192
193
194// Try to deduce where the Mup documentation is.
195// Returns true if updated the Preferences to point to new location.
196
197static bool
198deduce_documentation_location(const char * doc_location, const char * default_doc_location)
199{
200 char * place;
201 // First try the stored location, if any
202 if (Preferences_p->get(doc_location, place, default_doc_location) != 0) {
203 if (doc_found(place)) {
204 // Existing preference is good. No update needed.
205 return(false);
206 }
207 }
208
209 // Try default location
210 if (doc_found(default_doc_location)) {
211 Preferences_p->set(doc_location, default_doc_location);
212 return(true);
213 }
214
215 // Try relative to where Mup executable is.
216 char *muploc;
217 (void) Preferences_p->get(Mup_program_location, muploc,
218 Default_Mup_program_location);
219 char * basename_p;
220 if ((basename_p = strrchr(muploc, dir_separator())) != 0) {
221 int len = basename_p - muploc;
222 char mupdir[len + 1];
223 (void) strncpy(mupdir, muploc, len);
224 mupdir[len] = '\0';
225 if (doc_found(mupdir)) {
226 Preferences_p->set(doc_location, mupdir);
227 return(true);
228 }
229
230 // Try at ../docs from where mup executable was,
231 // since it could be there from unpacking tar file.
232 char * parentdir_p;
233 if ((parentdir_p = strrchr(mupdir, dir_separator())) != 0) {
234 len = parentdir_p - mupdir + 1;
235 // Add room for doc and terminator
236 char mupdocdir[len + 5];
237 (void) strncpy(mupdocdir, muploc, len);
238 (void) strcpy(mupdocdir + len, "docs");
239 if (doc_found(mupdocdir)) {
240 Preferences_p->set(doc_location, mupdocdir);
241 return(true);
242 }
243 }
244 }
245 return(false);
246}
247
248
249// This function attempts to find the locations of what we need,
250// like a PostScript viewer and MIDI player.
251
252void
253deduce_helper_locations(void)
254{
255 bool updated = false;
256
257 // First try to find a PostScript viewer
258 if (deduce_location(Viewer_location, Default_viewer_location, ".ps",
259 viewer_candidates)) {
260 updated = true;
261 }
262
263 // Next do MIDI player
264 if (deduce_location(MIDI_player_location, Default_MIDI_player_location,
265 ".mid", player_candidates)) {
266 updated = true;
267 }
268
269 // Find the Mup command itself
270 if (deduce_location(Mup_program_location, Default_Mup_program_location, ".mup", 0)) {
271 updated = true;
272 }
273
274 if (deduce_documentation_location(Mup_documentation_location,
275 Default_Mup_documentation_location)) {
276 updated = true;
277 }
278
279#ifdef OS_LIKE_WIN32
280 // Try to guess a good default place for Mup input files.
281 char * place;
282 if (Preferences_p->get(Music_files_location, place,
283 Default_music_files_location) == 0) {
284 if ((place = find_music_folder()) != 0) {
285 Preferences_p->set(Music_files_location, place);
286 updated = true;
287 }
288 }
289 // The same place is probably a good guess for Mup include files.
290 if (Preferences_p->get(MUPPATH_location, place,
291 Default_MUPPATH_location) == 0) {
292 if ((place = find_music_folder()) != 0) {
293 Preferences_p->set(MUPPATH_location, place);
294 updated = true;
295 }
296 }
297#endif
298
299 // If at least one better choice was found, update the persistent data.
300 if (updated) {
301 Preferences_p->flush();
302 }
303}
304
305
306// Given a path to Mup's documentation directory,
307// add on the name of the User's Guide index file.
308// Return that in a static area.
309
310const char *
311users_guide_index_file(const char * const doc_dir)
312{
313 static char file_path[FL_PATH_MAX];
314 (void) sprintf(file_path, "%s%c%s%c%s", doc_dir, dir_separator(),
315 uguide_directory, dir_separator(), uguide_filename);
316 return((const char *) file_path);
317}