2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
5 Desc: InitLocale() load locale preferences from a file.
9 #include <exec/types.h>
10 #include <proto/dos.h>
11 #include <proto/iffparse.h>
12 #include "locale_intern.h"
13 #include <libraries/iffparse.h>
14 #include <prefs/prefhdr.h>
15 #include <prefs/locale.h>
16 #include <proto/exec.h>
17 #include <proto/locale.h>
18 #include <aros/asmcall.h>
19 #include <aros/libcall.h>
21 #include <aros/debug.h>
25 #define DEBUG_INITLOCALE(x) ;
27 AROS_LD4(ULONG
, strcompare
,
28 AROS_UFPA(STRPTR
, string1
, A1
),
29 AROS_UFPA(STRPTR
, string2
, A2
),
30 AROS_UFPA(ULONG
, length
, D0
),
31 AROS_UFPA(ULONG
, how
, D1
),
32 struct LocaleBase
*, LocaleBase
, 22, english
35 extern void *__eng_functable
[];
39 (x) = (((x) & 0xFF000000) >> 24)\
40 | (((x) & 0x00FF0000) >> 8)\
41 | (((x) & 0x0000FF00) << 8)\
42 | (((x) & 0x000000FF) << 24);\
46 void SetLocaleLanguage(struct IntLocale *, struct LocaleBase *)
48 Try and set up the language of a Locale structure.
51 void SetLocaleLanguage(struct IntLocale
*il
, struct LocaleBase
*LocaleBase
)
53 struct Library
*lang
= NULL
;
58 DEBUG_INITLOCALE(dprintf("SetLocaleLanguage: Locale 0x%lx\n",il
));
60 while(lang
== NULL
&& i
< 10)
62 STRPTR lName
= il
->il_Locale
.loc_PrefLanguages
[i
];
67 /* Is this english? If not try and load the language */
68 #ifdef __MORPHOS__ /*I had some ugly problems with the macros adding a space before _Gate so I had to do it this way*/
69 ret
= AROS_UFC4(ULONG
, &LIB_strcompare_Gate
,
70 AROS_UFCA(STRPTR
, defLocale
.loc_PrefLanguages
[0], A1
),
71 AROS_UFCA(STRPTR
, lName
, A2
),
72 AROS_UFCA(ULONG
, 7, D0
),
73 AROS_UFCA(ULONG
, SC_ASCII
, D1
));
75 void *fn
= AROS_SLIB_ENTRY(strcompare
, english
);
76 ret
= AROS_CALL4(ULONG
, fn
,
77 AROS_LCA(STRPTR
, defLocale
.loc_PrefLanguages
[0], A1
),
78 AROS_LCA(STRPTR
, lName
, A2
),
79 AROS_LCA(ULONG
, 7, D0
),
80 AROS_LCA(ULONG
, SC_ASCII
, D1
),
81 struct LocaleBase
*, LocaleBase
);
86 #warning FIXME: watch out for buffer overflows here!
87 strcpy(fileBuf
, lName
);
88 strcat(fileBuf
, ".language");
90 /* Try and open the specified language */
91 lang
= OpenLibrary(fileBuf
, 0);
97 Ok, so the language didn't open, lets try for
98 MOSSYS:LOCALE/Languages/xxx.language
101 strcpy(fileBuf
, "MOSSYS:LOCALE/Languages/");
102 AddPart(fileBuf
, lName
, 512);
103 strcat(fileBuf
, ".language");
106 struct Process
*me
=(struct Process
*)FindTask(NULL
);
107 oldwinptr
= me
->pr_WindowPtr
;
108 me
->pr_WindowPtr
= (APTR
) -1;
109 lang
= OpenLibrary(fileBuf
, 0);
110 me
->pr_WindowPtr
= oldwinptr
;
118 Ok, so the language didn't open, lets try for
119 LOCALE:Languages/xxx.language
122 strcpy(fileBuf
, "LOCALE:Languages/");
123 AddPart(fileBuf
, lName
, 512);
124 strcat(fileBuf
, ".language");
126 lang
= OpenLibrary(fileBuf
, 0);
129 if((lang
== NULL
) && ((((struct Process
*)FindTask(NULL
))->pr_HomeDir
) != NULL
))
132 Ok, so we are still NULL, lets then try for
133 PROGDIR:Languages/xxx.language
135 strcpy(fileBuf
, "PROGDIR:Languages/");
136 AddPart(fileBuf
, lName
, 512);
137 strcat(fileBuf
, ".language");
139 lang
= OpenLibrary(fileBuf
, 0);
144 strncpy(il
->LanguageName
, FilePart(fileBuf
), 30);
147 /* If it is still no good, then we have no hope */
155 strcpy(il
->LanguageName
, defLocale
.loc_LanguageName
);
158 il
->il_Locale
.loc_LanguageName
= &il
->LanguageName
[0];
161 Ok so we now should have a language, or nothing. Either way
162 we now fill in the locale functions in the structure.
163 I remember there was a VERY big bug in here once, which I
164 finally managed to fix, only to blow away the only copy
165 of the file (and the rest of the locale.library) from all
168 If we could open any of the libraries, replace its function,
169 otherwise replace none of them.
172 il
->il_CurrentLanguage
= lang
;
176 mask
= AROS_LC0(ULONG
, mask
, struct Library
*, lang
, 5, Language
);
181 DEBUG_INITLOCALE(dprintf("SetLocaleLanguage: Language Mask 0x%lx\n",mask
));
182 /* CONST: If we add any more functions we need to increase this number */
183 for(i
= 0; i
< 17; i
++)
188 il
->il_LanguageFunctions
[i
] = (APTR
)(((ULONG
)lang
) - ((i
+6)*6));
190 il
->il_LanguageFunctions
[i
] = __AROS_GETVECADDR(lang
, (i
+6));
192 DEBUG_INITLOCALE(dprintf("SetLocaleLanguage: use Lanugage Entry %ld Func 0x%lx\n",i
,il
->il_LanguageFunctions
[i
]));
196 il
->il_LanguageFunctions
[i
] = __eng_functable
[i
];
197 DEBUG_INITLOCALE(dprintf("SetLocaleLanguage: use Default Entry %ld Func 0x%lx\n",i
,il
->il_LanguageFunctions
[i
]));
201 /* Open dos.catalog (needed for DosGetLocalizedString patch) */
202 il
->il_DosCatalog
= OpenCatalogA((struct Locale
*)il
, "System/Libs/dos.catalog", NULL
);
204 DEBUG_INITLOCALE(dprintf("SetLocaleLanguage: DosCatalog 0x%lx\n",il
->il_DosCatalog
));
207 /* InitLocale(IntLocale *, LocalePrefs *)
208 This procedure will extract all the relevant information out of
209 a LocalePrefs structure, and stuff it into a IntLocale structure.
211 This is really a silly way of doing things, but unfortunately it
212 is the only way that doesn't keep the entire chunk in memory,
213 (by duplicating the LocalePrefs chunk), or by doing extra loops
214 on things (counting string sizes, then allocating).
216 This puts it smack bang in the centre of speed/memory use.
217 This is mainly a separate procedure to get rid of the indentation.
220 void InitLocale(STRPTR filename
, struct IntLocale
*locale
,
221 struct LocalePrefs
*lp
, struct LocaleBase
*LocaleBase
)
223 struct CountryPrefs
*cp
;
226 DEBUG_INITLOCALE(dprintf("InitLocale: filename <%s> Locale 0x%lx LocalePrefs 0x%lx\n",filename
,locale
,lp
));
228 cp
= &lp
->lp_CountryData
;
230 strncpy(locale
->LocaleName
, FilePart(filename
), 30);
231 locale
->il_Locale
.loc_LocaleName
= &locale
->LocaleName
[0];
234 We can copy 300 bytes straight away since
235 the prefered languages are all in a row.
237 CopyMem(lp
->lp_PreferredLanguages
[0],
238 locale
->PreferredLanguages
[0], 300);
240 for(i
= 0, i2
= 0; i
< 10; i
++)
242 if (locale
->PreferredLanguages
[i
][0])
244 locale
->il_Locale
.loc_PrefLanguages
[i2
++] = locale
->PreferredLanguages
[i
];
250 /* The user did not set any preferred Language. So we automatically
251 poke "english" into the array (Tested on the Amiga where this
252 does seem to happen, too!) */
254 DEBUG_INITLOCALE(dprintf("InitLocale: user set no preferred lang\n"));
255 strcpy(locale
->PreferredLanguages
[0], defLocale
.loc_PrefLanguages
[0]);
256 locale
->il_Locale
.loc_PrefLanguages
[0] = locale
->PreferredLanguages
[0];
260 If we cannot open ANY of the languages, then all the language
261 function vectors would have the default language data.
263 SetLocaleLanguage(locale
, LocaleBase
);
265 locale
->il_Locale
.loc_Flags
= 0;
266 locale
->il_Locale
.loc_CodeSet
= 0;
267 locale
->il_Locale
.loc_CountryCode
= cp
->cp_CountryCode
;
268 locale
->il_Locale
.loc_TelephoneCode
= cp
->cp_TelephoneCode
;
269 locale
->il_Locale
.loc_GMTOffset
= lp
->lp_GMTOffset
;
270 locale
->il_Locale
.loc_CalendarType
= cp
->cp_CalendarType
;
272 #if (AROS_BIG_ENDIAN == 0)
273 EC(locale
->il_Locale
.loc_CountryCode
);
274 EC(locale
->il_Locale
.loc_TelephoneCode
);
275 EC(locale
->il_Locale
.loc_GMTOffset
);
278 /* Another really large section to copy,
279 from cp_DateTimeFormat[] to cp_MonFracGrouping[] incl
280 80 + 40 + 40 + 80 + 40 + 40 + (10 * 10)
283 CopyMem(&cp
->cp_DateTimeFormat
[0], &locale
->DateTimeFormat
[0], 420);
285 locale
->il_Locale
.loc_DateTimeFormat
= &locale
->DateTimeFormat
[0];
286 locale
->il_Locale
.loc_DateFormat
= &locale
->DateFormat
[0];
287 locale
->il_Locale
.loc_TimeFormat
= &locale
->TimeFormat
[0];
288 locale
->il_Locale
.loc_ShortDateTimeFormat
= &locale
->ShortDateTimeFormat
[0];
289 locale
->il_Locale
.loc_ShortDateFormat
= &locale
->ShortDateFormat
[0];
290 locale
->il_Locale
.loc_ShortTimeFormat
= &locale
->ShortTimeFormat
[0];
292 locale
->il_Locale
.loc_DecimalPoint
= &locale
->DecimalPoint
[0];
293 locale
->il_Locale
.loc_GroupSeparator
= &locale
->GroupSeparator
[0];
294 locale
->il_Locale
.loc_FracGroupSeparator
= &locale
->FracGroupSeparator
[0];
295 locale
->il_Locale
.loc_Grouping
= &locale
->Grouping
[0];
296 locale
->il_Locale
.loc_FracGrouping
= &locale
->FracGrouping
[0];
298 locale
->il_Locale
.loc_MonDecimalPoint
= &locale
->MonDecimalPoint
[0];
299 locale
->il_Locale
.loc_MonGroupSeparator
= &locale
->MonGroupSeparator
[0];
300 locale
->il_Locale
.loc_MonFracGroupSeparator
= &locale
->MonFracGroupSeparator
[0];
301 locale
->il_Locale
.loc_MonGrouping
= &locale
->MonGrouping
[0];
302 locale
->il_Locale
.loc_MonFracGrouping
= &locale
->MonFracGrouping
[0];
304 locale
->il_Locale
.loc_MonFracDigits
= cp
->cp_MonFracDigits
;
305 locale
->il_Locale
.loc_MonIntFracDigits
= cp
->cp_MonIntFracDigits
;
307 /* The three currency symbols, and +ve sign */
308 CopyMem(&cp
->cp_MonCS
, &locale
->MonCS
[0], 40);
310 locale
->il_Locale
.loc_MonCS
= &locale
->MonCS
[0];
311 locale
->il_Locale
.loc_MonSmallCS
= &locale
->MonSmallCS
[0];
312 locale
->il_Locale
.loc_MonIntCS
= &locale
->MonIntCS
[0];
313 locale
->il_Locale
.loc_MonPositiveSign
= &locale
->MonPositiveSign
[0];
315 locale
->il_Locale
.loc_MonPositiveSpaceSep
= cp
->cp_MonPositiveSpaceSep
;
316 locale
->il_Locale
.loc_MonPositiveSignPos
= cp
->cp_MonPositiveSignPos
;
317 locale
->il_Locale
.loc_MonPositiveCSPos
= cp
->cp_MonPositiveCSPos
;
319 CopyMem(&cp
->cp_MonNegativeSign
[0], &locale
->MonNegativeSign
[0], 10);
320 locale
->il_Locale
.loc_MonNegativeSign
= &locale
->MonNegativeSign
[0];
321 locale
->il_Locale
.loc_MonNegativeSpaceSep
= cp
->cp_MonNegativeSpaceSep
;
322 locale
->il_Locale
.loc_MonNegativeSignPos
= cp
->cp_MonNegativeSignPos
;
323 locale
->il_Locale
.loc_MonNegativeCSPos
= cp
->cp_MonNegativeCSPos
;
324 locale
->il_Locale
.loc_CalendarType
= cp
->cp_CalendarType
;
326 DEBUG_INITLOCALE(dprintf("InitLocale: done\n"));