1/*
2 * fontconfig/src/fcinit.c
3 *
4 * Copyright © 2001 Keith Packard
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of the author(s) not be used in
11 * advertising or publicity pertaining to distribution of the software without
12 * specific, written prior permission.  The authors make no
13 * representations about the suitability of this software for any purpose.  It
14 * is provided "as is" without express or implied warranty.
15 *
16 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22 * PERFORMANCE OF THIS SOFTWARE.
23 */
24
25#include "fcint.h"
26#include <stdlib.h>
27
28#if defined(FC_ATOMIC_INT_NIL)
29#warning Could not find any system to define atomic_int macros, library may NOT be thread-safe.
30#endif
31#if defined(FC_MUTEX_IMPL_NIL)
32#warning Could not find any system to define mutex macros, library may NOT be thread-safe.
33#endif
34#if defined(FC_ATOMIC_INT_NIL) || defined(FC_MUTEX_IMPL_NIL)
35#warning To suppress these warnings, define FC_NO_MT.
36#endif
37
38static FcConfig *
39FcInitFallbackConfig (const FcChar8 *sysroot)
40{
41    FcConfig	*config;
42    const FcChar8 *fallback = (const FcChar8 *) ""	\
43	"<fontconfig>" \
44	FC_DEFAULT_FONTS \
45	"  <dir prefix=\"xdg\">fonts</dir>" \
46	"  <cachedir>" FC_CACHEDIR "</cachedir>" \
47	"  <cachedir prefix=\"xdg\">fontconfig</cachedir>" \
48	"  <include ignore_missing=\"yes\">" CONFIGDIR "</include>" \
49	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/conf.d</include>" \
50	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/fonts.conf</include>" \
51	"</fontconfig>";
52
53    config = FcConfigCreate ();
54    if (!config)
55	goto bail0;
56    FcConfigSetSysRoot (config, sysroot);
57    if (!FcConfigParseAndLoadFromMemory (config, fallback, FcFalse))
58	goto bail1;
59
60    return config;
61
62bail1:
63    FcConfigDestroy (config);
64bail0:
65    return 0;
66}
67
68int
69FcGetVersion (void)
70{
71    return FC_VERSION;
72}
73
74/*
75 * Load the configuration files
76 */
77FcConfig *
78FcInitLoadOwnConfig (FcConfig *config)
79{
80    if (!config)
81    {
82	config = FcConfigCreate ();
83	if (!config)
84	    return NULL;
85    }
86
87    FcInitDebug ();
88
89    if (!FcConfigParseAndLoad (config, 0, FcTrue))
90    {
91	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
92	FcConfig *fallback = FcInitFallbackConfig (sysroot);
93
94	FcConfigDestroy (config);
95
96	return fallback;
97    }
98    (void) FcConfigParseOnly (config, (const FcChar8 *)FC_TEMPLATEDIR, FcFalse);
99
100    if (config->cacheDirs && config->cacheDirs->num == 0)
101    {
102	FcChar8 *prefix, *p;
103	size_t plen;
104	FcBool have_own = FcFalse;
105	char *env_file, *env_path;
106
107	env_file = getenv ("FONTCONFIG_FILE");
108	env_path = getenv ("FONTCONFIG_PATH");
109	if ((env_file != NULL && env_file[0] != 0) ||
110	    (env_path != NULL && env_path[0] != 0))
111	    have_own = FcTrue;
112
113	if (!have_own)
114	{
115	    fprintf (stderr,
116		     "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
117	    fprintf (stderr,
118		     "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
119		     FC_CACHEDIR);
120	}
121	prefix = FcConfigXdgCacheHome ();
122	if (!prefix)
123	    goto bail;
124	plen = strlen ((const char *)prefix);
125	p = realloc (prefix, plen + 12);
126	if (!p)
127	    goto bail;
128	prefix = p;
129	memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
130	prefix[plen + 11] = 0;
131	if (!have_own)
132	    fprintf (stderr,
133		     "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
134
135	if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
136	    !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
137	{
138	    FcConfig *fallback;
139	    const FcChar8 *sysroot;
140
141	  bail:
142	    sysroot = FcConfigGetSysRoot (config);
143	    fprintf (stderr,
144		     "Fontconfig error: out of memory");
145	    if (prefix)
146		FcStrFree (prefix);
147	    fallback = FcInitFallbackConfig (sysroot);
148	    FcConfigDestroy (config);
149
150	    return fallback;
151	}
152	FcStrFree (prefix);
153    }
154
155    return config;
156}
157
158FcConfig *
159FcInitLoadConfig (void)
160{
161    return FcInitLoadOwnConfig (NULL);
162}
163
164/*
165 * Load the configuration files and scan for available fonts
166 */
167FcConfig *
168FcInitLoadOwnConfigAndFonts (FcConfig *config)
169{
170    config = FcInitLoadOwnConfig (config);
171    if (!config)
172	return 0;
173    if (!FcConfigBuildFonts (config))
174    {
175	FcConfigDestroy (config);
176	return 0;
177    }
178    return config;
179}
180
181FcConfig *
182FcInitLoadConfigAndFonts (void)
183{
184    return FcInitLoadOwnConfigAndFonts (NULL);
185}
186
187/*
188 * Initialize the default library configuration
189 */
190FcBool
191FcInit (void)
192{
193    return FcConfigInit ();
194}
195
196/*
197 * Free all library-allocated data structures.
198 */
199void
200FcFini (void)
201{
202    FcConfigFini ();
203    FcConfigPathFini ();
204    FcDefaultFini ();
205    FcObjectFini ();
206    FcCacheFini ();
207}
208
209/*
210 * Reread the configuration and available font lists
211 */
212FcBool
213FcInitReinitialize (void)
214{
215    FcConfig	*config;
216    FcBool	ret;
217
218    config = FcInitLoadConfigAndFonts ();
219    if (!config)
220	return FcFalse;
221    ret = FcConfigSetCurrent (config);
222    /* FcConfigSetCurrent() increases the refcount.
223     * decrease it here to avoid the memory leak.
224     */
225    FcConfigDestroy (config);
226
227    return ret;
228}
229
230FcBool
231FcInitBringUptoDate (void)
232{
233    FcConfig	*config = FcConfigReference (NULL);
234    FcBool	ret = FcTrue;
235    time_t	now;
236
237    if (!config)
238	return FcFalse;
239    /*
240     * rescanInterval == 0 disables automatic up to date
241     */
242    if (config->rescanInterval == 0)
243	goto bail;
244    /*
245     * Check no more often than rescanInterval seconds
246     */
247    now = time (0);
248    if (config->rescanTime + config->rescanInterval - now > 0)
249	goto bail;
250    /*
251     * If up to date, don't reload configuration
252     */
253    if (FcConfigUptoDate (0))
254	goto bail;
255    ret = FcInitReinitialize ();
256bail:
257    FcConfigDestroy (config);
258
259    return ret;
260}
261
262#define __fcinit__
263#include "fcaliastail.h"
264#undef __fcinit__
265