1 /***************************************************************************
3 codesets.library - Amiga shared library for handling different codesets
4 Copyright (C) 2001-2005 by Alfonso [alfie] Ranieri <alforan@tin.it>.
5 Copyright (C) 2005-2009 by codesets.library Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 codesets.library project: http://sourceforge.net/projects/codesetslib/
21 ***************************************************************************/
25 #include <diskfont/glyph.h>
26 #include <diskfont/diskfonttag.h>
27 #include <proto/diskfont.h>
28 #include <proto/keymap.h>
29 #include <proto/locale.h>
30 #include <proto/exec.h>
31 #include <proto/dos.h>
32 #include <proto/utility.h>
36 #if defined(__amigaos4__)
37 struct Library
*DOSBase
= NULL
;
38 struct Library
*UtilityBase
= NULL
;
39 struct Library
*LocaleBase
= NULL
;
40 struct Library
*DiskfontBase
= NULL
;
42 struct DOSIFace
* IDOS
= NULL
;
43 struct UtilityIFace
* IUtility
= NULL
;
44 struct LocaleIFace
* ILocale
= NULL
;
45 struct DiskfontIFace
* IDiskfont
= NULL
;
47 #if !defined(__NEWLIB__)
48 extern struct Library
*__UtilityBase
;
49 extern struct UtilityIFace
* __IUtility
;
53 struct DosLibrary
*DOSBase
= NULL
;
54 #if defined(__MORPHOS__)
55 struct Library
*LocaleBase
= NULL
;
57 struct LocaleBase
*LocaleBase
= NULL
;
60 struct UtilityBase
*UtilityBase
= NULL
;
62 struct Library
*UtilityBase
= NULL
;
63 struct Library
*__UtilityBase
= NULL
; // required by clib2 & libnix
67 /****************************************************************************/
70 freeBase(struct LibraryHeader
*lib
)
74 D(DBF_STARTUP
, "freeing all resources of codesets.library");
76 // cleanup also the internal public codesets list
77 codesetsCleanup(&lib
->codesets
);
79 // close locale.library
82 DROPINTERFACE(ILocale
);
83 CloseLibrary((struct Library
*)LocaleBase
);
87 #if defined(__amigaos4__)
88 // close diskfont.library
91 DROPINTERFACE(IDiskfont
);
92 CloseLibrary((struct Library
*)DiskfontBase
);
97 // delete our private memory pool
100 #if defined(__amigaos4__)
101 FreeSysObject(ASOT_MEMPOOL
, lib
->pool
);
103 DeletePool(lib
->pool
);
108 // close utility.library
111 DROPINTERFACE(IUtility
);
112 CloseLibrary(UtilityBase
);
120 CloseLibrary((struct Library
*)DOSBase
);
128 /***********************************************************************/
134 const char *codesetName
;
137 // table with the default LANGUAGE<>CHARSET mapping we
138 // are using in codesets.library.
139 static const struct loc locs
[] =
141 { "bosanski", 8, "ISO-8859-2" },
142 { "català", 6, "ISO-8859-1 + Euro" },
143 { "czech", 5, "ISO-8859-2" },
144 { "dansk", 5, "ISO-8859-1 + Euro" },
145 { "deutsch", 7, "ISO-8859-1 + Euro" },
146 { "english", 7, "ISO-8859-1 + Euro" },
147 { "esperanto", 9, "ISO-8859-3" },
148 { "eesti", 5, "ISO-8859-15" },
149 { "èe¹tina", 7, "ISO-8859-2" }, /* Czech in MorphOS 2.0 */
150 { "español", 7, "ISO-8859-1 + Euro" },
151 { "français", 8, "ISO-8859-1 + Euro" },
152 { "gaeilge", 7, "ISO-8859-15" },
153 { "galego", 6, "ISO-8859-1 + Euro" },
154 { "greek", 5, "ISO-8859-7" },
155 { "hrvatski", 8, "ISO-8859-2" },
156 { "italiano", 8, "ISO-8859-1 + Euro" },
157 { "lietuvi", 7, "ISO-8859-13" },
158 { "magyar", 6, "ISO-8859-2" },
159 { "nederlands", 10, "ISO-8859-1 + Euro" },
160 { "norsk", 5, "ISO-8859-1 + Euro" },
161 { "polski", 6, "ISO-8859-2" },
162 { "português", 9, "ISO-8859-1 + Euro" },
163 { "russian", 7, "Amiga-1251" },
164 { "slovak", 6, "ISO-8859-2" },
165 { "slovensko", 9, "ISO-8859-2" },
166 { "srpski", 6, "ISO-8859-2" },
167 { "suomi", 5, "ISO-8859-1" },
168 { "svenska", 7, "ISO-8859-1 + Euro" },
169 { "türkçe", 6, "ISO-8859-9" },
174 getSystemCodeset(struct LibraryHeader
*lib
)
176 struct codeset
*foundCodeset
= NULL
;
180 // before we go any query the system via locale.library (which
181 // might not be so accurate) we try different other means of
182 // finding the codeset/charset of the system
185 LONG default_charset
= GetDiskFontCtrl(DFCTRL_CHARSET
);
186 char *charset
= (char *)ObtainCharsetInfo(DFCS_NUMBER
, default_charset
, DFCS_MIMENAME
);
188 foundCodeset
= codesetsFind(&lib
->codesets
, charset
);
190 D(DBF_STARTUP
, "%s system default codeset: '%s' (diskfont)", foundCodeset
? "found" : "not found", charset
);
196 /* The system maintains CODEPAGE environment variable which defines the preferred codepage for this user. */
199 if (GetVar("CODEPAGE", codepage
, sizeof(codepage
), 0) > 0)
201 foundCodeset
= codesetsFind(&lib
->codesets
, codepage
);
204 D(DBF_STARTUP
, "%s system default codeset: '%s' (keymap)", foundCodeset
? "found" : "not found", codepage
);
206 /* If CODEPAGE did not work (maybe user deleted it or something) we try a keymap instead. This only works
207 * in MorphOS 2 and only if an old Amiga keymap is not used.
209 if (foundCodeset
== NULL
)
211 struct Library
*KeymapBase
;
213 KeymapBase
= OpenLibrary("keymap.library", 51);
217 /* Since we requested V51 it is either V51 or newer */
218 if (KeymapBase
->lib_Version
> 51 || KeymapBase
->lib_Revision
>= 4)
220 #ifndef GetKeyMapCodepage
221 #define GetKeyMapCodepage(__p0) LP1(78, CONST_STRPTR , GetKeyMapCodepage, CONST struct KeyMap *, __p0, a0, , KEYMAP_BASE_NAME, 0, 0, 0, 0, 0, 0)
224 CONST_STRPTR codepage
;
226 codepage
= GetKeyMapCodepage(NULL
);
230 foundCodeset
= codesetsFind(&lib
->codesets
, codepage
);
232 D(DBF_STARTUP
, "%s system default codeset: '%s' (keymap)", foundCodeset
? "found" : "not found", codepage
);
236 CloseLibrary(KeymapBase
);
242 // if we still do not have our default charset we try to load
243 // it from and environment variable ENVARC:CHARSET
244 if(foundCodeset
== NULL
)
249 if(GetVar("CHARSET", charset
, sizeof(charset
), 0) > 0)
251 foundCodeset
= codesetsFind(&lib
->codesets
, charset
);
254 D(DBF_STARTUP
, "%s system default codeset: '%s' (ENV:CHARSET)", foundCodeset
? "found" : "not found", charset
);
257 // and if even the CHARSET environment variable didn't work
258 // out we check the LANGUAGE env variable against our own
259 // internal fallback list
260 if(foundCodeset
== NULL
)
264 if(GetVar("LANGUAGE", language
, sizeof(language
), 0) > 0)
267 struct loc
*curLoc
= NULL
;
272 curLoc
= (struct loc
*)&locs
[i
];
273 if(curLoc
== NULL
|| curLoc
->name
== NULL
)
276 if(!Strnicmp(language
, curLoc
->name
, curLoc
->len
))
284 foundCodeset
= codesetsFind(&lib
->codesets
, curLoc
->codesetName
);
287 D(DBF_STARTUP
, "%s system default codeset: '%s' (ENV:LANGUAGE)", foundCodeset
? "found" : "not found",
288 foundCodeset
? foundCodeset
->name
: "?");
291 // and the very last check we do to find out the system's charset is
292 // to use locale.library.
293 if(foundCodeset
== NULL
)
295 struct Locale
*locale
;
297 if((locale
= OpenLocale(NULL
)))
300 char *language
= locale
->loc_LanguageName
;
301 struct loc
*curLoc
= NULL
;
306 curLoc
= (struct loc
*)&locs
[i
];
307 if(curLoc
== NULL
|| curLoc
->name
== NULL
)
310 if(!Strnicmp(language
, curLoc
->name
, curLoc
->len
))
320 foundCodeset
= codesetsFind(&lib
->codesets
, curLoc
->codesetName
);
323 D(DBF_STARTUP
, "%s system default codeset: '%s' (locale)", foundCodeset
? "found" : "not found",
324 foundCodeset
? foundCodeset
->name
: "?");
327 // and if even that very last test didn't work out we
328 // can just take the ISO-8859-1 charset as the fallback default
329 if(foundCodeset
== NULL
)
330 lib
->systemCodeset
= codesetsFind(&lib
->codesets
, "ISO-8859-1");
332 lib
->systemCodeset
= foundCodeset
;
337 /***********************************************************************/
340 initBase(struct LibraryHeader
*lib
)
344 if((DOSBase
= (APTR
)OpenLibrary("dos.library", 37)) &&
345 GETINTERFACE(IDOS
, DOSBase
))
347 if((UtilityBase
= OpenLibrary("utility.library", 37)) &&
348 GETINTERFACE(IUtility
, UtilityBase
))
350 // we have to please the internal utilitybase
351 // pointers of libnix and clib2
352 #if !defined(__NEWLIB__) && !defined(__AROS__)
353 __UtilityBase
= (APTR
)UtilityBase
;
354 #if defined(__amigaos4__)
355 __IUtility
= IUtility
;
359 // setup the debugging stuff
364 #if defined(__amigaos4__)
365 if((DiskfontBase
= OpenLibrary("diskfont.library", 50)) &&
366 GETINTERFACE(IDiskfont
, DiskfontBase
))
369 #if defined(__amigaos4__)
370 lib
->pool
= AllocSysObjectTags(ASOT_MEMPOOL
, ASOPOOL_MFlags
, MEMF_SHARED
,
371 ASOPOOL_Puddle
, 4096,
372 ASOPOOL_Threshold
, 512,
375 lib
->pool
= CreatePool(MEMF_ANY
, 4096, 512);
377 if(lib
->pool
!= NULL
)
379 if(codesetsInit(&lib
->codesets
))
381 lib
->systemCodeset
= (struct codeset
*)lib
->codesets
.list
.mlh_Head
;
383 if((LocaleBase
= (APTR
)OpenLibrary("locale.library", 37)) &&
384 GETINTERFACE(ILocale
, LocaleBase
))
386 getSystemCodeset(lib
);
393 #if defined(__amigaos4__)
405 /***********************************************************************/