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 *
39 FcInitFallbackConfig (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
62 bail1:
63 FcConfigDestroy (config);
64 bail0:
65 return 0;
66 }
67
68 int
69 FcGetVersion (void)
70 {
71 return FC_VERSION;
72 }
73
74 /*
75 * Load the configuration files
76 */
77 FcConfig *
78 FcInitLoadOwnConfig (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
158 FcConfig *
159 FcInitLoadConfig (void)
160 {
161 return FcInitLoadOwnConfig (NULL);
162 }
163
164 /*
165 * Load the configuration files and scan for available fonts
166 */
167 FcConfig *
168 FcInitLoadOwnConfigAndFonts (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
181 FcConfig *
182 FcInitLoadConfigAndFonts (void)
183 {
184 return FcInitLoadOwnConfigAndFonts (NULL);
185 }
186
187 /*
188 * Initialize the default library configuration
189 */
190 FcBool
191 FcInit (void)
192 {
193 return FcConfigInit ();
194 }
195
196 /*
197 * Free all library-allocated data structures.
198 */
199 void
200 FcFini (void)
201 {
202 FcConfigFini ();
203 FcConfigPathFini ();
204 FcDefaultFini ();
205 FcObjectFini ();
206 FcCacheFini ();
207 }
208
209 /*
210 * Reread the configuration and available font lists
211 */
212 FcBool
213 FcInitReinitialize (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
230 FcBool
231 FcInitBringUptoDate (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 ();
256 bail:
257 FcConfigDestroy (config);
258
259 return ret;
260 }
261
262 #define __fcinit__
263 #include "fcaliastail.h"
264 #undef __fcinit__