fix config file path
[AROS.git] / workbench / prefs / locale / prefs.c
blobca3c74acffc0357b67a63c63cfccbe760c4e1083
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*********************************************************************************************/
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
12 #include <aros/macros.h>
14 //#define DEBUG 1
15 #include <aros/debug.h>
17 #include <prefs/prefhdr.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/locale.h>
22 #include <proto/utility.h>
23 #include <proto/alib.h>
24 #include <proto/iffparse.h>
26 #include "prefs.h"
27 #include "misc.h"
29 /*********************************************************************************************/
31 #define PREFS_PATH_ENVARC "ENVARC:SYS/locale.prefs"
32 #define PREFS_PATH_ENV "ENV:SYS/locale.prefs"
34 /*********************************************************************************************/
36 struct FilePrefHeader
38 UBYTE ph_Version;
39 UBYTE ph_Type;
40 UBYTE ph_Flags[4];
43 /*********************************************************************************************/
45 struct LocalePrefs localeprefs;
46 char character_set[CHARACTER_SET_LEN];
47 char restore_charset[CHARACTER_SET_LEN];
48 struct List country_list;
49 struct List language_list;
50 struct List pref_language_list;
52 /*********************************************************************************************/
54 static APTR mempool;
56 /*********************************************************************************************/
58 STATIC VOID SortInNode(struct List *list, struct Node *node)
60 struct Node *sort, *prev = NULL;
61 struct Locale *loc;
63 loc = OpenLocale(NULL);
65 ForeachNode(list, sort)
67 if (StrnCmp(loc,
68 node->ln_Name, sort->ln_Name,
69 strlen(node->ln_Name), SC_COLLATE2)
70 < 0)
72 break;
74 prev = sort;
77 Insert(list, node, prev);
78 CloseLocale(loc);
81 /*********************************************************************************************/
83 STATIC VOID ScanDirectory(char *pattern, struct List *list, LONG entrysize)
85 struct AnchorPath ap;
86 struct ListviewEntry *entry;
87 char *sp;
88 LONG error;
90 memset(&ap, 0, sizeof(ap));
92 error = MatchFirst(pattern, &ap);
93 while((error == 0))
95 if (ap.ap_Info.fib_DirEntryType < 0)
97 entry = (struct ListviewEntry *)AllocPooled(mempool, entrysize);
98 if (entry)
100 entry->node.ln_Name = entry->name;
101 strncpy( entry->name,
102 (const char *) ap.ap_Info.fib_FileName,
103 sizeof(entry->name) );
105 entry->name[0] = ToUpper(entry->name[0]);
106 sp = strchr(entry->name, '.');
107 if (sp) sp[0] = '\0';
109 strcpy(entry->realname, entry->name);
111 sp = entry->name;
112 while((sp = strchr(sp, '_')))
114 sp[0] = ' ';
115 if (sp[1])
117 /* Make char after underscore uppercase only if no
118 more underscores follow */
119 if (strchr(sp, '_') == 0)
121 sp[1] = ToUpper(sp[1]);
125 SortInNode(list, &entry->node);
128 error = MatchNext(&ap);
130 MatchEnd(&ap);
132 ForeachNode(list, entry)
134 sprintf(entry->displayflag, "\033I[5:Locale:Flags/Countries/%s]", entry->realname);
135 D(Printf("Locale: country entry flag: %s\n", entry->realname));
140 /*********************************************************************************************/
142 #if !AROS_BIG_ENDIAN
143 STATIC VOID FixCountryEndianess(struct CountryPrefs *country)
145 country->cp_Reserved[0] = AROS_BE2LONG(country->cp_Reserved[0]);
146 country->cp_Reserved[1] = AROS_BE2LONG(country->cp_Reserved[1]);
147 country->cp_Reserved[2] = AROS_BE2LONG(country->cp_Reserved[2]);
148 country->cp_Reserved[3] = AROS_BE2LONG(country->cp_Reserved[3]);
149 country->cp_CountryCode = AROS_BE2LONG(country->cp_CountryCode);
151 #endif
153 /*********************************************************************************************/
155 #if !AROS_BIG_ENDIAN
156 STATIC VOID FixLocaleEndianess(struct LocalePrefs *localeprefs)
158 localeprefs->lp_Reserved[0] = AROS_BE2LONG(localeprefs->lp_Reserved[0]);
159 localeprefs->lp_Reserved[1] = AROS_BE2LONG(localeprefs->lp_Reserved[1]);
160 localeprefs->lp_Reserved[2] = AROS_BE2LONG(localeprefs->lp_Reserved[2]);
161 localeprefs->lp_Reserved[3] = AROS_BE2LONG(localeprefs->lp_Reserved[3]);
162 localeprefs->lp_GMTOffset = AROS_BE2LONG(localeprefs->lp_GMTOffset);
163 localeprefs->lp_Flags = AROS_BE2LONG(localeprefs->lp_Flags);
165 #endif
167 /*********************************************************************************************/
169 BOOL Prefs_LoadCountry(STRPTR name, struct CountryPrefs *country)
171 static struct CountryPrefs loadcountry;
172 struct IFFHandle *iff;
173 char fullname[100];
174 BOOL retval = FALSE;
176 strcpy(fullname, "LOCALE:Countries");
177 AddPart(fullname, name, 100);
178 strcat(fullname, ".country");
180 D(Printf("[locale prefs] LoadCountry: Trying to open \"%s\"\n", fullname));
182 if ((iff = AllocIFF()))
184 if ((iff->iff_Stream = (IPTR)Open(fullname, MODE_OLDFILE)))
186 D(Printf("[locale prefs] LoadCountry: stream opened.\n"));
188 InitIFFasDOS(iff);
190 if (!OpenIFF(iff, IFFF_READ))
192 D(Printf("[locale prefs] LoadCountry: OpenIFF okay.\n"));
194 if (!StopChunk(iff, ID_PREF, ID_CTRY))
196 D(Printf("[locale prefs] LoadCountry: StopChunk okay.\n"));
198 if (!ParseIFF(iff, IFFPARSE_SCAN))
200 struct ContextNode *cn;
202 D(Printf("[locale prefs] LoadCountry: ParseIFF okay.\n"));
204 cn = CurrentChunk(iff);
206 if (cn->cn_Size == sizeof(struct CountryPrefs))
208 D(Printf("[locale prefs] LoadCountry: ID_CTRY chunk size okay.\n"));
210 if (ReadChunkBytes(iff, &loadcountry, sizeof(struct CountryPrefs)) == sizeof(struct CountryPrefs))
212 D(Printf("[locale prefs] LoadCountry: Reading chunk successful.\n"));
214 *country = loadcountry;
216 #if !AROS_BIG_ENDIAN
217 FixCountryEndianess(country);
218 #endif
220 D(Printf("[locale prefs] LoadCountry: Everything okay :-)\n"));
222 retval = TRUE;
225 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
226 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
227 CloseIFF(iff);
228 } /* if (!OpenIFF(iff, IFFF_READ)) */
229 Close((BPTR)iff->iff_Stream);
230 } /* if ((iff->iff_Stream = (IPTR)Open(fullname, MODE_OLDFILE))) */
231 FreeIFF(iff);
232 } /* if ((iff = AllocIFF())) */
234 return retval;
237 /*********************************************************************************************/
239 BOOL Prefs_ImportFH(BPTR fh)
241 static struct LocalePrefs loadprefs;
242 struct IFFHandle *iff;
243 BOOL retval = FALSE;
245 D(Printf("[locale prefs] LoadPrefsFH\n"));
247 if ((iff = AllocIFF()))
249 if ((iff->iff_Stream = (IPTR) fh))
251 D(Printf("[locale prefs] LoadPrefsFH: stream is ok.\n"));
253 InitIFFasDOS(iff);
255 if (!OpenIFF(iff, IFFF_READ))
257 D(Printf("[locale prefs] LoadPrefsFH: OpenIFF okay.\n"));
259 if (!StopChunk(iff, ID_PREF, ID_LCLE))
261 D(Printf("[locale prefs] LoadPrefsFH: StopChunk okay.\n"));
263 if (!ParseIFF(iff, IFFPARSE_SCAN))
265 struct ContextNode *cn;
267 D(Printf("[locale prefs] LoadPrefsFH: ParseIFF okay.\n"));
269 cn = CurrentChunk(iff);
271 if (cn->cn_Size == sizeof(struct LocalePrefs))
273 D(Printf("[locale prefs] LoadPrefsFH: ID_LCLE chunk size okay.\n"));
275 if (ReadChunkBytes(iff, &loadprefs, sizeof(struct LocalePrefs)) == sizeof(struct LocalePrefs))
277 D(Printf("[locale prefs] LoadPrefsFH: Reading chunk successful.\n"));
279 localeprefs = loadprefs;
281 #if !AROS_BIG_ENDIAN
282 FixLocaleEndianess(&localeprefs);
283 FixCountryEndianess(&localeprefs.lp_CountryData);
284 #endif
286 D(Printf("[locale prefs] LoadPrefsFH: Everything okay :-)\n"));
288 retval = TRUE;
291 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
292 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
293 CloseIFF(iff);
294 } /* if (!OpenIFF(iff, IFFF_READ)) */
295 } /* if ((iff->iff_Stream = (IPTR)Open(filename, MODE_OLDFILE))) */
296 FreeIFF(iff);
297 } /* if ((iff = AllocIFF())) */
299 D(Printf("[locale prefs] CountryName: %s\n",localeprefs.lp_CountryName));
300 int i=0;
301 while(i<10 && localeprefs.lp_PreferredLanguages[i])
303 D(Printf("[locale prefs] preferred %ld: %s\n",i,localeprefs.lp_PreferredLanguages[i]));
304 i++;
306 D(Printf("[locale prefs] lp_GMTOffset: %ld\n",localeprefs.lp_GMTOffset));
307 return retval;
311 /*********************************************************************************************/
313 BOOL Prefs_ExportFH(BPTR fh)
315 struct LocalePrefs saveprefs;
316 struct IFFHandle *iff;
317 BOOL retval = FALSE;
318 #if 0 /* unused */
319 BOOL delete_if_error = FALSE;
320 #endif
322 D(Printf("[locale prefs] SavePrefsFH: fh: %lx\n", fh));
324 saveprefs = localeprefs;
326 #if !AROS_BIG_ENDIAN
327 FixLocaleEndianess(&saveprefs);
328 FixCountryEndianess(&saveprefs.lp_CountryData);
329 #endif
331 if ((iff = AllocIFF()))
333 iff->iff_Stream = (IPTR) fh;
334 D(Printf("[locale prefs] SavePrefsFH: stream opened.\n"));
336 #if 0 /* unused */
337 delete_if_error = TRUE;
338 #endif
340 InitIFFasDOS(iff);
342 if (!OpenIFF(iff, IFFF_WRITE))
344 D(Printf("[locale prefs] SavePrefsFH: OpenIFF okay.\n"));
346 if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
348 D(Printf("[locale prefs] SavePrefsFH: PushChunk(FORM) okay.\n"));
350 if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct FilePrefHeader)))
352 struct FilePrefHeader head;
354 D(Printf("[locale prefs] SavePrefsFH: PushChunk(PRHD) okay.\n"));
356 head.ph_Version = PHV_CURRENT;
357 head.ph_Type = 0;
358 head.ph_Flags[0] =
359 head.ph_Flags[1] =
360 head.ph_Flags[2] =
361 head.ph_Flags[3] = 0;
363 if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head))
365 D(Printf("[locale prefs] SavePrefsFH: WriteChunkBytes(PRHD) okay.\n"));
367 PopChunk(iff);
369 if (!PushChunk(iff, ID_PREF, ID_LCLE, sizeof(struct LocalePrefs)))
371 D(Printf("[locale prefs] SavePrefsFH: PushChunk(LCLE) okay.\n"));
373 if (WriteChunkBytes(iff, &saveprefs, sizeof(saveprefs)) == sizeof(saveprefs))
375 D(Printf("[locale prefs] SavePrefsFH: WriteChunkBytes(SERL) okay.\n"));
376 D(Printf("[locale prefs] SavePrefsFH: Everything okay :-)\n"));
378 retval = TRUE;
380 PopChunk(iff);
381 } /* if (!PushChunk(iff, ID_PREF, ID_SERL, sizeof(struct LocalePrefs))) */
383 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
384 else
386 PopChunk(iff);
388 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
389 PopChunk(iff);
390 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
391 CloseIFF(iff);
392 } /* if (!OpenIFF(iff, IFFFWRITE)) */
393 FreeIFF(iff);
394 } /* if ((iff = AllocIFF())) */
396 #if 0 /* unused */
397 if (!retval && delete_if_error)
399 DeleteFile(filename);
401 #endif
403 return retval;
406 /*********************************************************************************************/
408 BOOL Prefs_SaveCharset(BOOL envarc)
410 LONG flags = GVF_GLOBAL_ONLY;
412 D(Printf("[locale prefs] SaveCharset(%ld)\n", envarc));
414 if (envarc)
415 flags |= GVF_SAVE_VAR;
416 /* We don't check results of the following actions because they may fail if ENVARC: is read-only (CD-ROM) */
417 if (character_set[0])
418 SetVar("CHARSET", character_set, -1, flags);
419 else
420 DeleteVar("CHARSET", flags);
422 return TRUE;
425 /*********************************************************************************************/
427 static BOOL Prefs_Load(STRPTR from)
429 BOOL retval = FALSE;
431 BPTR fh = Open(from, MODE_OLDFILE);
432 if (fh)
434 retval = Prefs_ImportFH(fh);
435 Close(fh);
438 return retval;
441 /*********************************************************************************************/
443 BOOL Prefs_HandleArgs(STRPTR from, BOOL use, BOOL save)
445 BPTR fh;
447 if (from)
449 if (!Prefs_Load(from))
451 ShowMessage("Can't read from input file");
452 return FALSE;
455 else
457 if (!Prefs_Load(PREFS_PATH_ENV))
459 if (!Prefs_Load(PREFS_PATH_ENVARC))
461 ShowMessage
463 "Can't read from file " PREFS_PATH_ENVARC
464 ".\nUsing default values."
466 Prefs_Default();
471 if (use || save)
473 Prefs_LoadCountry(localeprefs.lp_CountryName, &localeprefs.lp_CountryData);
474 fh = Open(PREFS_PATH_ENV, MODE_NEWFILE);
475 if (fh)
477 Prefs_ExportFH(fh);
478 Close(fh);
480 else
482 ShowMessage("Cant' open " PREFS_PATH_ENV " for writing.");
485 if (save)
487 fh = Open(PREFS_PATH_ENVARC, MODE_NEWFILE);
488 if (fh)
490 Prefs_ExportFH(fh);
491 Close(fh);
493 else
495 ShowMessage("Cant' open " PREFS_PATH_ENVARC " for writing.");
499 return TRUE;
502 /*********************************************************************************************/
504 BOOL Prefs_Initialize(VOID)
506 D(Printf("[locale prefs] InitPrefs\n"));
508 struct LanguageEntry *entry;
510 mempool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, 2048, 2048);
511 if (!mempool)
513 ShowMessage("Out of memory!");
514 return FALSE;
517 NewList(&country_list);
518 NewList(&language_list);
519 NewList(&pref_language_list);
521 ScanDirectory("LOCALE:Countries/~(#?.info)", &country_list, sizeof(struct CountryEntry));
522 ScanDirectory("LOCALE:Languages/#?.language", &language_list, sizeof(struct LanguageEntry));
524 /* English language is always available */
526 if ((entry = AllocPooled(mempool, sizeof(struct LanguageEntry))))
528 strcpy( entry->lve.name, "English");
529 strcpy( entry->lve.realname, "English");
530 entry->lve.node.ln_Name = entry->lve.name;
532 SortInNode(&language_list, &entry->lve.node);
535 character_set[0] = 0;
536 GetVar("CHARSET", character_set, sizeof(character_set), 0);
537 D(Printf("[locale prefs] System character set: %s\n", character_set));
539 return TRUE;
542 /*********************************************************************************************/
544 VOID Prefs_Deinitialize(VOID)
546 D(Printf("[locale prefs] CleanupPrefs\n"));
547 if (mempool)
549 DeletePool(mempool);
550 mempool = NULL;
554 /*********************************************************************************************/
556 BOOL Prefs_Default(VOID)
558 BOOL retval = FALSE;
559 WORD i;
561 localeprefs.lp_Reserved[0] = 0;
562 localeprefs.lp_Reserved[1] = 0;
563 localeprefs.lp_Reserved[2] = 0;
564 localeprefs.lp_Reserved[3] = 0;
566 strcpy(localeprefs.lp_CountryName, "united_states");
568 for(i = 0; i < 10; i++)
570 memset(localeprefs.lp_PreferredLanguages[i], 0, sizeof(localeprefs.lp_PreferredLanguages[i]));
572 localeprefs.lp_GMTOffset = 5 * 60;
573 localeprefs.lp_Flags = 0;
575 if (Prefs_LoadCountry((STRPTR) "united_states", &localeprefs.lp_CountryData))
577 retval = TRUE;
580 character_set[0] = 0;
582 return retval;