added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / prefs / locale / prefs.c
blobec76aee996c739ae11341898d4a965dd8d383cc7
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*********************************************************************************************/
11 #include "global.h"
12 #include <aros/macros.h>
14 #define DEBUG 0
15 #include <aros/debug.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
21 /*********************************************************************************************/
23 struct FilePrefHeader
25 UBYTE ph_Version;
26 UBYTE ph_Type;
27 UBYTE ph_Flags[4];
30 /*********************************************************************************************/
32 static struct LocalePrefs restore_prefs;
33 static APTR mempool;
35 /*********************************************************************************************/
37 static void ScanDirectory(STRPTR pattern, struct List *list, LONG entrysize)
39 struct AnchorPath ap;
40 struct ListviewEntry *entry;
41 STRPTR sp;
42 LONG error;
44 memset(&ap, 0, sizeof(ap));
46 error = MatchFirst(pattern, &ap);
47 while((error == 0))
49 if (ap.ap_Info.fib_DirEntryType < 0)
51 entry = (struct ListviewEntry *)AllocPooled(mempool, entrysize);
52 if (entry)
54 entry->node.ln_Name = entry->name;
55 strncpy(entry->name, ap.ap_Info.fib_FileName, sizeof(entry->name));
57 entry->name[0] = ToUpper(entry->name[0]);
58 sp = strchr(entry->name, '.');
59 if (sp) sp[0] = '\0';
61 strcpy(entry->realname, entry->name);
63 sp = entry->name;
64 while((sp = strchr(sp, '_')))
66 sp[0] = ' ';
67 if (sp[1])
69 /* Make char after underscore uppercase only if no
70 more underscores follow */
71 if (strchr(sp, '_') == 0)
73 sp[1] = ToUpper(sp[1]);
77 SortInNode(list, &entry->node);
80 error = MatchNext(&ap);
82 MatchEnd(&ap);
85 /*********************************************************************************************/
87 static BOOL GetCountryFromDefLocale(struct CountryPrefs *country)
89 BOOL retval = FALSE;
91 if (LocaleBase)
93 struct Locale *loc = OpenLocale(NULL);
95 CloseLocale(loc);
98 return retval;
101 /*********************************************************************************************/
103 void InitPrefs(STRPTR filename, BOOL use, BOOL save)
105 struct LanguageEntry *entry;
107 NewList(&country_list);
108 NewList(&language_list);
109 NewList(&pref_language_list);
111 mempool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 2048, 2048);
112 if (!mempool) Cleanup("Out of memory!");
114 ScanDirectory("LOCALE:Countries/~(#?.info)", &country_list, sizeof(struct CountryEntry));
115 ScanDirectory("LOCALE:Languages/#?.language", &language_list, sizeof(struct LanguageEntry));
117 /* English language is always available */
119 if ((entry = AllocPooled(mempool, sizeof(struct LanguageEntry))))
121 strcpy(entry->lve.name, "English");
122 strcpy(entry->lve.realname, "English");
123 entry->lve.node.ln_Name = entry->lve.name;
125 SortInNode(&language_list, &entry->lve.node);
128 if (!LoadPrefs(filename))
130 if (!DefaultPrefs())
132 if (!GetCountryFromDefLocale(&localeprefs.lp_CountryData))
134 Cleanup("Panic! Cannot setup default prefs!");
139 restore_prefs = localeprefs;
141 if (use || save)
143 SavePrefs(CONFIGNAME_ENV);
146 if (save)
148 SavePrefs(CONFIGNAME_ENVARC);
151 if (use || save) Cleanup(NULL);
154 /*********************************************************************************************/
156 void CleanupPrefs(void)
158 if (mempool) DeletePool(mempool);
161 /*********************************************************************************************/
163 #if !AROS_BIG_ENDIAN
164 static void FixCountryEndianess(struct CountryPrefs *country)
166 country->cp_Reserved[0] = AROS_BE2LONG(country->cp_Reserved[0]);
167 country->cp_Reserved[1] = AROS_BE2LONG(country->cp_Reserved[1]);
168 country->cp_Reserved[2] = AROS_BE2LONG(country->cp_Reserved[2]);
169 country->cp_Reserved[3] = AROS_BE2LONG(country->cp_Reserved[3]);
170 country->cp_CountryCode = AROS_BE2LONG(country->cp_CountryCode);
172 #endif
174 /*********************************************************************************************/
176 #if !AROS_BIG_ENDIAN
177 static void FixLocaleEndianess(struct LocalePrefs *localeprefs)
179 localeprefs->lp_Reserved[0] = AROS_BE2LONG(localeprefs->lp_Reserved[0]);
180 localeprefs->lp_Reserved[1] = AROS_BE2LONG(localeprefs->lp_Reserved[1]);
181 localeprefs->lp_Reserved[2] = AROS_BE2LONG(localeprefs->lp_Reserved[2]);
182 localeprefs->lp_Reserved[3] = AROS_BE2LONG(localeprefs->lp_Reserved[3]);
183 localeprefs->lp_GMTOffset = AROS_BE2LONG(localeprefs->lp_GMTOffset);
184 localeprefs->lp_Flags = AROS_BE2LONG(localeprefs->lp_Flags);
186 #endif
188 /*********************************************************************************************/
190 BOOL LoadCountry(STRPTR name, struct CountryPrefs *country)
192 static struct CountryPrefs loadcountry;
193 struct IFFHandle *iff;
194 UBYTE fullname[100];
195 BOOL retval = FALSE;
197 strcpy(fullname, "LOCALE:Countries");
198 AddPart(fullname, name, 100);
199 strcat(fullname, ".country");
201 D(bug("LoadCountry: Trying to open \"%s\"\n", fullname));
203 if ((iff = AllocIFF()))
205 if ((iff->iff_Stream = (IPTR)Open(fullname, MODE_OLDFILE)))
207 D(bug("LoadCountry: stream opened.\n"));
209 InitIFFasDOS(iff);
211 if (!OpenIFF(iff, IFFF_READ))
213 D(bug("LoadCountry: OpenIFF okay.\n"));
215 if (!StopChunk(iff, ID_PREF, ID_CTRY))
217 D(bug("LoadCountry: StopChunk okay.\n"));
219 if (!ParseIFF(iff, IFFPARSE_SCAN))
221 struct ContextNode *cn;
223 D(bug("LoadCountry: ParseIFF okay.\n"));
225 cn = CurrentChunk(iff);
227 if (cn->cn_Size == sizeof(struct CountryPrefs))
229 D(bug("LoadCountry: ID_CTRY chunk size okay.\n"));
231 if (ReadChunkBytes(iff, &loadcountry, sizeof(struct CountryPrefs)) == sizeof(struct CountryPrefs))
233 D(bug("LoadCountry: Reading chunk successful.\n"));
235 *country = loadcountry;
237 #if !AROS_BIG_ENDIAN
238 FixCountryEndianess(country);
239 #endif
241 D(bug("LoadCountry: Everything okay :-)\n"));
243 retval = TRUE;
247 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
249 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
251 CloseIFF(iff);
253 } /* if (!OpenIFF(iff, IFFF_READ)) */
255 Close((BPTR)iff->iff_Stream);
257 } /* if ((iff->iff_Stream = (IPTR)Open(fullname, MODE_OLDFILE))) */
259 FreeIFF(iff);
261 } /* if ((iff = AllocIFF())) */
263 return retval;
266 /*********************************************************************************************/
268 BOOL LoadPrefs(STRPTR filename)
270 static struct LocalePrefs loadprefs;
271 struct IFFHandle *iff;
272 BOOL retval = FALSE;
274 D(bug("LoadPrefs: Trying to open \"%s\"\n", filename));
276 if ((iff = AllocIFF()))
278 if ((iff->iff_Stream = (IPTR)Open(filename, MODE_OLDFILE)))
280 D(bug("LoadPrefs: stream opened.\n"));
282 InitIFFasDOS(iff);
284 if (!OpenIFF(iff, IFFF_READ))
286 D(bug("LoadPrefs: OpenIFF okay.\n"));
288 if (!StopChunk(iff, ID_PREF, ID_LCLE))
290 D(bug("LoadPrefs: StopChunk okay.\n"));
292 if (!ParseIFF(iff, IFFPARSE_SCAN))
294 struct ContextNode *cn;
296 D(bug("LoadPrefs: ParseIFF okay.\n"));
298 cn = CurrentChunk(iff);
300 if (cn->cn_Size == sizeof(struct LocalePrefs))
302 D(bug("LoadPrefs: ID_LCLE chunk size okay.\n"));
304 if (ReadChunkBytes(iff, &loadprefs, sizeof(struct LocalePrefs)) == sizeof(struct LocalePrefs))
306 D(bug("LoadPrefs: Reading chunk successful.\n"));
308 TellGUI(PAGECMD_PREFS_CHANGING);
310 localeprefs = loadprefs;
312 #if !AROS_BIG_ENDIAN
313 FixLocaleEndianess(&localeprefs);
314 FixCountryEndianess(&localeprefs.lp_CountryData);
315 #endif
316 TellGUI(PAGECMD_PREFS_CHANGED);
318 D(bug("LoadPrefs: Everything okay :-)\n"));
320 retval = TRUE;
324 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
326 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
328 CloseIFF(iff);
330 } /* if (!OpenIFF(iff, IFFF_READ)) */
332 Close((BPTR)iff->iff_Stream);
334 } /* if ((iff->iff_Stream = (IPTR)Open(filename, MODE_OLDFILE))) */
336 FreeIFF(iff);
338 } /* if ((iff = AllocIFF())) */
340 return retval;
343 /*********************************************************************************************/
345 BOOL SavePrefs(STRPTR filename)
347 static struct LocalePrefs saveprefs;
348 struct IFFHandle *iff;
349 WORD i;
350 BOOL retval = FALSE, delete_if_error = FALSE;
352 saveprefs = localeprefs;
353 #if !AROS_BIG_ENDIAN
354 FixLocaleEndianess(&saveprefs);
355 FixCountryEndianess(&saveprefs.lp_CountryData);
356 #endif
358 for(i = 0; i < 10; i++)
360 saveprefs.lp_PreferredLanguages[i][0] = ToLower(saveprefs.lp_PreferredLanguages[i][0]);
363 D(bug("SavePrefs: Trying to open \"%s\"\n", filename));
365 if ((iff = AllocIFF()))
367 if ((iff->iff_Stream = (IPTR)Open(filename, MODE_NEWFILE)))
369 D(bug("SavePrefs: stream opened.\n"));
371 delete_if_error = TRUE;
373 InitIFFasDOS(iff);
375 if (!OpenIFF(iff, IFFF_WRITE))
377 D(bug("SavePrefs: OpenIFF okay.\n"));
379 if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
381 D(bug("SavePrefs: PushChunk(FORM) okay.\n"));
383 if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct FilePrefHeader)))
385 struct FilePrefHeader head;
387 D(bug("SavePrefs: PushChunk(PRHD) okay.\n"));
389 head.ph_Version = 0; // FIXME: shouold be PHV_CURRENT, but see <prefs/prefhdr.h>
390 head.ph_Type = 0;
391 head.ph_Flags[0] =
392 head.ph_Flags[1] =
393 head.ph_Flags[2] =
394 head.ph_Flags[3] = 0;
396 if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head))
398 D(bug("SavePrefs: WriteChunkBytes(PRHD) okay.\n"));
400 PopChunk(iff);
402 if (!PushChunk(iff, ID_PREF, ID_LCLE, sizeof(struct LocalePrefs)))
404 D(bug("SavePrefs: PushChunk(LCLE) okay.\n"));
406 if (WriteChunkBytes(iff, &saveprefs, sizeof(saveprefs)) == sizeof(saveprefs))
408 D(bug("SavePrefs: WriteChunkBytes(LCLE) okay.\n"));
409 D(bug("SavePrefs: Everything okay :-)\n"));
411 retval = TRUE;
414 PopChunk(iff);
416 } /* if (!PushChunk(iff, ID_PREF, ID_LCLE, sizeof(struct LocalePrefs))) */
418 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
419 else
421 PopChunk(iff);
424 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
426 PopChunk(iff);
428 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
430 CloseIFF(iff);
432 } /* if (!OpenIFF(iff, IFFFWRITE)) */
434 Close((BPTR)iff->iff_Stream);
436 } /* if ((iff->iff_Stream = (IPTR)Open(filename, MODE_NEWFILE))) */
438 FreeIFF(iff);
440 } /* if ((iff = AllocIFF())) */
442 if (!retval && delete_if_error)
444 DeleteFile(filename);
447 return retval;
450 /*********************************************************************************************/
452 BOOL DefaultPrefs(void)
454 BOOL retval = FALSE;
455 WORD i;
457 TellGUI(PAGECMD_PREFS_CHANGING);
459 localeprefs.lp_Reserved[0] = 0;
460 localeprefs.lp_Reserved[1] = 0;
461 localeprefs.lp_Reserved[2] = 0;
462 localeprefs.lp_Reserved[3] = 0;
464 strcpy(localeprefs.lp_CountryName, "united_states");
466 for(i = 0; i < 10; i++)
468 memset(localeprefs.lp_PreferredLanguages[i], 0, sizeof(localeprefs.lp_PreferredLanguages[i]));
470 localeprefs.lp_GMTOffset = 5 * 60;
471 localeprefs.lp_Flags = 0;
473 if (LoadCountry("united_states", &localeprefs.lp_CountryData))
475 retval = TRUE;
478 TellGUI(PAGECMD_PREFS_CHANGED);
480 return retval;
483 /*********************************************************************************************/
485 void RestorePrefs(void)
487 TellGUI(PAGECMD_PREFS_CHANGING);
488 localeprefs = restore_prefs;
489 TellGUI(PAGECMD_PREFS_CHANGED);
492 /*********************************************************************************************/