1 /* $XConsortium: fontpath.c /main/4 1995/10/27 16:13:29 rswiston $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
4 * (c) Copyright 1993, 1994 International Business Machines Corp. *
5 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
6 * (c) Copyright 1993, 1994 Novell, Inc. *
9 ** fontpath.c - font path modification routines
11 ** $fontpath.c,v 1.1 93/06/24 14:52:10 bill Exp $
13 ** Copyright 1993 Hewlett-Packard Company
18 # include <X11/Xatom.h>
28 int ApplyFontPathMods( struct display *d, Display *dpy );
29 void GetSysParms( char **tzpp, char **fhpp, char **ftpp );
30 static int PathInPList(char *path, char **fplist, int listlen);
31 static int PathInZList(char *path, char *fplist, int listlen);
32 static int SeparateParts( char **path );
36 DebugFontPath(char *note, char **path, int nelems)
39 Debug(" %s: %d elements\n",note,nelems);
40 for (i=0; i<nelems; i++)
41 Debug(" %s\n",path[i]);
45 ErrorHandler(Display *dpy, XErrorEvent *event)
47 XmuPrintDefaultErrorMessage(dpy, event, stderr);
48 return 0; /* nonfatal */
51 /* ________________________________________________________________
53 **| ApplyFontPathMods(d) - |
55 **| If new font path mods are mandated, fabricate and apply |
56 **| an appropriate new complete X server font path. |
58 **| Specify: d = pointer to display structure |
60 **| Returns: nothing |
61 **|________________________________________________________________|
65 ApplyFontPathMods( struct display *d, Display *dpy )
71 char **fontPath,**newList;
76 Debug("ApplyFontPathMods() for %s\n",d->name);
78 if (d->displayType.location == Foreign) {
79 Debug(" Foreign display\n");
83 if (!(fontPath=XGetFontPath(dpy, &numPaths))) {
84 Debug(" Can't get font path\n");
89 ** Font path mods can come from (in priority order):
91 ** 1. FONT_PATH_HEAD/TAIL definitions in /etc/src.sh
92 ** 2. fontPathHead/Tail resources
95 GetSysParms(0,&fph,&fpt);
97 if (fph) { s = "sys parm file"; }
98 else if (fpHead) { s = "resource"; fph = strdup(fpHead); }
99 if (fph && !*fph) { free(fph); fph = NULL; }
100 if (fph) Debug(" +fp (%s) %s\n",s,fph);
102 if (fpt) { s = "sys parm file"; }
103 else if (fpTail) { s = "resource"; fpt = strdup(fpTail); }
104 if (fpt && !*fpt) { free(fpt); fpt = NULL; }
105 if (fpt) Debug(" fp+ (%s) %s\n",s,fpt);
108 ** Break up fph and fpt into constituent parts and
109 ** then reconstruct the complete, modified font path.
110 ** During reconstruction we also eliminate redundancies.
113 numHeads = SeparateParts(&fph);
114 numTails = SeparateParts(&fpt);
115 if (numHeads || numTails) {
116 newList = (char **) malloc((numHeads+numPaths+numTails)
119 for (s=fph, i=j=0; j<numHeads; j++) {
120 if (!PathInPList(s,newList,i))
124 for (j=0; j<numPaths; j++) {
125 if (!PathInPList(fontPath[j],newList,i) &&
126 !PathInZList(fontPath[j],fpt,numTails)) {
127 newList[i++] = fontPath[j];
130 for (s=fpt, j=0; j<numTails; j++) {
131 if (!PathInPList(s,newList,i))
136 DebugFontPath("Request (XSetFontPath)",newList,i);
139 ** Tell X server to set new font path now. Log failure,
140 ** but don't let it be fatal. (Note that caller should
141 ** reset error handler to elsewhere when we return.)
144 (void)XSetErrorHandler(ErrorHandler);
145 XSetFontPath(dpy, newList, i);
148 if (debugLevel > 0) {
149 newList = XGetFontPath(dpy, &i);
150 DebugFontPath("Confirm (XGetFontPath)",newList,i);
151 XFreeFontPath(newList);
158 XFreeFontPath(fontPath);
161 /* ___________________________________________________________________
163 **| PathInPList(path,fplist,listlen) - |
165 **| Determine if a specific fontpath element is in a list, |
166 **| taking into account that identical elements may be formed |
167 **| differently (with multiple embedded and trailing slashes). |
169 **| Specify: (char *)path = the single element to be tested |
170 **| (char **)fplist = list of ptrs to asciz elements |
171 **| (int)listlen = number of pointers in the list |
173 **| Returns: TRUE if element is in the list |
174 **|___________________________________________________________________|
178 PathInPList(char *path, char **fplist, int listlen)
181 while (listlen-- > 0) {
182 for (s=path, t=fplist[listlen]; *s && (*s == *t); ) {
183 t++; while (*t == '/') t++;
184 s++; while (*s == '/') s++;
186 if (!*s && !*t) return 1;
191 /* ___________________________________________________________________
193 **| PathInZList(path,fplist,listlen) - |
195 **| Determine if a specific fontpath element is in a list, |
196 **| taking into account that identical elements may be formed |
197 **| differently (with multiple embedded and trailing slashes). |
199 **| Specify: (char *)path = the single element to be tested |
200 **| (char *)fplist = list of concatenated asciz elements |
201 **| (int)listlen = number of elements in the list |
203 **| Returns: TRUE if element is in the list |
204 **|___________________________________________________________________|
208 PathInZList(char *path, char *fplist, int listlen)
211 for (t=fplist; listlen > 0; listlen--) {
212 for (s=path; *s && (*s == *t); ) {
213 t++; while (*t == '/') t++;
214 s++; while (*s == '/') s++;
216 if (!*s && !*t) return 1;
222 /* ________________________________________________________________
224 **| SeparateParts(path) |
226 **| Break a comma-delimited asciz path string into its |
227 **| separate asciz constituent parts. |
229 **| Specify: path = ptr to asciz path string (e.g., "as,df,jk") |
231 **| Returns: number of constituent parts, with path string |
232 **| converted into as many sequential asciz strings |
233 **| (e.g., "as\0df\0jk"). |
234 **|________________________________________________________________|
238 SeparateParts( char **path )
243 for (s=*path; t=strtok(s,","); s=NULL, nparts++);
247 /* ___________________________________________________________________
249 **| GetSysParms(tzpp,fhpp,ftpp) - |
251 **| Extract TZ, FONT_PATH_HEAD, and FONT_PATH_TAIL definitions |
252 **| from the sys parms file (typically /etc/src.sh). |
254 **| Specify: (char **)tzpp = where to put ptr to TZ string |
255 **| (char **)fhpp = where to put ptr to FONT_PATH_HEAD |
256 **| (char **)ftpp = where to put ptr to FONT_PATH_TAIL |
258 **| Specify a NULL (char **) for any undesired strings. |
260 **| Returns: Appropriate pointers to malloc'ed strings (NULL pointer |
261 **| if a string is neither requested nor defined). |
262 **|___________________________________________________________________|
266 GetSysParms( char **tzpp, char **fhpp, char **ftpp )
271 if (tzpp) *tzpp = NULL;
272 if (fhpp) *fhpp = NULL;
273 if (ftpp) *ftpp = NULL;
274 if ((*sysParmsFile != '/') || !(fin=fopen(sysParmsFile,"r"))) {
275 Debug("(GetSysParms) Can't open sys parms file\n");
278 Debug("(GetSysParms) Reading sys parms file\n");
279 while (fgets(buf,255,fin)) {
280 for (t=buf; *t && *t<=' '; t++); /* t -> EOS or nonblank */
281 if (!*t || *t=='#') continue; /* ignore comment lines */
282 while (*t && *t!='\n') t++; /* t -> EOS or newline */
283 if (*t) *t = '\0'; /* discard newline char */
285 if ((s=strstr(buf,"TZ=")) && (t=strtok(s+3,"; \t")))
286 *tzpp = (char *) strdup(t);
288 if ((s=strstr(buf,"FONT_PATH_HEAD=")) && (t=strtok(s+15,"; \t")))
289 *fhpp = (char *) strdup(t);
291 if ((s=strstr(buf,"FONT_PATH_TAIL=")) && (t=strtok(s+15,"; \t")))
292 *ftpp = (char *) strdup(t);