Updated for CVS 2.5.32 now.
[fvwm.git] / libs / FlocaleCharset.c
blob11b93371cad15ee5db0693ecba0b16c59dc1dcc3
1 /* -*-c-*- */
2 /* Copyright (C) 2002 Olivier Chapuis */
3 /* This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 /* ---------------------------- included header files ---------------------- */
20 #include "config.h"
21 #include <stdio.h>
23 #include <X11/Xlib.h>
24 #include <X11/Xatom.h>
26 #include "Strings.h"
27 #include "Parse.h"
28 #include "Flocale.h"
29 #include "FlocaleCharset.h"
30 #include "Ficonv.h"
32 #if FlocaleLibcharsetSupport
33 #include <libcharset.h>
34 #endif
35 #if FlocaleCodesetSupport
36 #include <langinfo.h>
37 #endif
39 /* ---------------------------- local definitions -------------------------- */
41 /* ---------------------------- local macros ------------------------------- */
43 /* ---------------------------- imports ------------------------------------ */
45 /* ---------------------------- included code files ------------------------ */
47 /* ---------------------------- local types -------------------------------- */
49 /* ---------------------------- forward declarations ----------------------- */
51 /* ---------------------------- local variables ---------------------------- */
53 /* X locale charset */
54 static FlocaleCharset *FLCXOMCharset = NULL;
55 /* list of XOM locale charset */
56 static FlocaleCharset **FLCXOMCharsetList = NULL;
57 static int FLCXOMCharsetList_num = 0;
58 /* UTF-8 charset */
59 static FlocaleCharset *FLCUtf8Charset = NULL;
60 /* locale charset from the locale not X */
61 static FlocaleCharset *FLCLocaleCharset = NULL;
63 static char *nullsl[] = {NULL};
65 #if FiconvSupport
66 /* from hpux iconv man page: The fromcode and tocode names can be any length,
67 * but only the first four and the last letter are used to identify the code
68 * set. */
69 /* the first name is the gnu canonical name */
70 char *armscii_8[] = {"ARMSCII-8", NULL};
71 char *big5_0[] = {"BIG5",
72 "big5", /* aix, hpux, osf */
73 "zh_TW-big5", /* solaris 9? */
74 NULL};
75 char *big5hkscs_0[] = {"BIG5-HKSCS",
76 "BIG5",
77 "big5", /* aix, hpux, osf */
78 "zh_TW-big5", /* solaris 9? */
79 NULL};
80 char *cns11643[] = {"EUCTW",
81 "EUC-TW",
82 "eucTW",
83 "euc-tw",
84 "euctw",
85 NULL};
86 char *dosencoding_cp437[] = {"CP437", NULL};
87 char *dosencoding_cp850[] = {"CP850",
88 "cp850", /* osf */
89 "IBM-850", /* aix */
90 NULL};
91 char *gb2312_1980_0[] = {"EUC-CN",
92 "GB2312",
93 "gb2312", /* solaris */
94 "dechanzi", /* osf */
95 "hp15CN", /* hpux */
96 "IBM-eucCN", /* aix */
97 "eucCN", /* irix */
98 NULL};
99 char *gbk_0[] = {"GBK", NULL};
100 char *georgian_academy[] = {"GEORGIAN-ACADEMY", NULL};
101 char *georgian_ps[] = {"GEORGIAN-PS", NULL};
102 char *ibm_cp1133[] = {"CP850" , NULL};
103 char *isiri_3342[] = {"ISIRI-3342", NULL};
104 /* embed ascii into ISO-8859-1*/
105 char *iso8859_1[] = {"ISO-8859-1", /* gnu */
106 "ISO8859-1", /* aix, irix, osf, solaris */
107 "iso8859-1", /* aix, irix, osf */
108 "iso88591", /* hpux */
109 "8859-1", /* solaris ? */
110 "iso81", /* hpux */
111 "ascii",
112 "ASCII",
113 "646", /* solaris */
114 "ANSI_X3.4-1968",
115 "ISO_646.IRV:1983", /* old glibc */
116 "american_e",
117 NULL};
118 char *iso8859_2[] = {"ISO-8859-2",
119 "ISO8859-2",
120 "iso8859-2",
121 "iso88592",
122 "8859-2",
123 "iso82",
124 NULL};
125 char *iso8859_3[] = {"ISO-8859-3",
126 "ISO8859-3",
127 "iso8859-3",
128 "iso88593",
129 "8859-3",
130 "iso83",
131 NULL};
132 char *iso8859_4[] = {"ISO-8859-4",
133 "ISO8859-4",
134 "iso8859-4",
135 "iso88594",
136 "8859-4",
137 "iso84",
138 NULL};
139 char *iso8859_5[] = {"ISO-8859-5",
140 "ISO8859-5",
141 "iso8859-5",
142 "iso88595",
143 "8859-5",
144 "iso85",
145 NULL};
146 char *iso8859_6[] = {"ISO-8859-6",
147 "ISO8859-6",
148 "iso8859-6",
149 "iso88596",
150 "8859-6",
151 "iso86",
152 NULL};
153 char *iso8859_7[] = {"ISO-8859-7",
154 "ISO8859-7",
155 "iso8859-7",
156 "iso88597",
157 "8859-7",
158 "iso87",
159 NULL};
160 char *iso8859_8[] = {"ISO-8859-8",
161 "ISO8859-8",
162 "iso88859-8",
163 "iso88598",
164 "8859-8",
165 "iso88",
166 NULL};
167 char *iso8859_9[] = {"ISO-8859-9",
168 "ISO8859-9",
169 "iso8859-9",
170 "iso88599",
171 "8859-9",
172 "iso89",
173 NULL};
174 char *iso8859_10[] = {"ISO-8859-10",
175 "ISO8859-10",
176 "iso8859-10",
177 "iso885910",
178 "8859-10",
179 "iso80", /*?*/
180 "iso10",
181 NULL};
182 char *iso8859_13[] = {"ISO-8859-13",
183 "ISO8859-13",
184 "iso8859-13",
185 "iso885913",
186 "8859-13",
187 "IBM-921", /* aix */
188 "iso813", /*?*/
189 "iso13",
190 NULL};
191 char *iso8859_14[] = {"ISO-8859-14",
192 "ISO8859-14",
193 "iso8859-14",
194 "iso885914",
195 "8859-14",
196 "iso814",
197 "iso14",
198 NULL};
199 char *iso8859_15[] = {"ISO-8859-15",
200 "ISO88859-15",
201 "iso88859-15",
202 "iso885915",
203 "8859-15",
204 "iso815",
205 "iso15",
206 NULL};
207 char *iso8859_16[] = {"ISO-8859-16",
208 "ISO8859-16",
209 "iso8859-16",
210 "iso885916",
211 "8859-16",
212 "iso80",
213 "iso16",
214 NULL};
215 char *jisx0201_1976_0[] = {"JIS_X0201",
216 "ISO-IR-14",
217 "jis", /* hpux */
218 NULL};
219 char *jisx0208_1983_0[] = {"JIS_X0208", NULL};
220 char *jisx0208_1990_0[] = {"JIS_X0208", NULL};
221 char *jisx0212_1990_0[] = {"JIS_X0212", NULL};
222 char *koi8_r[] = {"KOI8-R", /* gnu, solaris */
223 NULL};
224 char *koi8_u[] = {"KOI8-U",
225 NULL};
226 char *ksc5601[] = {"KSC5636",
227 "ko_KR-johap", /* solaris */
228 "ko_KR-johap92",
229 "ko_KR-euc",
230 "eucKR",
231 "EUC-KR",
232 "EUCKR",
233 "euc-kr",
234 "CP949", /* osf */
235 NULL};
236 char *microsoft_cp1251[] = {"CP1251",
237 NULL};
238 char *microsoft_cp1255[] = {"CP1255",
239 NULL};
240 char *microsoft_cp1256[] = {"CP1256",
241 NULL};
242 char *mulelao_1[] = {"MULELAO-1",
243 "MULELAO",
244 NULL};
245 char *sjisx_1[] = {"SHIFT_JIS",
246 "SJIS", /* solaris, osf */
247 "sjis", /* hpux */
248 "PCK", /* solaris */
249 NULL};
250 char *tatar_cyr[] = {NULL};
251 char *tcvn_5712[] = {"TCVN", NULL};
252 char *tis620_0[] = {"TIS-620",
253 "tis620", /* hpux */
254 "TACTIS", /* osf */
255 NULL};
256 char *viscii1_1_1[] = {"VISCII", NULL};
257 /* encofing only ...*/
258 char *utf_8[] = {"UTF-8", /* gnu, solaris */
259 "UTF8",
260 "utf8",
261 "utf_8",
262 NULL};
263 char *usc_2[] = {"USC-2",
264 "USC2",
265 "usc2",
266 "usc-2",
267 "usc_2",
268 NULL};
269 char *usc_4[] = {"USC-4",
270 "USC4",
271 "usc4",
272 "usc-4",
273 "usc_4",
274 NULL};
275 char *utf_16[] = {"UTF-16",
276 "UTF16",
277 "utf16",
278 "utf_16",
279 NULL};
280 char *euc_jp[] = {"EUC-JP",
281 "EUCJP",
282 "euc_jp",
283 "euc-jp",
284 "eucjp",
285 NULL};
286 #endif
288 #if FiconvSupport
290 #ifdef HAVE_BIDI
291 #define CT_ENTRY(x,y,z) \
292 {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, z, FLC_ENCODING_TYPE_FONT}
293 #define CT_ENTRY_WET(x,y,z,t) \
294 {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, z, t}
295 #else
296 #define CT_ENTRY(x,y,z) \
297 {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, NULL, FLC_ENCODING_TYPE_FONT}
298 #define CT_ENTRY_WET(x,y,z,t) \
299 {x, y, FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED, NULL, t}
300 #endif
302 #else /* !FlocaleIconvSupport */
304 #ifdef HAVE_BIDI
305 #define CT_ENTRY(x,y,z) \
306 {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, z, FLC_ENCODING_TYPE_FONT}
307 #define CT_ENTRY_WET(x,y,z,t) \
308 {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, z, t}
309 #else
310 #define CT_ENTRY(x,y,z) \
311 {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL, FLC_ENCODING_TYPE_FONT}
312 #define CT_ENTRY_WET(x,y,z,t) \
313 {x, nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL, t}
314 #endif
316 #endif
318 static
319 FlocaleCharset UnknownCharset =
320 {"Unknown", nullsl, FLC_INDEX_ICONV_CHARSET_NOT_FOUND, NULL};
322 /* the table contains all Xorg "charset" plus some others */
324 FlocaleCharset FlocaleCharsetTable[] =
326 CT_ENTRY("ARMSCII-8", armscii_8, NULL),
327 CT_ENTRY("BIG5-0", big5_0, NULL),
328 CT_ENTRY("BIG5HKSCS-0", big5hkscs_0, NULL),
329 CT_ENTRY("CNS11643.1986-1", cns11643, NULL),
330 CT_ENTRY("CNS11643.1986-2", cns11643, NULL),
331 CT_ENTRY("CNS11643.1992-3", cns11643, NULL),
332 CT_ENTRY("CNS11643.1992-4", cns11643, NULL),
333 CT_ENTRY("CNS11643.1992-5", cns11643, NULL),
334 CT_ENTRY("CNS11643.1992-6", cns11643, NULL),
335 CT_ENTRY("CNS11643.1992-7", cns11643, NULL),
336 CT_ENTRY("DOSENCODING-CP437", dosencoding_cp437, NULL),
337 CT_ENTRY("DOSENCODING-CP850", dosencoding_cp850, NULL),
338 CT_ENTRY("EUC-JP", euc_jp, NULL),
339 CT_ENTRY("GB2312.1980-0", gb2312_1980_0, NULL),
340 CT_ENTRY("GBK-0", gbk_0, NULL),
341 CT_ENTRY("GEORGIAN-ACADEMY", georgian_academy, NULL),
342 CT_ENTRY("GEORGIAN-PS", georgian_ps, NULL),
343 CT_ENTRY("IBM-CP1133", ibm_cp1133, NULL),
344 CT_ENTRY("ISIRI-3342", isiri_3342, "ISIRI-3342"),
345 /* exception ISO10646-1 implies UTF-8 and not USC-2 ! */
346 CT_ENTRY_WET("ISO10646-1", utf_8, "UTF-8", FLC_ENCODING_TYPE_UTF_8),
347 CT_ENTRY("ISO8859-1", iso8859_1, NULL),
348 CT_ENTRY("ISO8859-2", iso8859_2, NULL),
349 CT_ENTRY("ISO8859-3", iso8859_3, NULL),
350 CT_ENTRY("ISO8859-4", iso8859_4, NULL),
351 CT_ENTRY("ISO8859-5", iso8859_5, NULL),
352 CT_ENTRY("ISO8859-6", iso8859_6, "ISO8859-6"),
353 CT_ENTRY("ISO8859-6.8X", iso8859_6, "ISO8859-6"),
354 CT_ENTRY("ISO8859-7", iso8859_7, NULL),
355 CT_ENTRY("ISO8859-8", iso8859_8, "ISO8859-8"),
356 CT_ENTRY("ISO8859-9", iso8859_9, NULL),
357 CT_ENTRY("ISO8859-9E", iso8859_9, NULL),
358 CT_ENTRY("ISO8859-10", iso8859_10, NULL),
359 CT_ENTRY("ISO8859-13", iso8859_13, NULL),
360 CT_ENTRY("ISO8859-14", iso8859_14, NULL),
361 CT_ENTRY("ISO8859-15", iso8859_15, NULL),
362 CT_ENTRY("ISO8859-16", iso8859_16, NULL),
363 CT_ENTRY("JISX.UDC-1", jisx0201_1976_0, NULL), /* ? */
364 CT_ENTRY("JISX0201.1976-0", jisx0201_1976_0, NULL),
365 CT_ENTRY("JISX0208.1983-0", jisx0208_1983_0, NULL),
366 CT_ENTRY("JISX0208.1990-0", jisx0208_1990_0, NULL),
367 CT_ENTRY("JISX0212.1990-0", jisx0212_1990_0, NULL),
368 CT_ENTRY("KOI8-C", koi8_r, NULL),
369 CT_ENTRY("KOI8-R", koi8_r, NULL),
370 CT_ENTRY("KOI8-U", koi8_u, NULL),
371 CT_ENTRY("KSC5601.1987-0", ksc5601, NULL),
372 CT_ENTRY("KSC5601.1992-0", ksc5601, NULL),
373 CT_ENTRY("MICROSOFT-CP1251", microsoft_cp1251, NULL),
374 CT_ENTRY("MICROSOFT-CP1255", microsoft_cp1255, "CP1255"),
375 CT_ENTRY("MICROSOFT-CP1256", microsoft_cp1256, "CP1256"),
376 CT_ENTRY("MULELAO-1", mulelao_1, NULL),
377 CT_ENTRY("SJISX-1", sjisx_1, NULL),
378 CT_ENTRY("TATAR-CYR", tatar_cyr, NULL),
379 CT_ENTRY("TCVN-5712", tcvn_5712, NULL),
380 CT_ENTRY("TIS620-0", tis620_0, NULL),
381 CT_ENTRY("VISCII1.1-1", viscii1_1_1, NULL),
382 /* aliases */
383 /* CT_ENTRY("ADOBE-STANDARD", iso8859_1, NULL), no! */
384 CT_ENTRY("ASCII-0", iso8859_1, NULL),
385 CT_ENTRY("BIBIG5HKSCS", big5_0, NULL), /* ? */
386 CT_ENTRY("BIG5-E0", big5_0, NULL), /* emacs */
387 CT_ENTRY("BIG5-E1", big5_0, NULL), /* emacs */
388 CT_ENTRY("BIG5-1", big5_0, NULL),
389 CT_ENTRY("ISO646.1991-IRV", iso8859_1, NULL),
390 CT_ENTRY("TIS620.2533-1", tis620_0, NULL),
391 CT_ENTRY_WET("UTF-8", utf_8, "UTF-8", FLC_ENCODING_TYPE_UTF_8),
392 CT_ENTRY_WET("USC-2", usc_2, "USC-2", FLC_ENCODING_TYPE_USC_2),
393 CT_ENTRY_WET("USC-4", usc_4, NULL, FLC_ENCODING_TYPE_USC_4),
394 CT_ENTRY_WET("UTF-16", utf_16, NULL, FLC_ENCODING_TYPE_UTF_16),
395 CT_ENTRY(NULL, nullsl, NULL)
398 /* to be supported: ADOBE-STANDARD, some Xft1 charset */
400 /* ---------------------------- exported variables (globals) --------------- */
402 /* ---------------------------- local functions ---------------------------- */
404 static
405 FlocaleCharset *FlocaleCharsetOfXCharset(char *x)
407 int j = 0;
409 while(FlocaleCharsetTable[j].x != NULL)
411 if (StrEquals(x,FlocaleCharsetTable[j].x))
413 return &FlocaleCharsetTable[j];
415 j++;
417 return NULL;
420 static
421 FlocaleCharset *FlocaleCharsetOfLocaleCharset(char *l)
423 int j = 0, i = 0;
425 while(FlocaleCharsetTable[j].x != NULL)
427 if (StrEquals(l, FlocaleCharsetTable[j].x))
429 return &FlocaleCharsetTable[j];
431 i = 0;
432 while(FlocaleCharsetTable[j].locale[i] != NULL)
434 if (StrEquals(l, FlocaleCharsetTable[j].locale[i]))
436 return &FlocaleCharsetTable[j];
438 i++;
440 j++;
442 return NULL;
445 static
446 FlocaleCharset *FlocaleCharsetOfFontStruct(Display *dpy, XFontStruct *fs)
448 unsigned long value = 0;
449 char *name,*tmp;
450 FlocaleCharset *fc;
451 int count = 0;
453 if (fs == NULL)
454 return NULL;
456 if (!XGetFontProperty(fs, XA_FONT, &value))
458 return NULL;
460 if ((name = XGetAtomName(dpy, value)) == NULL)
462 return NULL;
465 tmp = name;
466 while (*tmp != '\0' && count < 13)
468 if (*tmp == '-')
470 count++;
472 tmp++;
473 if (count == 13)
475 fc = FlocaleCharsetOfXCharset(tmp);
476 XFree(name);
477 return fc;
480 XFree(name);
481 return NULL;
484 static
485 void FlocaleInit_X_Charset(Display *dpy, const char *module)
487 #ifdef HAVE_XOUTPUT_METHOD
488 XOM om;
489 XOMCharSetList cs;
490 int i;
492 om = XOpenOM(dpy, NULL, NULL, NULL);
493 if (om && XGetOMValues(om, XNRequiredCharSet, &cs, NULL) == NULL)
495 if (cs.charset_count > 0)
497 if (FLCXOMCharsetList != NULL)
499 free(FLCXOMCharsetList);
501 FLCXOMCharsetList_num = cs.charset_count;
502 FLCXOMCharsetList = (FlocaleCharset **)safemalloc(
503 sizeof(FlocaleCharset) * cs.charset_count);
504 for (i = 0; i < FLCXOMCharsetList_num; i++)
506 FLCXOMCharsetList[i] =
507 FlocaleCharsetOfXCharset(
508 cs.charset_list[i]);
509 #if FLOCALE_DEBUG_CHARSET
510 fprintf(stderr,
511 "[FlocaleInitCharset] XOM charset "
512 "%i: %s, bidi:%s\n",
514 FLC_DEBUG_GET_X_CHARSET(
515 FLCXOMCharsetList[i]),
516 FLC_DEBUG_GET_BIDI_CHARSET (
517 FLCXOMCharsetList[i]));
518 #endif
522 if (om)
524 XCloseOM(om);
526 if (FLCXOMCharsetList_num > 0 && FLCXOMCharsetList[0])
528 char *best_charset;
530 if (FLCLocaleCharset != NULL)
532 best_charset = FLCLocaleCharset->x;
533 #if FLOCALE_DEBUG_CHARSET
534 fprintf(stderr,
535 "[FlocaleInitCharset] FLCLocaleCharset: %s\n",
536 best_charset);
537 #endif
539 else
541 best_charset = FLOCALE_FALLBACK_XCHARSET;
542 #if FLOCALE_DEBUG_CHARSET
543 fprintf(stderr,
544 "[FlocaleInitCharset] FALLBACK: %s\n",
545 best_charset);
546 #endif
549 FLCXOMCharset = FLCXOMCharsetList[0];
550 if (best_charset == NULL)
552 /* should not happen */
554 else
556 for(i = 0; i < FLCXOMCharsetList_num; i++)
558 if (StrEquals(
559 best_charset,
560 FLC_DEBUG_GET_X_CHARSET(
561 FLCXOMCharsetList[i])))
563 FLCXOMCharset = FLCXOMCharsetList[i];
564 break;
568 #if FLOCALE_DEBUG_CHARSET
569 fprintf(stderr,
570 "[FlocaleInitCharset] XOM charset "
571 "%i: %s\n",
573 FLC_DEBUG_GET_X_CHARSET(FLCXOMCharset));
574 #endif
576 #endif
579 /* ---------------------------- interface functions ------------------------ */
581 void FlocaleCharsetInit(Display *dpy, const char *module)
583 static Bool initialized = False;
584 char *charset;
586 if (initialized == True)
588 return;
590 initialized = True;
592 /* try to find the regular charset */
593 charset = getenv("CHARSET");
594 #if FLOCALE_DEBUG_CHARSET
595 fprintf(stderr,
596 "[FlocaleInitCharset] CHARSET: %s\n", (!charset)? "null":charset);
597 #endif
598 if ((!charset || strlen(charset) < 3) && FlocaleLibcharsetSupport)
600 charset = (char *)Flocale_charset();
601 #if FLOCALE_DEBUG_CHARSET
602 fprintf(
603 stderr,
604 "[FlocaleInitCharset] FlocaleLibcharsetSupport: %s\n",
605 (!charset)? "null":charset);
606 #endif
608 if ((!charset || strlen(charset) < 3) && FlocaleCodesetSupport)
610 charset = Fnl_langinfo(FCODESET);
611 #if FLOCALE_DEBUG_CHARSET
612 fprintf(
613 stderr,
614 "[FlocaleInitCharset] Fnl_langinfo: %s\n",
615 (!charset)? "null":charset);
616 #endif
618 if (charset != NULL && strlen(charset) > 2)
620 FLCLocaleCharset =
621 FlocaleCharsetOfLocaleCharset(charset);
622 #if FLOCALE_DEBUG_CHARSET
623 fprintf(
624 stderr,
625 "[FlocaleInitCharset] FLCLocaleCharset: %s\n", charset);
626 #endif
629 /* set the defaults X locale charsets */
630 FlocaleInit_X_Charset(dpy, module);
632 /* never null */
633 FLCUtf8Charset = FlocaleCharsetOfXCharset(FLOCALE_UTF8_XCHARSET);
635 #if FLOCALE_DEBUG_CHARSET
636 fprintf(stderr,"[FlocaleCharsetInit] locale charset: x:%s, bidi:%s\n",
637 FLC_DEBUG_GET_X_CHARSET(FLCXOMCharset),
638 FLC_DEBUG_GET_BIDI_CHARSET (FLCXOMCharset));
639 fprintf(stderr,"[FlocaleCharsetInit] locale charset: x:%s, bidi:%s\n",
640 FLC_DEBUG_GET_X_CHARSET(FLCLocaleCharset),
641 FLC_DEBUG_GET_BIDI_CHARSET (FLCLocaleCharset));
642 #endif
644 return;
647 void FlocaleCharsetSetFlocaleCharset(
648 Display *dpy, FlocaleFont *flf, char *hints, char *encoding,
649 char *module)
651 char *charset = NULL;
652 char *iconv = NULL;
653 Bool iconv_found = False;
654 int i = 0;
656 FlocaleCharsetInit(dpy, module);
658 if (hints && *hints)
660 iconv = GetQuotedString(
661 hints, &charset, "/", NULL, NULL, NULL);
662 if (charset && *charset && *charset != '*' )
664 flf->fc = FlocaleCharsetOfXCharset(charset);
666 if (flf->fc == NULL && charset && *charset && *charset != '*')
668 flf->fc = FlocaleCharsetOfLocaleCharset(charset);
670 if (flf->fc == NULL && iconv && *iconv)
672 flf->fc = FlocaleCharsetOfLocaleCharset(iconv);
675 if (flf->fc == NULL)
677 if (FftSupport && flf->fftf.fftfont != NULL)
679 flf->fc = FlocaleCharsetOfXCharset(flf->fftf.encoding);
681 else if (flf->fontset != None)
683 if (FLCXOMCharset != NULL)
685 flf->fc = FLCXOMCharset;
687 else
689 /* we are here if !HAVE_XOUTPUT_METHOD */
690 XFontStruct **fs_list;
691 char **ml;
693 if (XFontsOfFontSet(
694 flf->fontset, &fs_list, &ml) > 0)
696 flf->fc = FLCXOMCharset =
697 FlocaleCharsetOfFontStruct(
698 dpy, fs_list[0]);
702 else if (flf->font != NULL)
704 flf->fc = FlocaleCharsetOfFontStruct(dpy, flf->font);
707 if (flf->fc != NULL && iconv && *iconv)
709 /* the user has specified an iconv converter name:
710 * check if we have it and force user choice */
711 while(!iconv_found &&
712 FLC_GET_LOCALE_CHARSET(flf->fc,i) != NULL)
714 if (
715 strcmp(
716 iconv,
717 FLC_GET_LOCALE_CHARSET(flf->fc,i)) ==
720 iconv_found = True;
721 /* Trust the user? yes ... */
722 FLC_SET_ICONV_INDEX(flf->fc,i);
724 i++;
727 if (iconv && *iconv && !iconv_found)
729 FlocaleCharset *fc;
731 /* the user has specified an iconv converter name and we do not
732 * have it: must create a FlocaleCharset */
733 flf->flags.must_free_fc = True;
734 fc = (FlocaleCharset *)safemalloc(sizeof(FlocaleCharset));
735 if (flf->fc != NULL)
737 CopyString(&fc->x, flf->fc->x);
738 fc->encoding_type = flf->fc->encoding_type;
739 if (flf->fc->bidi)
740 CopyString(&fc->bidi, flf->fc->bidi);
741 else
742 fc->bidi = NULL;
744 else
746 CopyString(&fc->x, "Unknown"); /* for simplicity */
747 fc->bidi = NULL;
748 fc->encoding_type = FLC_ENCODING_TYPE_FONT;
750 fc->locale = (char **)safemalloc(2*sizeof(char *));
751 CopyString(&fc->locale[0], iconv);
752 fc->locale[1] = NULL;
753 fc->iconv_index = FLC_INDEX_ICONV_CHARSET_NOT_INITIALIZED;
754 flf->fc = fc;
756 if (charset != NULL)
758 free(charset);
760 if (flf->fc == NULL)
762 flf->fc = &UnknownCharset;
765 /* now the string charset */
766 if (encoding != NULL)
768 flf->str_fc = FlocaleCharsetOfXCharset(encoding);
769 if (flf->str_fc == NULL)
771 flf->str_fc = FlocaleCharsetOfLocaleCharset(encoding);
773 if (flf->str_fc == NULL)
775 flf->str_fc = &UnknownCharset;
778 else if (FftSupport && flf->fftf.fftfont != NULL)
780 if (flf->fftf.str_encoding != NULL)
782 flf->str_fc = FlocaleCharsetOfXCharset(
783 flf->fftf.str_encoding);
784 if (flf->str_fc == NULL)
786 flf->str_fc = FlocaleCharsetOfLocaleCharset(
787 flf->fftf.str_encoding);
789 if (flf->str_fc == NULL)
791 flf->str_fc = &UnknownCharset;
794 else
796 flf->str_fc =
797 FlocaleCharsetGetDefaultCharset(dpy, module);
800 if (flf->str_fc == NULL)
802 if (flf->fc != &UnknownCharset)
804 flf->str_fc = flf->fc;
806 else
808 flf->str_fc =
809 FlocaleCharsetGetDefaultCharset(dpy, module);
814 FlocaleCharset *FlocaleCharsetGetDefaultCharset(Display *dpy, char *module)
816 static int warn = True;
818 FlocaleCharsetInit(dpy, module);
820 if (FLCXOMCharset != NULL)
821 return FLCXOMCharset;
822 if (FLCLocaleCharset != NULL)
823 return FLCLocaleCharset;
825 if (warn)
827 warn = False;
828 fprintf(stderr,
829 "[%s][%s]: WARN -- Cannot find default locale "
830 "charset with:\n\t",
831 (module != NULL)? module:"FVWMlibs",
832 "FlocaleGetDefaultCharset");
833 fprintf(stderr,"X Ouput Method ");
834 fprintf(stderr,", CHARSET env variable");
835 if (FlocaleLibcharsetSupport)
836 fprintf(stderr,", locale_charset");
837 if (FlocaleCodesetSupport)
838 fprintf(stderr,", nl_langinfo");
839 fprintf(stderr,"\n");
840 /* never null */
841 FLCLocaleCharset =
842 FlocaleCharsetOfXCharset(FLOCALE_FALLBACK_XCHARSET);
843 fprintf(stderr,"\tUse default charset: %s\n",
844 FLOCALE_FALLBACK_XCHARSET);
847 return FLCLocaleCharset;
850 FlocaleCharset *FlocaleCharsetGetFLCXOMCharset(void)
852 return FLCXOMCharset;
855 FlocaleCharset *FlocaleCharsetGetUtf8Charset(void)
857 return FLCUtf8Charset;
860 FlocaleCharset *FlocaleCharsetGetLocaleCharset(void)
862 return FLCLocaleCharset;
865 FlocaleCharset *FlocaleCharsetGetUnknownCharset(void)
867 return &UnknownCharset;
870 const char *FlocaleGetBidiCharset(Display *dpy, FlocaleCharset *fc)
872 if (fc == NULL || fc == FlocaleCharsetGetUnknownCharset() ||
873 fc->bidi == NULL)
875 return NULL;
877 return (const char *)fc->bidi;
881 FlocaleCharset *FlocaleCharsetGetEUCJPCharset(void)
883 static FlocaleCharset *fc = NULL;
885 if (fc != NULL)
886 return fc;
888 /* never null */
889 fc = FlocaleCharsetOfXCharset("EUC-JP");
890 return fc;
893 Bool FlocaleCharsetIsCharsetXLocale(Display *dpy, char *charset, char *module)
895 #ifdef HAVE_XOUTPUT_METHOD
896 int i;
898 FlocaleCharsetInit(dpy, module);
899 if (FLCXOMCharsetList_num > 0)
901 for(i = 0; i < FLCXOMCharsetList_num; i++)
903 if (StrEquals(
904 FLC_DEBUG_GET_X_CHARSET(
905 FLCXOMCharsetList[i]),
906 charset))
908 return True;
912 return False;
913 #else
914 return True; /* Hum */
915 #endif
918 void FlocaleCharsetPrintXOMInfo(void)
920 #ifdef HAVE_XOUTPUT_METHOD
921 int i;
923 fprintf(stderr," XOM Charsets: ");
924 if (FLCXOMCharsetList_num > 0)
926 for(i = 0; i < FLCXOMCharsetList_num; i++)
928 fprintf(
929 stderr, "%s ",
930 FLC_DEBUG_GET_X_CHARSET(FLCXOMCharsetList[i]));
933 fprintf(stderr,"\n");
934 #endif