12c393a42Smrg/*
2a6844aabSmrg * fontconfig/src/fcinit.c
32c393a42Smrg *
42c393a42Smrg * Copyright © 2001 Keith Packard
52c393a42Smrg *
62c393a42Smrg * Permission to use, copy, modify, distribute, and sell this software and its
72c393a42Smrg * documentation for any purpose is hereby granted without fee, provided that
82c393a42Smrg * the above copyright notice appear in all copies and that both that
92c393a42Smrg * copyright notice and this permission notice appear in supporting
10ca08ab68Smrg * documentation, and that the name of the author(s) not be used in
112c393a42Smrg * advertising or publicity pertaining to distribution of the software without
12ca08ab68Smrg * specific, written prior permission.  The authors make no
132c393a42Smrg * representations about the suitability of this software for any purpose.  It
142c393a42Smrg * is provided "as is" without express or implied warranty.
152c393a42Smrg *
16a6844aabSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
172c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18a6844aabSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
192c393a42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
202c393a42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
212c393a42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
222c393a42Smrg * PERFORMANCE OF THIS SOFTWARE.
232c393a42Smrg */
242c393a42Smrg
252c393a42Smrg#include "fcint.h"
262c393a42Smrg#include <stdlib.h>
272c393a42Smrg
28c9710b42Smrg#if defined(FC_ATOMIC_INT_NIL)
296338c9e2Sriastradh#warning Could not find any system to define atomic_int macros, library may NOT be thread-safe.
30c9710b42Smrg#endif
31c9710b42Smrg#if defined(FC_MUTEX_IMPL_NIL)
326338c9e2Sriastradh#warning Could not find any system to define mutex macros, library may NOT be thread-safe.
33c9710b42Smrg#endif
34c9710b42Smrg#if defined(FC_ATOMIC_INT_NIL) || defined(FC_MUTEX_IMPL_NIL)
356338c9e2Sriastradh#warning To suppress these warnings, define FC_NO_MT.
36c9710b42Smrg#endif
37c9710b42Smrg
382c393a42Smrgstatic FcConfig *
3918bd4a06SmrgFcInitFallbackConfig (const FcChar8 *sysroot)
402c393a42Smrg{
412c393a42Smrg    FcConfig	*config;
421887081fSmrg    const FcChar8 *fallback = (const FcChar8 *) ""	\
431887081fSmrg	"<fontconfig>" \
447872e0a1Smrg	FC_DEFAULT_FONTS \
451887081fSmrg	"  <dir prefix=\"xdg\">fonts</dir>" \
461887081fSmrg	"  <cachedir>" FC_CACHEDIR "</cachedir>" \
471887081fSmrg	"  <cachedir prefix=\"xdg\">fontconfig</cachedir>" \
487872e0a1Smrg	"  <include ignore_missing=\"yes\">" CONFIGDIR "</include>" \
491887081fSmrg	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/conf.d</include>" \
501887081fSmrg	"  <include ignore_missing=\"yes\" prefix=\"xdg\">fontconfig/fonts.conf</include>" \
511887081fSmrg	"</fontconfig>";
522c393a42Smrg
532c393a42Smrg    config = FcConfigCreate ();
542c393a42Smrg    if (!config)
552c393a42Smrg	goto bail0;
5618bd4a06Smrg    FcConfigSetSysRoot (config, sysroot);
571887081fSmrg    if (!FcConfigParseAndLoadFromMemory (config, fallback, FcFalse))
582c393a42Smrg	goto bail1;
591887081fSmrg
602c393a42Smrg    return config;
612c393a42Smrg
622c393a42Smrgbail1:
632c393a42Smrg    FcConfigDestroy (config);
642c393a42Smrgbail0:
652c393a42Smrg    return 0;
662c393a42Smrg}
672c393a42Smrg
682c393a42Smrgint
692c393a42SmrgFcGetVersion (void)
702c393a42Smrg{
712c393a42Smrg    return FC_VERSION;
722c393a42Smrg}
732c393a42Smrg
742c393a42Smrg/*
752c393a42Smrg * Load the configuration files
762c393a42Smrg */
772c393a42SmrgFcConfig *
78c9710b42SmrgFcInitLoadOwnConfig (FcConfig *config)
792c393a42Smrg{
80c9710b42Smrg    if (!config)
81c9710b42Smrg    {
82c9710b42Smrg	config = FcConfigCreate ();
83c9710b42Smrg	if (!config)
84c9710b42Smrg	    return NULL;
85c9710b42Smrg    }
86ca08ab68Smrg
872c393a42Smrg    FcInitDebug ();
88ca08ab68Smrg
892c393a42Smrg    if (!FcConfigParseAndLoad (config, 0, FcTrue))
902c393a42Smrg    {
9118bd4a06Smrg	const FcChar8 *sysroot = FcConfigGetSysRoot (config);
9218bd4a06Smrg	FcConfig *fallback = FcInitFallbackConfig (sysroot);
9318bd4a06Smrg
942c393a42Smrg	FcConfigDestroy (config);
9518bd4a06Smrg
9618bd4a06Smrg	return fallback;
972c393a42Smrg    }
981887081fSmrg    (void) FcConfigParseOnly (config, (const FcChar8 *)FC_TEMPLATEDIR, FcFalse);
99ca08ab68Smrg
1002c393a42Smrg    if (config->cacheDirs && config->cacheDirs->num == 0)
1012c393a42Smrg    {
102c9710b42Smrg	FcChar8 *prefix, *p;
103ca08ab68Smrg	size_t plen;
10418bd4a06Smrg	FcBool have_own = FcFalse;
10518bd4a06Smrg	char *env_file, *env_path;
106ca08ab68Smrg
10718bd4a06Smrg	env_file = getenv ("FONTCONFIG_FILE");
10818bd4a06Smrg	env_path = getenv ("FONTCONFIG_PATH");
10918bd4a06Smrg	if ((env_file != NULL && env_file[0] != 0) ||
11018bd4a06Smrg	    (env_path != NULL && env_path[0] != 0))
11118bd4a06Smrg	    have_own = FcTrue;
11218bd4a06Smrg
11318bd4a06Smrg	if (!have_own)
11418bd4a06Smrg	{
11518bd4a06Smrg	    fprintf (stderr,
11618bd4a06Smrg		     "Fontconfig warning: no <cachedir> elements found. Check configuration.\n");
11718bd4a06Smrg	    fprintf (stderr,
11818bd4a06Smrg		     "Fontconfig warning: adding <cachedir>%s</cachedir>\n",
11918bd4a06Smrg		     FC_CACHEDIR);
12018bd4a06Smrg	}
121ca08ab68Smrg	prefix = FcConfigXdgCacheHome ();
122ca08ab68Smrg	if (!prefix)
123ca08ab68Smrg	    goto bail;
124c9710b42Smrg	plen = strlen ((const char *)prefix);
125c9710b42Smrg	p = realloc (prefix, plen + 12);
126c9710b42Smrg	if (!p)
127ca08ab68Smrg	    goto bail;
128c9710b42Smrg	prefix = p;
129ca08ab68Smrg	memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11);
130ca08ab68Smrg	prefix[plen + 11] = 0;
13118bd4a06Smrg	if (!have_own)
13218bd4a06Smrg	    fprintf (stderr,
13318bd4a06Smrg		     "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n");
134ca08ab68Smrg
1352c393a42Smrg	if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) ||
136ca08ab68Smrg	    !FcConfigAddCacheDir (config, (FcChar8 *) prefix))
1372c393a42Smrg	{
13818bd4a06Smrg	    FcConfig *fallback;
13918bd4a06Smrg	    const FcChar8 *sysroot;
14018bd4a06Smrg
141ca08ab68Smrg	  bail:
14218bd4a06Smrg	    sysroot = FcConfigGetSysRoot (config);
1432c393a42Smrg	    fprintf (stderr,
1442c393a42Smrg		     "Fontconfig error: out of memory");
145c9710b42Smrg	    if (prefix)
146c9710b42Smrg		FcStrFree (prefix);
14718bd4a06Smrg	    fallback = FcInitFallbackConfig (sysroot);
1482c393a42Smrg	    FcConfigDestroy (config);
14918bd4a06Smrg
15018bd4a06Smrg	    return fallback;
1512c393a42Smrg	}
152c9710b42Smrg	FcStrFree (prefix);
1532c393a42Smrg    }
1542c393a42Smrg
1552c393a42Smrg    return config;
1562c393a42Smrg}
1572c393a42Smrg
158c9710b42SmrgFcConfig *
159c9710b42SmrgFcInitLoadConfig (void)
160c9710b42Smrg{
161c9710b42Smrg    return FcInitLoadOwnConfig (NULL);
162c9710b42Smrg}
163c9710b42Smrg
1642c393a42Smrg/*
1652c393a42Smrg * Load the configuration files and scan for available fonts
1662c393a42Smrg */
1672c393a42SmrgFcConfig *
168c9710b42SmrgFcInitLoadOwnConfigAndFonts (FcConfig *config)
1692c393a42Smrg{
170c9710b42Smrg    config = FcInitLoadOwnConfig (config);
1712c393a42Smrg    if (!config)
1722c393a42Smrg	return 0;
1732c393a42Smrg    if (!FcConfigBuildFonts (config))
1742c393a42Smrg    {
1752c393a42Smrg	FcConfigDestroy (config);
1762c393a42Smrg	return 0;
1772c393a42Smrg    }
1782c393a42Smrg    return config;
1792c393a42Smrg}
1802c393a42Smrg
181c9710b42SmrgFcConfig *
182c9710b42SmrgFcInitLoadConfigAndFonts (void)
183c9710b42Smrg{
184c9710b42Smrg    return FcInitLoadOwnConfigAndFonts (NULL);
185c9710b42Smrg}
186c9710b42Smrg
1872c393a42Smrg/*
1882c393a42Smrg * Initialize the default library configuration
1892c393a42Smrg */
1902c393a42SmrgFcBool
1912c393a42SmrgFcInit (void)
1922c393a42Smrg{
193c9710b42Smrg    return FcConfigInit ();
1942c393a42Smrg}
1952c393a42Smrg
1962c393a42Smrg/*
1972c393a42Smrg * Free all library-allocated data structures.
1982c393a42Smrg */
1992c393a42Smrgvoid
2002c393a42SmrgFcFini (void)
2012c393a42Smrg{
202c9710b42Smrg    FcConfigFini ();
2037872e0a1Smrg    FcConfigPathFini ();
204c9710b42Smrg    FcDefaultFini ();
20518bd4a06Smrg    FcObjectFini ();
2067872e0a1Smrg    FcCacheFini ();
2072c393a42Smrg}
2082c393a42Smrg
2092c393a42Smrg/*
2102c393a42Smrg * Reread the configuration and available font lists
2112c393a42Smrg */
2122c393a42SmrgFcBool
2132c393a42SmrgFcInitReinitialize (void)
2142c393a42Smrg{
2152c393a42Smrg    FcConfig	*config;
21618bd4a06Smrg    FcBool	ret;
2172c393a42Smrg
2182c393a42Smrg    config = FcInitLoadConfigAndFonts ();
2192c393a42Smrg    if (!config)
2202c393a42Smrg	return FcFalse;
22118bd4a06Smrg    ret = FcConfigSetCurrent (config);
22218bd4a06Smrg    /* FcConfigSetCurrent() increases the refcount.
22318bd4a06Smrg     * decrease it here to avoid the memory leak.
22418bd4a06Smrg     */
22518bd4a06Smrg    FcConfigDestroy (config);
22618bd4a06Smrg
22718bd4a06Smrg    return ret;
2282c393a42Smrg}
2292c393a42Smrg
2302c393a42SmrgFcBool
2312c393a42SmrgFcInitBringUptoDate (void)
2322c393a42Smrg{
2337872e0a1Smrg    FcConfig	*config = FcConfigReference (NULL);
2347872e0a1Smrg    FcBool	ret = FcTrue;
2352c393a42Smrg    time_t	now;
2362c393a42Smrg
23718bd4a06Smrg    if (!config)
23818bd4a06Smrg	return FcFalse;
2392c393a42Smrg    /*
2402c393a42Smrg     * rescanInterval == 0 disables automatic up to date
2412c393a42Smrg     */
2422c393a42Smrg    if (config->rescanInterval == 0)
2437872e0a1Smrg	goto bail;
2442c393a42Smrg    /*
2452c393a42Smrg     * Check no more often than rescanInterval seconds
2462c393a42Smrg     */
2472c393a42Smrg    now = time (0);
2482c393a42Smrg    if (config->rescanTime + config->rescanInterval - now > 0)
2497872e0a1Smrg	goto bail;
2502c393a42Smrg    /*
2512c393a42Smrg     * If up to date, don't reload configuration
2522c393a42Smrg     */
2532c393a42Smrg    if (FcConfigUptoDate (0))
2547872e0a1Smrg	goto bail;
2557872e0a1Smrg    ret = FcInitReinitialize ();
2567872e0a1Smrgbail:
2577872e0a1Smrg    FcConfigDestroy (config);
2587872e0a1Smrg
2597872e0a1Smrg    return ret;
2602c393a42Smrg}
2612c393a42Smrg
2622c393a42Smrg#define __fcinit__
2632c393a42Smrg#include "fcaliastail.h"
2642c393a42Smrg#undef __fcinit__
265