1/*
2 * Copyright 1992, 1993 by TOSHIBA Corp.
3 *
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of TOSHIBA not be used in advertising
9 * or publicity pertaining to distribution of the software without specific,
10 * written prior permission. TOSHIBA make no representations about the
11 * suitability of this software for any purpose.  It is provided "as is"
12 * without express or implied warranty.
13 *
14 * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16 * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20 * SOFTWARE.
21 *
22 * Author: Katsuhisa Yano	TOSHIBA Corp.
23 *			   	mopi@osa.ilab.toshiba.co.jp
24 */
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29#include <stdio.h>
30#include "Xlibint.h"
31#include "XlcPubI.h"
32
33static const char *
34default_string(
35    XLCd lcd)
36{
37    return XLC_PUBLIC(lcd, default_string);
38}
39
40static XLCd create (const char *name, XLCdMethods methods);
41static Bool initialize (XLCd lcd);
42static void destroy (XLCd lcd);
43static char *get_values (XLCd lcd, XlcArgList args, int num_args);
44
45static XLCdPublicMethodsRec publicMethods = {
46    {
47	destroy,
48	_XlcDefaultMapModifiers,
49	NULL,
50	NULL,
51	_XrmDefaultInitParseInfo,
52	_XmbTextPropertyToTextList,
53	_XwcTextPropertyToTextList,
54	_Xutf8TextPropertyToTextList,
55	_XmbTextListToTextProperty,
56	_XwcTextListToTextProperty,
57	_Xutf8TextListToTextProperty,
58	_XwcFreeStringList,
59	default_string,
60	NULL,
61	NULL
62    },
63    {
64	NULL,
65	create,
66	initialize,
67	destroy,
68	get_values,
69	_XlcGetLocaleDataBase
70    }
71};
72
73XLCdMethods _XlcPublicMethods = (XLCdMethods) &publicMethods;
74
75static XLCd
76create(
77    const char *name,
78    XLCdMethods methods)
79{
80    XLCd lcd;
81    XLCdPublicMethods new;
82
83    lcd = Xcalloc(1, sizeof(XLCdRec));
84    if (lcd == NULL)
85        return (XLCd) NULL;
86
87    lcd->core = Xcalloc(1, sizeof(XLCdPublicRec));
88    if (lcd->core == NULL)
89	goto err;
90
91    new = Xmalloc(sizeof(XLCdPublicMethodsRec));
92    if (new == NULL)
93	goto err;
94    memcpy(new,methods,sizeof(XLCdPublicMethodsRec));
95    lcd->methods = (XLCdMethods) new;
96
97    return lcd;
98
99err:
100    Xfree(lcd->core);
101    Xfree(lcd);
102    return (XLCd) NULL;
103}
104
105static Bool
106load_public(
107    XLCd lcd)
108{
109    XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
110    char **values;
111    const char *str;
112    int num;
113
114    if(_XlcCreateLocaleDataBase(lcd) == NULL)
115	return False;
116
117    _XlcGetResource(lcd, "XLC_XLOCALE", "mb_cur_max", &values, &num);
118    if (num > 0) {
119	pub->mb_cur_max = atoi(values[0]);
120	if (pub->mb_cur_max < 1)
121	    pub->mb_cur_max = 1;
122    } else
123	pub->mb_cur_max = 1;
124
125    _XlcGetResource(lcd, "XLC_XLOCALE", "state_depend_encoding", &values, &num);
126    if (num > 0 && !_XlcCompareISOLatin1(values[0], "True"))
127	pub->is_state_depend = True;
128    else
129	pub->is_state_depend = False;
130
131    _XlcGetResource(lcd, "XLC_XLOCALE", "encoding_name", &values, &num);
132    str = (num > 0) ? values[0] : "STRING";
133    pub->encoding_name = strdup(str);
134    if (pub->encoding_name == NULL)
135	return False;
136
137    return True;
138}
139
140static Bool
141initialize_core(
142    XLCd lcd)
143{
144    XLCdMethods methods = lcd->methods;
145    XLCdMethods core = &publicMethods.core;
146
147    if (methods->close == NULL)
148	methods->close = core->close;
149
150    if (methods->map_modifiers == NULL)
151	methods->map_modifiers = core->map_modifiers;
152
153    if (methods->open_om == NULL)
154#ifdef USE_DYNAMIC_LC
155	_XInitDefaultOM(lcd);
156#else
157	_XInitOM(lcd);
158#endif
159
160    if (methods->open_im == NULL)
161#ifdef USE_DYNAMIC_LC
162	_XInitDefaultIM(lcd);
163#else
164	_XInitIM(lcd);
165#endif
166
167    if (methods->init_parse_info == NULL)
168	methods->init_parse_info = core->init_parse_info;
169
170    if (methods->mb_text_prop_to_list == NULL)
171	methods->mb_text_prop_to_list = core->mb_text_prop_to_list;
172
173    if (methods->wc_text_prop_to_list == NULL)
174	methods->wc_text_prop_to_list = core->wc_text_prop_to_list;
175
176    if (methods->utf8_text_prop_to_list == NULL)
177	methods->utf8_text_prop_to_list = core->utf8_text_prop_to_list;
178
179    if (methods->mb_text_list_to_prop == NULL)
180	methods->mb_text_list_to_prop = core->mb_text_list_to_prop;
181
182    if (methods->wc_text_list_to_prop == NULL)
183	methods->wc_text_list_to_prop = core->wc_text_list_to_prop;
184
185    if (methods->utf8_text_list_to_prop == NULL)
186	methods->utf8_text_list_to_prop = core->utf8_text_list_to_prop;
187
188    if (methods->wc_free_string_list == NULL)
189	methods->wc_free_string_list = core->wc_free_string_list;
190
191    if (methods->default_string == NULL)
192	methods->default_string = core->default_string;
193
194    return True;
195}
196
197static Bool
198initialize(
199    XLCd lcd)
200{
201    XLCdPublicMethodsPart *methods = XLC_PUBLIC_METHODS(lcd);
202    XLCdPublicMethodsPart *pub_methods = &publicMethods.pub;
203    XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
204    char *name;
205#if !defined(X_LOCALE)
206    int len;
207    char sinamebuf[256];
208    char* siname;
209#endif
210
211    _XlcInitCTInfo();
212
213    if (initialize_core(lcd) == False)
214	return False;
215
216    name = lcd->core->name;
217#if !defined(X_LOCALE)
218    /*
219     * _XlMapOSLocaleName will return the same string or a substring
220     * of name, so strlen(name) is okay
221     */
222    if ((len = (int) strlen(name)) < sizeof sinamebuf)
223        siname = sinamebuf;
224    else
225        siname = Xmalloc (len + 1);
226    if (siname == NULL)
227        return False;
228    name = _XlcMapOSLocaleName(name, siname);
229#endif
230    /* _XlcResolveLocaleName will lookup the SI's name for the locale */
231    if (_XlcResolveLocaleName(name, pub) == 0) {
232#if !defined(X_LOCALE)
233	if (siname != sinamebuf) Xfree (siname);
234#endif
235	return False;
236    }
237#if !defined(X_LOCALE)
238    if (siname != sinamebuf)
239        Xfree (siname);
240#endif
241
242    if (pub->default_string == NULL)
243	pub->default_string = "";
244
245    if (methods->get_values == NULL)
246	methods->get_values = pub_methods->get_values;
247
248    if (methods->get_resource == NULL)
249	methods->get_resource = pub_methods->get_resource;
250
251    return load_public(lcd);
252}
253
254static void
255destroy_core(
256    XLCd lcd)
257{
258    if (lcd) {
259        if (lcd->core) {
260            Xfree(lcd->core->name);
261            Xfree(lcd->core->modifiers);
262            Xfree(lcd->core);
263        }
264        Xfree(lcd->methods);
265        Xfree(lcd);
266    }
267}
268
269static void
270destroy(
271    XLCd lcd)
272{
273    XLCdPublicPart *pub = XLC_PUBLIC_PART(lcd);
274
275    _XlcDestroyLocaleDataBase(lcd);
276
277    Xfree(pub->siname);
278    Xfree(pub->encoding_name);
279
280    destroy_core(lcd);
281}
282
283static XlcResource resources[] = {
284    { XlcNCodeset, NULLQUARK, sizeof(char *),
285      XOffsetOf(XLCdPublicRec, pub.codeset), XlcGetMask },
286    { XlcNDefaultString, NULLQUARK, sizeof(char *),
287      XOffsetOf(XLCdPublicRec, pub.default_string), XlcGetMask },
288    { XlcNEncodingName, NULLQUARK, sizeof(char *),
289      XOffsetOf(XLCdPublicRec, pub.encoding_name), XlcGetMask },
290    { XlcNLanguage, NULLQUARK, sizeof(char *),
291      XOffsetOf(XLCdPublicRec, pub.language), XlcGetMask },
292    { XlcNMbCurMax, NULLQUARK, sizeof(int),
293      XOffsetOf(XLCdPublicRec, pub.mb_cur_max), XlcGetMask },
294    { XlcNStateDependentEncoding, NULLQUARK, sizeof(Bool),
295      XOffsetOf(XLCdPublicRec, pub.is_state_depend), XlcGetMask },
296    { XlcNTerritory, NULLQUARK, sizeof(char *),
297      XOffsetOf(XLCdPublicRec, pub.territory), XlcGetMask }
298};
299
300static char *
301get_values(
302    XLCd lcd,
303    XlcArgList args,
304    int num_args)
305{
306    XLCdPublic pub = (XLCdPublic) lcd->core;
307
308    if (resources[0].xrm_name == NULLQUARK)
309	_XlcCompileResourceList(resources, XlcNumber(resources));
310
311    return _XlcGetValues((XPointer) pub, resources, XlcNumber(resources), args,
312			 num_args, XlcGetMask);
313}
314