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