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 #pragma message("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 #pragma message("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 #pragma message("To suppress these warnings, define FC_NO_MT.")
36 #endif
37 
38 static FcConfig *
FcInitFallbackConfig(const FcChar8 * sysroot)39 FcInitFallbackConfig (const FcChar8 *sysroot)
40 {
41     FcConfig	*config;
42     const FcChar8 *fallback = (const FcChar8 *) ""	\
43 	"<fontconfig>" \
44 	"  <dir>" FC_DEFAULT_FONTS "</dir>" \
45 	"  <dir prefix=\"xdg\">fonts</dir>" \
46 	"  <cachedir>" FC_CACHEDIR "</cachedir>" \
47 	"  <cachedir prefix=\"xdg\">fontconfig</cachedir>" \
48 	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/conf.d</include>" \
49 	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/fonts.conf</include>" \
50 	"</fontconfig>";
51 
52     config = FcConfigCreate ();
53     if (!config)
54 	goto bail0;
55     FcConfigSetSysRoot (config, sysroot);
56     if (!FcConfigParseAndLoadFromMemory (config, fallback, FcFalse))
57 	goto bail1;
58 
59     return config;
60 
61 bail1:
62     FcConfigDestroy (config);
63 bail0:
64     return 0;
65 }
66 
67 int
FcGetVersion(void)68 FcGetVersion (void)
69 {
70     return FC_VERSION;
71 }
72 
73 /*
74  * Load the configuration files
75  */
76 FcConfig *
FcInitLoadOwnConfig(FcConfig * config)77 FcInitLoadOwnConfig (FcConfig *config)
78 {
79     if (!config)
80     {
81 	config = FcConfigCreate ();
82 	if (!config)
83 	    return NULL;
84     }
85 
86     FcInitDebug ();
87 
88     if (!FcConfigParseAndLoad (config, 0, FcTrue))
89     {
90 	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
91 	FcConfig *fallback = FcInitFallbackConfig (sysroot);
92 
93 	FcConfigDestroy (config);
94 
95 	return fallback;
96     }
97     (void) FcConfigParseOnly (config, (const FcChar8 *)FC_TEMPLATEDIR, FcFalse);
98 
99     if (config->cacheDirs && config->cacheDirs->num == 0)
100     {
101 	FcChar8 *prefix, *p;
102 	size_t plen;
103 	FcBool have_own = FcFalse;
104 	char *env_file, *env_path;
105 
106 	env_file = getenv ("FONTCONFIG_FILE");
107 	env_path = getenv ("FONTCONFIG_PATH");
108 	if ((env_file != NULL && env_file[0] != 0) ||
109 	    (env_path != NULL && env_path[0] != 0))
110 	    have_own = FcTrue;
111 
112 	if (!have_own)
113 	{
114 	    fprintf (stderr,
115 		     "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
116 	    fprintf (stderr,
117 		     "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
118 		     FC_CACHEDIR);
119 	}
120 	prefix = FcConfigXdgCacheHome ();
121 	if (!prefix)
122 	    goto bail;
123 	plen = strlen ((const char *)prefix);
124 	p = realloc (prefix, plen + 12);
125 	if (!p)
126 	    goto bail;
127 	prefix = p;
128 	memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
129 	prefix[plen + 11] = 0;
130 	if (!have_own)
131 	    fprintf (stderr,
132 		     "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
133 
134 	if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
135 	    !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
136 	{
137 	    FcConfig *fallback;
138 	    const FcChar8 *sysroot;
139 
140 	  bail:
141 	    sysroot = FcConfigGetSysRoot (config);
142 	    fprintf (stderr,
143 		     "Fontconfig error: out of memory");
144 	    if (prefix)
145 		FcStrFree (prefix);
146 	    fallback = FcInitFallbackConfig (sysroot);
147 	    FcConfigDestroy (config);
148 
149 	    return fallback;
150 	}
151 	FcStrFree (prefix);
152     }
153 
154     return config;
155 }
156 
157 FcConfig *
FcInitLoadConfig(void)158 FcInitLoadConfig (void)
159 {
160     return FcInitLoadOwnConfig (NULL);
161 }
162 
163 /*
164  * Load the configuration files and scan for available fonts
165  */
166 FcConfig *
FcInitLoadOwnConfigAndFonts(FcConfig * config)167 FcInitLoadOwnConfigAndFonts (FcConfig *config)
168 {
169     config = FcInitLoadOwnConfig (config);
170     if (!config)
171 	return 0;
172     if (!FcConfigBuildFonts (config))
173     {
174 	FcConfigDestroy (config);
175 	return 0;
176     }
177     return config;
178 }
179 
180 FcConfig *
FcInitLoadConfigAndFonts(void)181 FcInitLoadConfigAndFonts (void)
182 {
183     return FcInitLoadOwnConfigAndFonts (NULL);
184 }
185 
186 /*
187  * Initialize the default library configuration
188  */
189 FcBool
FcInit(void)190 FcInit (void)
191 {
192     return FcConfigInit ();
193 }
194 
195 /*
196  * Free all library-allocated data structures.
197  */
198 void
FcFini(void)199 FcFini (void)
200 {
201     FcConfigFini ();
202     FcCacheFini ();
203     FcDefaultFini ();
204     FcObjectFini ();
205     FcConfigPathFini ();
206 }
207 
208 /*
209  * Reread the configuration and available font lists
210  */
211 FcBool
FcInitReinitialize(void)212 FcInitReinitialize (void)
213 {
214     FcConfig	*config;
215     FcBool	ret;
216 
217     config = FcInitLoadConfigAndFonts ();
218     if (!config)
219 	return FcFalse;
220     ret = FcConfigSetCurrent (config);
221     /* FcConfigSetCurrent() increases the refcount.
222      * decrease it here to avoid the memory leak.
223      */
224     FcConfigDestroy (config);
225 
226     return ret;
227 }
228 
229 FcBool
FcInitBringUptoDate(void)230 FcInitBringUptoDate (void)
231 {
232     FcConfig	*config = FcConfigReference (NULL);
233     FcBool	ret = FcTrue;
234     time_t	now;
235 
236     if (!config)
237 	return FcFalse;
238     /*
239      * rescanInterval == 0 disables automatic up to date
240      */
241     if (config->rescanInterval == 0)
242 	goto bail;
243     /*
244      * Check no more often than rescanInterval seconds
245      */
246     now = time (0);
247     if (config->rescanTime + config->rescanInterval - now > 0)
248 	goto bail;
249     /*
250      * If up to date, don't reload configuration
251      */
252     if (FcConfigUptoDate (0))
253 	goto bail;
254     ret = FcInitReinitialize ();
255 bail:
256     FcConfigDestroy (config);
257 
258     return ret;
259 }
260 
261 #define __fcinit__
262 #include "fcaliastail.h"
263 #undef __fcinit__
264