2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
6 /*********************************************************************************************/
12 #include <aros/macros.h>
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>
29 /*********************************************************************************************/
31 #define PREFS_PATH_ENVARC "ENVARC:SYS/locale.prefs"
32 #define PREFS_PATH_ENV "ENV:SYS/locale.prefs"
34 /*********************************************************************************************/
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 /*********************************************************************************************/
56 /*********************************************************************************************/
58 STATIC VOID
SortInNode(struct List
*list
, struct Node
*node
)
60 struct Node
*sort
, *prev
= NULL
;
63 loc
= OpenLocale(NULL
);
65 ForeachNode(list
, sort
)
68 node
->ln_Name
, sort
->ln_Name
,
69 strlen(node
->ln_Name
), SC_COLLATE2
)
77 Insert(list
, node
, prev
);
81 /*********************************************************************************************/
83 STATIC VOID
ScanDirectory(char *pattern
, struct List
*list
, LONG entrysize
)
86 struct ListviewEntry
*entry
;
90 memset(&ap
, 0, sizeof(ap
));
92 error
= MatchFirst(pattern
, &ap
);
95 if (ap
.ap_Info
.fib_DirEntryType
< 0)
97 entry
= (struct ListviewEntry
*)AllocPooled(mempool
, entrysize
);
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
);
112 while((sp
= strchr(sp
, '_')))
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
);
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 /*********************************************************************************************/
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
);
153 /*********************************************************************************************/
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
);
167 /*********************************************************************************************/
169 BOOL
Prefs_LoadCountry(STRPTR name
, struct CountryPrefs
*country
)
171 static struct CountryPrefs loadcountry
;
172 struct IFFHandle
*iff
;
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"));
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
;
217 FixCountryEndianess(country
);
220 D(Printf("[locale prefs] LoadCountry: Everything okay :-)\n"));
225 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
226 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
228 } /* if (!OpenIFF(iff, IFFF_READ)) */
229 Close((BPTR
)iff
->iff_Stream
);
230 } /* if ((iff->iff_Stream = (IPTR)Open(fullname, MODE_OLDFILE))) */
232 } /* if ((iff = AllocIFF())) */
237 /*********************************************************************************************/
239 BOOL
Prefs_ImportFH(BPTR fh
)
241 static struct LocalePrefs loadprefs
;
242 struct IFFHandle
*iff
;
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"));
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
;
282 FixLocaleEndianess(&localeprefs
);
283 FixCountryEndianess(&localeprefs
.lp_CountryData
);
286 D(Printf("[locale prefs] LoadPrefsFH: Everything okay :-)\n"));
291 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
292 } /* if (!StopChunk(iff, ID_PREF, ID_CTRY)) */
294 } /* if (!OpenIFF(iff, IFFF_READ)) */
295 } /* if ((iff->iff_Stream = (IPTR)Open(filename, MODE_OLDFILE))) */
297 } /* if ((iff = AllocIFF())) */
299 D(Printf("[locale prefs] CountryName: %s\n",localeprefs
.lp_CountryName
));
301 while(i
<10 && localeprefs
.lp_PreferredLanguages
[i
])
303 D(Printf("[locale prefs] preferred %ld: %s\n",i
,localeprefs
.lp_PreferredLanguages
[i
]));
306 D(Printf("[locale prefs] lp_GMTOffset: %ld\n",localeprefs
.lp_GMTOffset
));
311 /*********************************************************************************************/
313 BOOL
Prefs_ExportFH(BPTR fh
)
315 struct LocalePrefs saveprefs
;
316 struct IFFHandle
*iff
;
319 BOOL delete_if_error
= FALSE
;
322 D(Printf("[locale prefs] SavePrefsFH: fh: %lx\n", fh
));
324 saveprefs
= localeprefs
;
327 FixLocaleEndianess(&saveprefs
);
328 FixCountryEndianess(&saveprefs
.lp_CountryData
);
331 if ((iff
= AllocIFF()))
333 iff
->iff_Stream
= (IPTR
) fh
;
334 D(Printf("[locale prefs] SavePrefsFH: stream opened.\n"));
337 delete_if_error
= TRUE
;
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
;
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"));
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"));
381 } /* if (!PushChunk(iff, ID_PREF, ID_SERL, sizeof(struct LocalePrefs))) */
383 } /* if (WriteChunkBytes(iff, &head, sizeof(head)) == sizeof(head)) */
388 } /* if (!PushChunk(iff, ID_PREF, ID_PRHD, sizeof(struct PrefHeader))) */
390 } /* if (!PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)) */
392 } /* if (!OpenIFF(iff, IFFFWRITE)) */
394 } /* if ((iff = AllocIFF())) */
397 if (!retval
&& delete_if_error
)
399 DeleteFile(filename
);
406 /*********************************************************************************************/
408 BOOL
Prefs_SaveCharset(BOOL envarc
)
410 LONG flags
= GVF_GLOBAL_ONLY
;
412 D(Printf("[locale prefs] SaveCharset(%ld)\n", 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
);
420 DeleteVar("CHARSET", flags
);
425 /*********************************************************************************************/
427 static BOOL
Prefs_Load(STRPTR from
)
431 BPTR fh
= Open(from
, MODE_OLDFILE
);
434 retval
= Prefs_ImportFH(fh
);
441 /*********************************************************************************************/
443 BOOL
Prefs_HandleArgs(STRPTR from
, BOOL use
, BOOL save
)
449 if (!Prefs_Load(from
))
451 ShowMessage("Can't read from input file");
457 if (!Prefs_Load(PREFS_PATH_ENV
))
459 if (!Prefs_Load(PREFS_PATH_ENVARC
))
463 "Can't read from file " PREFS_PATH_ENVARC
464 ".\nUsing default values."
473 Prefs_LoadCountry(localeprefs
.lp_CountryName
, &localeprefs
.lp_CountryData
);
474 fh
= Open(PREFS_PATH_ENV
, MODE_NEWFILE
);
482 ShowMessage("Cant' open " PREFS_PATH_ENV
" for writing.");
487 fh
= Open(PREFS_PATH_ENVARC
, MODE_NEWFILE
);
495 ShowMessage("Cant' open " PREFS_PATH_ENVARC
" for writing.");
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);
513 ShowMessage("Out of memory!");
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
));
542 /*********************************************************************************************/
544 VOID
Prefs_Deinitialize(VOID
)
546 D(Printf("[locale prefs] CleanupPrefs\n"));
554 /*********************************************************************************************/
556 BOOL
Prefs_Default(VOID
)
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
))
580 character_set
[0] = 0;