File: | difs/fonts.c |
Location: | line 914, column 4 |
Description: | Value stored to 'err' is never read |
1 | /* |
2 | * font control |
3 | */ |
4 | /* |
5 | |
6 | Copyright 1990, 1991, 1998 The Open Group |
7 | |
8 | Permission to use, copy, modify, distribute, and sell this software and its |
9 | documentation for any purpose is hereby granted without fee, provided that |
10 | the above copyright notice appear in all copies and that both that |
11 | copyright notice and this permission notice appear in supporting |
12 | documentation. |
13 | |
14 | The above copyright notice and this permission notice shall be included in |
15 | all copies or substantial portions of the Software. |
16 | |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
21 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
23 | |
24 | Except as contained in this notice, the name of The Open Group shall not be |
25 | used in advertising or otherwise to promote the sale, use or other dealings |
26 | in this Software without prior written authorization from The Open Group. |
27 | |
28 | * Copyright 1990, 1991 Network Computing Devices; |
29 | * Portions Copyright 1987 by Digital Equipment Corporation |
30 | * |
31 | * Permission to use, copy, modify, distribute, and sell this software and |
32 | * its documentation for any purpose is hereby granted without fee, provided |
33 | * that the above copyright notice appear in all copies and that both that |
34 | * copyright notice and this permission notice appear in supporting |
35 | * documentation, and that the names of Network Computing Devices or Digital |
36 | * not be used in advertising or publicity pertaining to distribution |
37 | * of the software without specific, written prior permission. |
38 | * |
39 | * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH |
40 | * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF |
41 | * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES |
42 | * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL |
43 | * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
44 | * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS |
45 | * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF |
46 | * THIS SOFTWARE. |
47 | */ |
48 | /*#define DEBUG*/ |
49 | |
50 | #include "config.h" |
51 | |
52 | #include <X11/fonts/FS.h> |
53 | #include <X11/fonts/FSproto.h> |
54 | #include <stdio.h> |
55 | #include <stdlib.h> |
56 | #include <X11/Xos.h> |
57 | #include "clientstr.h" |
58 | #include "fsresource.h" |
59 | #include "difsfnst.h" |
60 | #include <X11/fonts/fontstruct.h> |
61 | #include "closestr.h" |
62 | #include "globals.h" |
63 | #include "difs.h" |
64 | #include "dispatch.h" |
65 | #include "swaprep.h" |
66 | |
67 | static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; |
68 | static int num_fpes = 0; |
69 | static FPEFunctions *fpe_functions = (FPEFunctions *) 0; |
70 | static int num_fpe_types = 0; |
71 | |
72 | static int num_slept_fpes = 0; |
73 | static int size_slept_fpes = 0; |
74 | static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; |
75 | |
76 | #define NUM_IDS_PER_CLIENT5 5 |
77 | |
78 | int |
79 | FontToFSError(int err) |
80 | { |
81 | switch (err) { |
82 | case Successful85: |
83 | return FSSuccess-1; |
84 | case AllocError80: |
85 | return FSBadAlloc9; |
86 | case BadFontName83: |
87 | case BadFontPath86: |
88 | return FSBadName7; |
89 | case BadFontFormat88: |
90 | return FSBadFormat1; |
91 | case BadCharRange87: |
92 | return FSBadRange3; |
93 | default: |
94 | return err; |
95 | } |
96 | } |
97 | |
98 | static inline void |
99 | UseFPE(FontPathElementPtr fpe) |
100 | { |
101 | fpe->refcount++; |
102 | } |
103 | |
104 | static inline void |
105 | FreeFPE(FontPathElementPtr fpe) |
106 | { |
107 | fpe->refcount--; |
108 | if (fpe->refcount == 0) { |
109 | (*fpe_functions[fpe->type].free_fpe) (fpe); |
110 | fsfree(fpe->name)FSfree((pointer)fpe->name); |
111 | fsfree(fpe)FSfree((pointer)fpe); |
112 | } |
113 | } |
114 | |
115 | /* |
116 | * note that the font wakeup queue is not refcounted. this is because |
117 | * an fpe needs to be added when it's inited, and removed when it's finally |
118 | * freed, in order to handle any data that isn't requested, like FS events. |
119 | * |
120 | * since the only thing that should call these routines is the renderer's |
121 | * init_fpe() and free_fpe(), there shouldn't be any problem in using |
122 | * freed data. |
123 | */ |
124 | static void |
125 | QueueFontWakeup(FontPathElementPtr fpe) |
126 | { |
127 | int i; |
128 | FontPathElementPtr *new; |
129 | |
130 | for (i = 0; i < num_slept_fpes; i++) { |
131 | if (slept_fpes[i] == fpe) { |
132 | |
133 | #ifdef DEBUG |
134 | fprintf(stderr__stderrp, "re-queueing fpe wakeup\n"); |
135 | #endif |
136 | |
137 | return; |
138 | } |
139 | } |
140 | if (num_slept_fpes == size_slept_fpes) { |
141 | new = (FontPathElementPtr *) |
142 | fsrealloc(slept_fpes,FSrealloc((pointer)slept_fpes, (unsigned long)sizeof(FontPathElementPtr ) * (size_slept_fpes + 4)) |
143 | sizeof(FontPathElementPtr) * (size_slept_fpes + 4))FSrealloc((pointer)slept_fpes, (unsigned long)sizeof(FontPathElementPtr ) * (size_slept_fpes + 4)); |
144 | if (!new) |
145 | return; |
146 | slept_fpes = new; |
147 | size_slept_fpes += 4; |
148 | } |
149 | slept_fpes[num_slept_fpes] = fpe; |
150 | num_slept_fpes++; |
151 | } |
152 | |
153 | static void |
154 | RemoveFontWakeup(FontPathElementPtr fpe) |
155 | { |
156 | int i, |
157 | j; |
158 | |
159 | for (i = 0; i < num_slept_fpes; i++) { |
160 | if (slept_fpes[i] == fpe) { |
161 | for (j = i; j < num_slept_fpes; j++) { |
162 | slept_fpes[j] = slept_fpes[j + 1]; |
163 | } |
164 | num_slept_fpes--; |
165 | return; |
166 | } |
167 | } |
168 | } |
169 | |
170 | /* ARGSUSED */ |
171 | static void |
172 | FontWakeup(pointer data, int count, unsigned long *lastSelectMask) |
173 | { |
174 | int i; |
175 | FontPathElementPtr fpe; |
176 | |
177 | if (count < 0) |
178 | return; /* ignore -1 return from select XXX */ |
179 | /* wake up any fpe's that may be waiting for information */ |
180 | for (i = 0; i < num_slept_fpes; i++) { |
181 | fpe = slept_fpes[i]; |
182 | (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, lastSelectMask); |
183 | } |
184 | } |
185 | |
186 | static Bool |
187 | add_id_to_list(FontIDListPtr ids, Font fid) |
188 | { |
189 | Font *newlist; |
190 | |
191 | /* |
192 | * assumes the list is packed tightly |
193 | */ |
194 | if (ids->num == ids->size) { |
195 | /* increase size of array */ |
196 | newlist = (Font *) fsrealloc(ids->client_list,FSrealloc((pointer)ids->client_list, (unsigned long)sizeof (Font) * (ids->size + 5)) |
197 | sizeof(Font) * (ids->size + NUM_IDS_PER_CLIENT))FSrealloc((pointer)ids->client_list, (unsigned long)sizeof (Font) * (ids->size + 5)); |
198 | if (!newlist) |
199 | return FALSE0; |
200 | ids->client_list = newlist; |
201 | ids->size += NUM_IDS_PER_CLIENT5; |
202 | } |
203 | ids->client_list[ids->num++] = fid; |
204 | return TRUE1; |
205 | } |
206 | |
207 | static void |
208 | remove_id_from_list(FontIDListPtr ids, Font fid) |
209 | { |
210 | int i; |
211 | |
212 | for (i = 0; i < ids->num; i++) { |
213 | if (ids->client_list[i] == fid) { |
214 | /* a memmove() might be better here */ |
215 | while (i < ids->num) { |
216 | ids->client_list[i] = ids->client_list[i + 1]; |
217 | i++; |
218 | } |
219 | ids->num--; |
220 | return; |
221 | } |
222 | } |
223 | assert(0)((void)0); |
224 | } |
225 | |
226 | static FontIDListPtr |
227 | make_clients_id_list(void) |
228 | { |
229 | FontIDListPtr ids; |
230 | Font *fids; |
231 | |
232 | ids = (FontIDListPtr) fsalloc(sizeof(FontIDListRec))FSalloc((unsigned long)sizeof(FontIDListRec)); |
233 | fids = (Font *) fsalloc(sizeof(Font) * NUM_IDS_PER_CLIENT)FSalloc((unsigned long)sizeof(Font) * 5); |
234 | if (!ids || !fids) { |
235 | fsfree(ids)FSfree((pointer)ids); |
236 | fsfree(fids)FSfree((pointer)fids); |
237 | return (FontIDListPtr) 0; |
238 | } |
239 | bzero((char *) fids, sizeof(Font) * NUM_IDS_PER_CLIENT)__builtin___memset_chk ((char *) fids, 0, sizeof(Font) * 5, __builtin_object_size ((char *) fids, 0)); |
240 | ids->client_list = fids; |
241 | ids->size = NUM_IDS_PER_CLIENT5; |
242 | ids->num = 0; |
243 | return ids; |
244 | } |
245 | |
246 | static void |
247 | free_svrPrivate(pointer svrPrivate) |
248 | { |
249 | int i; |
250 | FontIDListPtr *idlist, ids; |
251 | |
252 | idlist = (FontIDListPtr *) svrPrivate; |
253 | if (idlist) { |
254 | for (i = 0; i < MAXCLIENTS128; i++) { |
255 | ids = idlist[i]; |
256 | if (ids) { |
257 | fsfree((char *) ids->client_list)FSfree((pointer)(char *) ids->client_list); |
258 | fsfree((char *) ids)FSfree((pointer)(char *) ids); |
259 | } |
260 | } |
261 | fsfree((char *) idlist)FSfree((pointer)(char *) idlist); |
262 | } |
263 | } |
264 | |
265 | #undef cPtr((LFWXIclosurePtr)data) |
266 | #define cPtr((LFWXIclosurePtr)data) ((OFclosurePtr )data) |
267 | |
268 | static Bool |
269 | do_open_font(ClientPtr client, pointer data) |
270 | { |
271 | FontPtr pfont = NullFont((FontPtr) 0); |
272 | FontPathElementPtr fpe = NULL((void *)0); |
273 | int err = 0; |
274 | int i; |
275 | char *alias, |
276 | *newname; |
277 | int newlen; |
278 | ClientFontPtr cfp; |
279 | Font orig; |
280 | FontIDListPtr *idlist, |
281 | ids; |
282 | int aliascount = 20; |
283 | |
284 | if (client->clientGone == CLIENT_GONE1) { |
285 | if (cPtr((LFWXIclosurePtr)data)->current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
286 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current_fpe]; |
287 | (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); |
288 | } |
289 | err = Successful85; |
290 | goto dropout; |
291 | } |
292 | while (cPtr((LFWXIclosurePtr)data)->current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
293 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current_fpe]; |
294 | err = (*fpe_functions[fpe->type].open_font) |
295 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, cPtr((LFWXIclosurePtr)data)->flags, |
296 | cPtr((LFWXIclosurePtr)data)->fontname, cPtr((LFWXIclosurePtr)data)->fnamelen, cPtr((LFWXIclosurePtr)data)->format, cPtr((LFWXIclosurePtr)data)->format_mask, |
297 | cPtr((LFWXIclosurePtr)data)->fontid, &pfont, &alias, |
298 | cPtr((LFWXIclosurePtr)data)->non_cachable_font && cPtr((LFWXIclosurePtr)data)->non_cachable_font->fpe == fpe ? |
299 | cPtr((LFWXIclosurePtr)data)->non_cachable_font : |
300 | (FontPtr)0); |
301 | |
302 | if (err == FontNameAlias82 && alias) { |
303 | newlen = strlen(alias); |
304 | newname = (char *) fsrealloc(cPtr->fontname, newlen)FSrealloc((pointer)((LFWXIclosurePtr)data)->fontname, (unsigned long)newlen); |
305 | if (!newname) { |
306 | err = AllocError80; |
307 | break; |
308 | } |
309 | memmove( newname, alias, newlen)__builtin___memmove_chk (newname, alias, newlen, __builtin_object_size (newname, 0)); |
310 | cPtr((LFWXIclosurePtr)data)->fontname = newname; |
311 | cPtr((LFWXIclosurePtr)data)->fnamelen = newlen; |
312 | cPtr((LFWXIclosurePtr)data)->current_fpe = 0; |
313 | if (--aliascount <= 0) break; |
314 | continue; |
315 | } |
316 | if (err == BadFontName83) { |
317 | cPtr((LFWXIclosurePtr)data)->current_fpe++; |
318 | continue; |
319 | } |
320 | if (err == Suspended84) { |
321 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
322 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
323 | ClientSleep(client, do_open_font, (pointer) cPtr((LFWXIclosurePtr)data)); |
324 | } |
325 | return TRUE1; |
326 | } |
327 | break; |
328 | } |
329 | if (err != Successful85) { |
330 | goto dropout; |
331 | } |
332 | if (!pfont) { |
333 | err = BadFontName83; |
334 | goto dropout; |
335 | } |
336 | cfp = (ClientFontPtr) fsalloc(sizeof(ClientFontRec))FSalloc((unsigned long)sizeof(ClientFontRec)); |
337 | if (!cfp) { |
338 | err = AllocError80; |
339 | goto dropout; |
340 | } |
341 | cfp->font = pfont; |
342 | cfp->clientindex = cPtr((LFWXIclosurePtr)data)->client->index; |
343 | |
344 | if (fontPatternCache && pfont != cPtr((LFWXIclosurePtr)data)->non_cachable_font) |
345 | CacheFontPattern(fontPatternCache, cPtr((LFWXIclosurePtr)data)->orig_name, cPtr((LFWXIclosurePtr)data)->orig_len, pfont); |
346 | |
347 | /* either pull out the other id or make the array */ |
348 | if (pfont->refcnt != 0) { |
349 | idlist = (FontIDListPtr *) pfont->svrPrivate; |
350 | ids = idlist[cPtr((LFWXIclosurePtr)data)->client->index]; |
351 | if (!ids) { |
352 | ids = make_clients_id_list(); |
353 | if (!ids) { |
354 | err = AllocError80; |
355 | fsfree(cfp)FSfree((pointer)cfp); |
356 | goto dropout; |
357 | } |
358 | idlist[cPtr((LFWXIclosurePtr)data)->client->index] = ids; |
359 | } |
360 | orig = (ids->num > 0) ? ids->client_list[0] : (Font)0; |
361 | } else { |
362 | idlist = (FontIDListPtr *) fsalloc(sizeof(FontIDListPtr) * MAXCLIENTS)FSalloc((unsigned long)sizeof(FontIDListPtr) * 128); |
363 | if (!idlist) { |
364 | err = AllocError80; |
365 | fsfree(cfp)FSfree((pointer)cfp); |
366 | goto dropout; |
367 | } |
368 | ids = make_clients_id_list(); |
369 | if (!ids) { |
370 | err = AllocError80; |
371 | fsfree(idlist)FSfree((pointer)idlist); |
372 | fsfree(cfp)FSfree((pointer)cfp); |
373 | goto dropout; |
374 | } |
375 | bzero((char *) idlist, (sizeof(FontIDListPtr) * MAXCLIENTS))__builtin___memset_chk ((char *) idlist, 0, (sizeof(FontIDListPtr ) * 128), __builtin_object_size ((char *) idlist, 0)); |
376 | idlist[cPtr((LFWXIclosurePtr)data)->client->index] = ids; |
377 | orig = (Font) 0; |
378 | pfont->svrPrivate = (pointer) idlist; |
379 | } |
380 | if (!AddResource(cPtr((LFWXIclosurePtr)data)->client->index, cPtr((LFWXIclosurePtr)data)->fontid, RT_FONT((RESTYPE)1), (pointer) cfp)) { |
381 | fsfree(cfp)FSfree((pointer)cfp); |
382 | free_svrPrivate(pfont->svrPrivate); |
383 | pfont->svrPrivate = (pointer) 0; |
384 | err = AllocError80; |
385 | goto dropout; |
386 | } |
387 | else { |
388 | /* send the reply */ |
389 | fsOpenBitmapFontReply rep = { |
390 | .type = FS_Reply0, |
391 | .otherid_valid = orig ? TRUE1 : FALSE0, |
392 | .sequenceNumber = client->sequence, |
393 | .length = SIZEOF(fsOpenBitmapFontReply)16 >> 2, |
394 | .otherid = orig, |
395 | .cachable = pfont->info.cachable |
396 | }; |
397 | WriteReplyToClient(client,if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &rep ); else (void)WriteToClient(client, (int)(16), (char *)(& rep)); |
398 | SIZEOF(fsOpenBitmapFontReply), &rep)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &rep ); else (void)WriteToClient(client, (int)(16), (char *)(& rep));; |
399 | add_id_to_list(ids, cPtr((LFWXIclosurePtr)data)->fontid); |
400 | if (pfont->refcnt == 0) { |
401 | if (!pfont->fpe) |
402 | pfont->fpe = fpe; |
403 | UseFPE(pfont->fpe); |
404 | } |
405 | pfont->refcnt++; |
406 | } |
407 | dropout: |
408 | if (err != Successful85) { |
409 | SendErrToClientDoSendErrToClient(cPtr((LFWXIclosurePtr)data)->client, FontToFSError(err), (pointer) &(cPtr((LFWXIclosurePtr)data)->fontid)); |
410 | } |
411 | if (cPtr((LFWXIclosurePtr)data)->slept) |
412 | ClientWakeup(cPtr((LFWXIclosurePtr)data)->client); |
413 | for (i = 0; i < cPtr((LFWXIclosurePtr)data)->num_fpes; i++) { |
414 | FreeFPE(cPtr((LFWXIclosurePtr)data)->fpe_list[i]); |
415 | } |
416 | fsfree(cPtr->fpe_list)FSfree((pointer)((LFWXIclosurePtr)data)->fpe_list); |
417 | fsfree(cPtr->fontname)FSfree((pointer)((LFWXIclosurePtr)data)->fontname); |
418 | fsfree(cPtr)FSfree((pointer)((LFWXIclosurePtr)data)); |
419 | return TRUE1; |
420 | } |
421 | |
422 | int |
423 | OpenFont( |
424 | ClientPtr client, |
425 | Font fid, |
426 | fsBitmapFormat format, |
427 | fsBitmapFormatMask format_mask, |
428 | int namelen, |
429 | char *name) |
430 | { |
431 | FontPtr pfont = (FontPtr)0; |
432 | OFclosurePtr c; |
433 | FontIDListPtr *idlist, |
434 | ids; |
435 | int i; |
436 | |
437 | if (namelen == 0 || namelen > XLFDMAXFONTNAMELEN256) { |
438 | SendErrToClientDoSendErrToClient(client, FSBadName7, (pointer) 0); |
439 | return FSBadName7; |
440 | } |
441 | #ifdef DEBUG |
442 | fprintf(stderr__stderrp,"OpenFont: %sn",name); |
443 | #endif |
444 | /* |
445 | ** Check name cache. If we find a cached version of this font that |
446 | ** is cachable, immediately satisfy the request with it. If we find |
447 | ** a cached version of this font that is non-cachable, we do not |
448 | ** satisfy the request with it. Instead, we pass the FontPtr to the |
449 | ** FPE's open_font code (the fontfile FPE in turn passes the |
450 | ** information to the rasterizer; the fserve FPE ignores it). |
451 | ** |
452 | ** Presumably, the font is marked non-cachable because the FPE has |
453 | ** put some licensing restrictions on it. If the FPE, using |
454 | ** whatever logic it relies on, determines that it is willing to |
455 | ** share this existing font with the client, then it has the option |
456 | ** to return the FontPtr we passed it as the newly-opened font. |
457 | ** This allows the FPE to exercise its licensing logic without |
458 | ** having to create another instance of a font that already exists. |
459 | */ |
460 | |
461 | if (fontPatternCache && |
462 | (pfont = FindCachedFontPattern(fontPatternCache, name, namelen)) && |
463 | pfont->info.cachable) { |
464 | ClientFontPtr cfp; |
465 | |
466 | idlist = (FontIDListPtr *) pfont->svrPrivate; |
467 | ids = idlist[client->index]; |
468 | if (!ids) { |
469 | ids = make_clients_id_list(); |
470 | if (!ids) { |
471 | goto lowmem; |
472 | } |
473 | idlist[client->index] = ids; |
474 | } |
475 | cfp = (ClientFontPtr) fsalloc(sizeof(ClientFontRec))FSalloc((unsigned long)sizeof(ClientFontRec)); |
476 | if (!cfp) { |
477 | lowmem: |
478 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
479 | return FSBadAlloc9; |
480 | } |
481 | cfp->font = pfont; |
482 | cfp->clientindex = client->index; |
483 | if (!AddResource(client->index, fid, RT_FONT((RESTYPE)1), (pointer) cfp)) { |
484 | goto lowmem; |
485 | } |
486 | if (!add_id_to_list(ids, fid)) { |
487 | goto lowmem; |
488 | } |
489 | else { |
490 | fsOpenBitmapFontReply rep = { |
491 | .type = FS_Reply0, |
492 | .otherid_valid = (ids->num > 1) ? TRUE1 : FALSE0, |
493 | .sequenceNumber = client->sequence, |
494 | .length = SIZEOF(fsOpenBitmapFontReply)16 >> 2, |
495 | .otherid = (ids->num > 1) ? ids->client_list[0] : 0, |
496 | .cachable = TRUE1 /* XXX */ |
497 | }; |
498 | WriteReplyToClient(client,if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &rep ); else (void)WriteToClient(client, (int)(16), (char *)(& rep)); |
499 | SIZEOF(fsOpenBitmapFontReply), &rep)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &rep ); else (void)WriteToClient(client, (int)(16), (char *)(& rep));; |
500 | pfont->refcnt++; |
501 | return FSSuccess-1; |
502 | } |
503 | } |
504 | c = (OFclosurePtr) fsalloc(sizeof(OFclosureRec))FSalloc((unsigned long)sizeof(OFclosureRec)); |
505 | if (!c) |
506 | goto lowmem; |
507 | c->fontname = (char *) fsalloc(namelen)FSalloc((unsigned long)namelen); |
508 | if (!c->fontname) { |
509 | fsfree(c)FSfree((pointer)c); |
510 | goto lowmem; |
511 | } |
512 | /* |
513 | * copy the current FPE list, so that if it gets changed by another client |
514 | * while we're blocking, the request still appears atomic |
515 | */ |
516 | c->fpe_list = (FontPathElementPtr *) |
517 | fsalloc(sizeof(FontPathElementPtr) * num_fpes)FSalloc((unsigned long)sizeof(FontPathElementPtr) * num_fpes); |
518 | if (!c->fpe_list) { |
519 | fsfree(c->fontname)FSfree((pointer)c->fontname); |
520 | fsfree(c)FSfree((pointer)c); |
521 | goto lowmem; |
522 | } |
523 | memmove( c->fontname, name, namelen)__builtin___memmove_chk (c->fontname, name, namelen, __builtin_object_size (c->fontname, 0)); |
524 | for (i = 0; i < num_fpes; i++) { |
525 | c->fpe_list[i] = font_path_elements[i]; |
526 | UseFPE(c->fpe_list[i]); |
527 | } |
528 | c->client = client; |
529 | c->fontid = fid; |
530 | c->current_fpe = 0; |
531 | c->num_fpes = num_fpes; |
532 | c->fnamelen = namelen; |
533 | c->orig_name = name; |
534 | c->orig_len = namelen; |
535 | c->slept = FALSE0; |
536 | c->flags = (FontLoadInfo0x0001 | FontLoadProps0x0002); |
537 | c->format = format; |
538 | c->format_mask = format_mask; |
539 | c->non_cachable_font = pfont; |
540 | |
541 | (void) do_open_font(client, (pointer) c); |
542 | return FSSuccess-1; |
543 | } |
544 | |
545 | static int |
546 | close_font(FontPtr pfont) |
547 | { |
548 | FontPathElementPtr fpe; |
549 | |
550 | assert(pfont)((void)0); |
551 | if (--pfont->refcnt == 0) { |
552 | if (fontPatternCache) |
553 | RemoveCachedFontPattern(fontPatternCache, pfont); |
554 | fpe = pfont->fpe; |
555 | free_svrPrivate(pfont->svrPrivate); |
556 | (*fpe_functions[fpe->type].close_font) (fpe, pfont); |
557 | FreeFPE(fpe); |
558 | } |
559 | return FSSuccess-1; |
560 | } |
561 | |
562 | int |
563 | CloseClientFont( |
564 | ClientFontPtr cfp, |
565 | FSID fid) |
566 | { |
567 | FontIDListPtr *idlist; |
568 | FontIDListPtr ids; |
569 | int ret; |
570 | |
571 | assert(cfp)((void)0); |
572 | /* clear otherid id */ |
573 | idlist = (FontIDListPtr *) cfp->font->svrPrivate; |
574 | ids = idlist[cfp->clientindex]; |
575 | remove_id_from_list(ids, fid); |
576 | ret = close_font(cfp->font); |
577 | fsfree((char *) cfp)FSfree((pointer)(char *) cfp); |
578 | return ret; |
579 | } |
580 | |
581 | /* |
582 | * search all the known FPE prefixes looking for one to match the given |
583 | * FPE name |
584 | */ |
585 | static int |
586 | determine_fpe_type(char *name) |
587 | { |
588 | int i; |
589 | for (i = 0; i < num_fpe_types; i++) { |
590 | if ((*fpe_functions[i].name_check) (name)) |
591 | return i; |
592 | } |
593 | return -1; |
594 | } |
595 | |
596 | static void |
597 | free_font_path(FontPathElementPtr *list, int n) |
598 | { |
599 | int i; |
600 | |
601 | for (i = 0; i < n; i++) { |
602 | FreeFPE(list[i]); |
603 | } |
604 | fsfree((char *) list)FSfree((pointer)(char *) list); |
605 | } |
606 | |
607 | static FontPathElementPtr |
608 | find_existing_fpe( |
609 | FontPathElementPtr *list, |
610 | int num, |
611 | char *name, |
612 | int len) |
613 | { |
614 | FontPathElementPtr fpe; |
615 | int i; |
616 | |
617 | for (i = 0; i < num; i++) { |
618 | fpe = list[i]; |
619 | if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0) |
620 | return fpe; |
621 | } |
622 | return (FontPathElementPtr) 0; |
623 | } |
624 | |
625 | /* |
626 | * does the work of setting up the fpe list |
627 | * |
628 | * paths should be a counted string |
629 | */ |
630 | static int |
631 | set_font_path_elements( |
632 | int npaths, |
633 | char *paths, |
634 | int *bad) |
635 | { |
636 | int i, validpaths, err = 0; |
637 | int len; |
638 | int type; |
639 | char *cp = paths; |
640 | char *name; |
641 | FontPathElementPtr fpe, *fplist; |
642 | |
643 | fplist = (FontPathElementPtr *) |
644 | fsalloc(sizeof(FontPathElementPtr) * npaths)FSalloc((unsigned long)sizeof(FontPathElementPtr) * npaths); |
645 | if (!fplist) { |
646 | *bad = 0; |
647 | return FSBadAlloc9; |
648 | } |
649 | for (i = 0; i < num_fpe_types; i++) { |
650 | if (fpe_functions[i].set_path_hook) |
651 | (*fpe_functions[i].set_path_hook) (); |
652 | } |
653 | for (i = 0, validpaths = 0; i < npaths; i++) { |
654 | len = *cp++; |
655 | if (len) { |
656 | /* if it's already in our active list, just reset it */ |
657 | /* |
658 | * note that this can miss FPE's in limbo -- may be worth catching |
659 | * them, though it'd muck up refcounting |
660 | */ |
661 | fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len); |
662 | if (fpe) { |
663 | err = (*fpe_functions[fpe->type].reset_fpe) (fpe); |
664 | if (err == Successful85) { |
665 | UseFPE(fpe);/* since it'll be decref'd later when freed |
666 | * from the old list */ |
667 | fplist[validpaths++] = fpe; |
668 | cp += len; |
669 | continue; |
670 | } |
671 | /* can't do it, so act like it's a new one */ |
672 | } |
673 | name = (char *) fsalloc(len + 1)FSalloc((unsigned long)len + 1); |
674 | if (!name) { |
675 | err = FSBadAlloc9; |
676 | goto bail; |
677 | } |
678 | strncpy(name, (char *) cp, len)__builtin___strncpy_chk (name, (char *) cp, len, __builtin_object_size (name, 2 > 1 ? 1 : 0)); |
679 | name[len] = '\0'; |
680 | type = determine_fpe_type(name); |
681 | if (type == -1) |
682 | { |
683 | NoticeF("ignoring font path element %s (bad font path descriptor)\n", name); |
684 | fsfree(name)FSfree((pointer)name); |
685 | cp += len; |
686 | continue; |
687 | } |
688 | /* must be new -- make it */ |
689 | fpe = (FontPathElementPtr) fsalloc(sizeof(FontPathElementRec))FSalloc((unsigned long)sizeof(FontPathElementRec)); |
690 | if (!fpe) { |
691 | fsfree(name)FSfree((pointer)name); |
692 | err = FSBadAlloc9; |
693 | goto bail; |
694 | } |
695 | fpe->type = type; |
696 | fpe->name = name; |
697 | fpe->refcount = 1; |
698 | |
699 | cp += len; |
700 | fpe->name_length = len; |
701 | err = (*fpe_functions[fpe->type].init_fpe) (fpe); |
702 | if (err != Successful85) { |
703 | NoticeF("ignoring font path element %s (unreadable)\n", fpe->name); |
704 | fsfree(fpe->name)FSfree((pointer)fpe->name); |
705 | fsfree(fpe)FSfree((pointer)fpe); |
706 | continue; |
707 | } |
708 | fplist[validpaths++] = fpe; |
709 | } |
710 | } |
711 | if (validpaths < npaths) { |
712 | FontPathElementPtr *ftmp = (FontPathElementPtr *) |
713 | fsrealloc(fplist, sizeof(FontPathElementPtr) * validpaths)FSrealloc((pointer)fplist, (unsigned long)sizeof(FontPathElementPtr ) * validpaths); |
714 | |
715 | if (!ftmp && validpaths) |
716 | goto bail; |
717 | |
718 | fplist = ftmp; |
719 | npaths = validpaths; |
720 | } |
721 | if (validpaths == 0) { |
722 | err = FontToFSError(err); |
723 | goto bail; |
724 | } |
725 | free_font_path(font_path_elements, num_fpes); |
726 | font_path_elements = fplist; |
727 | num_fpes = npaths; |
728 | if (fontPatternCache) |
729 | EmptyFontPatternCache(fontPatternCache); |
730 | return FSSuccess-1; |
731 | bail: |
732 | *bad = validpaths; |
733 | while (--validpaths >= 0) |
734 | FreeFPE(fplist[i]); |
735 | fsfree(fplist)FSfree((pointer)fplist); |
736 | return err; |
737 | } |
738 | |
739 | /* |
740 | * expects comma seperated string |
741 | */ |
742 | int |
743 | SetFontCatalogue( |
744 | char *str, |
745 | int *badpath) |
746 | { |
747 | int len, |
748 | npaths; |
749 | char *paths, |
750 | *end, |
751 | *p; |
752 | int err; |
753 | |
754 | len = strlen(str) + 1; |
755 | paths = p = (char *) ALLOCATE_LOCAL(len)__builtin_alloca((int)(len)); |
756 | npaths = 0; |
757 | |
758 | while (*str) { |
759 | end = index(str, ','); |
760 | if (!end) { |
761 | end = str + strlen(str); |
762 | } |
763 | *p++ = len = end - str; |
764 | memmove( p, str, len)__builtin___memmove_chk (p, str, len, __builtin_object_size ( p, 0)); |
765 | npaths++; |
766 | str += len; /* skip entry */ |
767 | if (*str == ',') |
768 | str++; /* skip any comma */ |
769 | p += len; |
770 | } |
771 | |
772 | err = set_font_path_elements(npaths, paths, badpath); |
773 | |
774 | DEALLOCATE_LOCAL(paths)do {} while(0); |
775 | |
776 | return err; |
777 | } |
778 | |
779 | #undef cPtr((LFWXIclosurePtr)data) |
780 | #define cPtr((LFWXIclosurePtr)data) ((LFclosurePtr)data) |
781 | |
782 | static Bool |
783 | do_list_fonts_and_aliases(ClientPtr client, pointer data) |
784 | { |
785 | FontPathElementPtr fpe; |
786 | int err = Successful85; |
787 | FontNamesPtr names = NULL((void *)0); |
788 | char *name, *resolved; |
789 | int namelen, resolvedlen; |
790 | int nnames; |
791 | int stringLens; |
792 | int i; |
793 | fsListFontsReply reply; |
794 | char *bufptr; |
795 | char *bufferStart; |
796 | int aliascount = 0; |
797 | |
798 | if (client->clientGone == CLIENT_GONE1) { |
799 | if (cPtr((LFWXIclosurePtr)data)->current.current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
800 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current.current_fpe]; |
801 | (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); |
802 | } |
803 | err = Successful85; |
804 | goto bail; |
805 | } |
806 | |
807 | if (!cPtr((LFWXIclosurePtr)data)->current.patlen) |
808 | goto finish; |
809 | |
810 | while (cPtr((LFWXIclosurePtr)data)->current.current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
811 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current.current_fpe]; |
812 | err = Successful85; |
813 | |
814 | if (!fpe_functions[fpe->type].start_list_fonts_and_aliases) |
815 | { |
816 | /* This FPE doesn't support/require list_fonts_and_aliases */ |
817 | |
818 | err = (*fpe_functions[fpe->type].list_fonts) |
819 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, cPtr((LFWXIclosurePtr)data)->current.pattern, |
820 | cPtr((LFWXIclosurePtr)data)->current.patlen, cPtr((LFWXIclosurePtr)data)->current.max_names - cPtr((LFWXIclosurePtr)data)->names->nnames, |
821 | cPtr((LFWXIclosurePtr)data)->names); |
822 | |
823 | if (err == Suspended84) { |
824 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
825 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
826 | ClientSleep(client, do_list_fonts_and_aliases, (pointer) cPtr((LFWXIclosurePtr)data)); |
827 | } |
828 | return TRUE1; |
829 | } |
830 | |
831 | err = BadFontName83; |
832 | } |
833 | else |
834 | { |
835 | /* Start of list_fonts_and_aliases functionality. Modeled |
836 | after list_fonts_with_info in that it resolves aliases, |
837 | except that the information collected from FPEs is just |
838 | names, not font info. Each list_next_font_or_alias() |
839 | returns either a name into name/namelen or an alias into |
840 | name/namelen and its target name into resolved/resolvedlen. |
841 | The code at this level then resolves the alias by polling |
842 | the FPEs. */ |
843 | |
844 | if (!cPtr((LFWXIclosurePtr)data)->current.list_started) { |
845 | err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases) |
846 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, cPtr((LFWXIclosurePtr)data)->current.pattern, |
847 | cPtr((LFWXIclosurePtr)data)->current.patlen, cPtr((LFWXIclosurePtr)data)->current.max_names - cPtr((LFWXIclosurePtr)data)->names->nnames, |
848 | &cPtr((LFWXIclosurePtr)data)->current.private); |
849 | if (err == Suspended84) { |
850 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
851 | ClientSleep(client, do_list_fonts_and_aliases, |
852 | (pointer) cPtr((LFWXIclosurePtr)data)); |
853 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
854 | } |
855 | return TRUE1; |
856 | } |
857 | if (err == Successful85) |
858 | cPtr((LFWXIclosurePtr)data)->current.list_started = TRUE1; |
859 | } |
860 | if (err == Successful85) { |
861 | name = NULL((void *)0); |
862 | err = (*fpe_functions[fpe->type].list_next_font_or_alias) |
863 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, &name, &namelen, &resolved, |
864 | &resolvedlen, cPtr((LFWXIclosurePtr)data)->current.private); |
865 | if (err == Suspended84) { |
866 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
867 | ClientSleep(client, do_list_fonts_and_aliases, |
868 | (pointer) cPtr((LFWXIclosurePtr)data)); |
869 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
870 | } |
871 | return TRUE1; |
872 | } |
873 | } |
874 | |
875 | if (err == Successful85) |
876 | { |
877 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) |
878 | { |
879 | if (cPtr((LFWXIclosurePtr)data)->savedName) |
880 | (void)AddFontNamesName(cPtr((LFWXIclosurePtr)data)->names, cPtr((LFWXIclosurePtr)data)->savedName, |
881 | cPtr((LFWXIclosurePtr)data)->savedNameLen); |
882 | } |
883 | else |
884 | (void)AddFontNamesName(cPtr((LFWXIclosurePtr)data)->names, name, namelen); |
885 | } |
886 | |
887 | /* |
888 | * When we get an alias back, save our state and reset back to |
889 | * the start of the FPE looking for the specified name. As |
890 | * soon as a real font is found for the alias, pop back to the |
891 | * old state |
892 | */ |
893 | else if (err == FontNameAlias82) { |
894 | char tmp_pattern[XLFDMAXFONTNAMELEN256]; |
895 | /* |
896 | * when an alias recurses, we need to give |
897 | * the last FPE a chance to clean up; so we call |
898 | * it again, and assume that the error returned |
899 | * is BadFontName, indicating the alias resolution |
900 | * is complete. |
901 | */ |
902 | memmove(tmp_pattern, resolved, resolvedlen)__builtin___memmove_chk (tmp_pattern, resolved, resolvedlen, __builtin_object_size (tmp_pattern, 0)); |
903 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) |
904 | { |
905 | char *tmpname; |
906 | int tmpnamelen; |
907 | |
908 | tmpname = NULL((void *)0); |
909 | (void) (*fpe_functions[fpe->type].list_next_font_or_alias) |
910 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, &tmpname, &tmpnamelen, |
911 | &tmpname, &tmpnamelen, cPtr((LFWXIclosurePtr)data)->current.private); |
912 | if (--aliascount <= 0) |
913 | { |
914 | err = BadFontName83; |
Value stored to 'err' is never read | |
915 | goto ContBadFontName; |
916 | } |
917 | } |
918 | else |
919 | { |
920 | cPtr((LFWXIclosurePtr)data)->saved = cPtr((LFWXIclosurePtr)data)->current; |
921 | cPtr((LFWXIclosurePtr)data)->haveSaved = TRUE1; |
922 | if (cPtr((LFWXIclosurePtr)data)->savedName) |
923 | fsfree(cPtr->savedName)FSfree((pointer)((LFWXIclosurePtr)data)->savedName); |
924 | cPtr((LFWXIclosurePtr)data)->savedName = (char *)fsalloc(namelen + 1)FSalloc((unsigned long)namelen + 1); |
925 | if (cPtr((LFWXIclosurePtr)data)->savedName) |
926 | memmove(cPtr->savedName, name, namelen + 1)__builtin___memmove_chk (((LFWXIclosurePtr)data)->savedName , name, namelen + 1, __builtin_object_size (((LFWXIclosurePtr )data)->savedName, 0)); |
927 | cPtr((LFWXIclosurePtr)data)->savedNameLen = namelen; |
928 | aliascount = 20; |
929 | } |
930 | memmove(cPtr->current.pattern, tmp_pattern, resolvedlen)__builtin___memmove_chk (((LFWXIclosurePtr)data)->current. pattern, tmp_pattern, resolvedlen, __builtin_object_size (((LFWXIclosurePtr )data)->current.pattern, 0)); |
931 | cPtr((LFWXIclosurePtr)data)->current.patlen = resolvedlen; |
932 | cPtr((LFWXIclosurePtr)data)->current.max_names = cPtr((LFWXIclosurePtr)data)->names->nnames + 1; |
933 | cPtr((LFWXIclosurePtr)data)->current.current_fpe = -1; |
934 | cPtr((LFWXIclosurePtr)data)->current.private = NULL((void *)0); |
935 | err = BadFontName83; |
936 | } |
937 | } |
938 | /* |
939 | * At the end of this FPE, step to the next. If we've finished |
940 | * processing an alias, pop state back. If we've collected enough |
941 | * font names, quit. |
942 | */ |
943 | if (err == BadFontName83) { |
944 | ContBadFontName: ; |
945 | cPtr((LFWXIclosurePtr)data)->current.list_started = FALSE0; |
946 | cPtr((LFWXIclosurePtr)data)->current.current_fpe++; |
947 | err = Successful85; |
948 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) |
949 | { |
950 | /* If we're searching for an alias, limit the search to |
951 | FPE's of the same type as the one the alias came |
952 | from. This is unnecessarily restrictive, but if we |
953 | have both fontfile and fs FPE's, this restriction can |
954 | drastically reduce network traffic to the fs -- else |
955 | we could poll the fs for *every* local alias found; |
956 | on a typical system enabling FILE_NAMES_ALIASES, this |
957 | is significant. */ |
958 | |
959 | while (cPtr((LFWXIclosurePtr)data)->current.current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes && |
960 | cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current.current_fpe]->type != |
961 | cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->saved.current_fpe]->type) |
962 | cPtr((LFWXIclosurePtr)data)->current.current_fpe++; |
963 | |
964 | if (cPtr((LFWXIclosurePtr)data)->names->nnames == cPtr((LFWXIclosurePtr)data)->current.max_names || |
965 | cPtr((LFWXIclosurePtr)data)->current.current_fpe == cPtr((LFWXIclosurePtr)data)->num_fpes) { |
966 | cPtr((LFWXIclosurePtr)data)->haveSaved = FALSE0; |
967 | cPtr((LFWXIclosurePtr)data)->current = cPtr((LFWXIclosurePtr)data)->saved; |
968 | /* Give the saved namelist a chance to clean itself up */ |
969 | continue; |
970 | } |
971 | } |
972 | if (cPtr((LFWXIclosurePtr)data)->names->nnames == cPtr((LFWXIclosurePtr)data)->current.max_names) |
973 | break; |
974 | } |
975 | } |
976 | |
977 | /* |
978 | * send the reply |
979 | */ |
980 | if (err != Successful85) { |
981 | SendErrToClientDoSendErrToClient(client, FontToFSError(err), (pointer) 0); |
982 | goto bail; |
983 | } |
984 | |
985 | finish: |
986 | |
987 | names = cPtr((LFWXIclosurePtr)data)->names; |
988 | nnames = names->nnames; |
989 | client = cPtr((LFWXIclosurePtr)data)->client; |
990 | stringLens = 0; |
991 | for (i = 0; i < nnames; i++) |
992 | stringLens += (names->length[i] <= 255) ? names->length[i] : 0; |
993 | |
994 | reply = (fsListFontsReply) { |
995 | .type = FS_Reply0, |
996 | .sequenceNumber = client->sequence, |
997 | .length = (SIZEOF(fsListFontsReply)16 + stringLens + nnames + 3) >> 2, |
998 | .following = 0, |
999 | .nFonts = nnames |
1000 | }; |
1001 | |
1002 | bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2)__builtin_alloca((int)(reply.length << 2)); |
1003 | |
1004 | if (!bufptr && reply.length) { |
1005 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
1006 | goto bail; |
1007 | } |
1008 | /* |
1009 | * since WriteToClient long word aligns things, copy to temp buffer and |
1010 | * write all at once |
1011 | */ |
1012 | for (i = 0; i < nnames; i++) { |
1013 | if (names->length[i] > 255) |
1014 | reply.nFonts--; |
1015 | else |
1016 | { |
1017 | *bufptr++ = names->length[i]; |
1018 | memmove( bufptr, names->names[i], names->length[i])__builtin___memmove_chk (bufptr, names->names[i], names-> length[i], __builtin_object_size (bufptr, 0)); |
1019 | bufptr += names->length[i]; |
1020 | } |
1021 | } |
1022 | nnames = reply.nFonts; |
1023 | reply.length = (SIZEOF(fsListFontsReply)16 + stringLens + nnames + 3) >> 2; |
1024 | WriteReplyToClient(client, SIZEOF(fsListFontsReply), &reply)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(16), &reply ); else (void)WriteToClient(client, (int)(16), (char *)(& reply));; |
1025 | (void) WriteToClient(client, stringLens + nnames, bufferStart); |
1026 | DEALLOCATE_LOCAL(bufferStart)do {} while(0); |
1027 | |
1028 | bail: |
1029 | if (cPtr((LFWXIclosurePtr)data)->slept) |
1030 | ClientWakeup(client); |
1031 | for (i = 0; i < cPtr((LFWXIclosurePtr)data)->num_fpes; i++) |
1032 | FreeFPE(cPtr((LFWXIclosurePtr)data)->fpe_list[i]); |
1033 | fsfree(cPtr->fpe_list)FSfree((pointer)((LFWXIclosurePtr)data)->fpe_list); |
1034 | if (cPtr((LFWXIclosurePtr)data)->savedName) fsfree(cPtr->savedName)FSfree((pointer)((LFWXIclosurePtr)data)->savedName); |
1035 | FreeFontNames(names); |
1036 | fsfree(cPtr)FSfree((pointer)((LFWXIclosurePtr)data)); |
1037 | return TRUE1; |
1038 | } |
1039 | |
1040 | int |
1041 | ListFonts( |
1042 | ClientPtr client, |
1043 | int length, |
1044 | unsigned char *pattern, |
1045 | int maxNames) |
1046 | { |
1047 | int i; |
1048 | LFclosurePtr c; |
1049 | |
1050 | /* |
1051 | * The right error to return here would be BadName, however the |
1052 | * specification does not allow for a Name error on this request. |
1053 | * Perhaps a better solution would be to return a nil list, i.e. |
1054 | * a list containing zero fontnames. |
1055 | */ |
1056 | if (length > XLFDMAXFONTNAMELEN256) { |
1057 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
1058 | return TRUE1; |
1059 | } |
1060 | |
1061 | if (!(c = (LFclosurePtr) fsalloc(sizeof *c)FSalloc((unsigned long)sizeof *c))) |
1062 | goto badAlloc; |
1063 | c->fpe_list = (FontPathElementPtr *) |
1064 | fsalloc(sizeof(FontPathElementPtr) * num_fpes)FSalloc((unsigned long)sizeof(FontPathElementPtr) * num_fpes); |
1065 | if (!c->fpe_list) { |
1066 | fsfree(c)FSfree((pointer)c); |
1067 | goto badAlloc; |
1068 | } |
1069 | c->names = MakeFontNamesRecord(maxNames < 100 ? maxNames : 100); |
1070 | if (!c->names) |
1071 | { |
1072 | fsfree(c->fpe_list)FSfree((pointer)c->fpe_list); |
1073 | fsfree(c)FSfree((pointer)c); |
1074 | goto badAlloc; |
1075 | } |
1076 | memmove( c->current.pattern, pattern, length)__builtin___memmove_chk (c->current.pattern, pattern, length , __builtin_object_size (c->current.pattern, 0)); |
1077 | for (i = 0; i < num_fpes; i++) { |
1078 | c->fpe_list[i] = font_path_elements[i]; |
1079 | UseFPE(c->fpe_list[i]); |
1080 | } |
1081 | c->client = client; |
1082 | c->num_fpes = num_fpes; |
1083 | c->current.patlen = length; |
1084 | c->current.current_fpe = 0; |
1085 | c->current.max_names = maxNames; |
1086 | c->current.list_started = FALSE0; |
1087 | c->current.private = NULL((void *)0); |
1088 | c->haveSaved = FALSE0; |
1089 | c->slept = FALSE0; |
1090 | c->savedName = NULL((void *)0); |
1091 | do_list_fonts_and_aliases(client, (pointer) c); |
1092 | return TRUE1; |
1093 | badAlloc: |
1094 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
1095 | return TRUE1; |
1096 | } |
1097 | |
1098 | static int padlength[4] = {0, 3, 2, 1}; |
1099 | static char padding[3]; |
1100 | |
1101 | #undef cPtr((LFWXIclosurePtr)data) |
1102 | #define cPtr((LFWXIclosurePtr)data) ((LFWXIclosurePtr)data) |
1103 | |
1104 | static Bool |
1105 | do_list_fonts_with_info(ClientPtr client, pointer data) |
1106 | { |
1107 | FontPathElementPtr fpe; |
1108 | int err = Successful85; |
1109 | char *name; |
1110 | int namelen; |
1111 | int numFonts; |
1112 | FontInfoRec fontInfo, |
1113 | *pFontInfo; |
1114 | fsListFontsWithXInfoReply *reply; |
1115 | int length; |
1116 | fsPropInfo *prop_info; |
1117 | int lenpropdata; |
1118 | int i; |
1119 | int aliascount = 0; |
1120 | |
1121 | if (client->clientGone == CLIENT_GONE1) { |
1122 | if (cPtr((LFWXIclosurePtr)data)->current.current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
1123 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current.current_fpe]; |
1124 | (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); |
1125 | } |
1126 | err = Successful85; |
1127 | goto bail; |
1128 | } |
1129 | while (cPtr((LFWXIclosurePtr)data)->current.current_fpe < cPtr((LFWXIclosurePtr)data)->num_fpes) { |
1130 | fpe = cPtr((LFWXIclosurePtr)data)->fpe_list[cPtr((LFWXIclosurePtr)data)->current.current_fpe]; |
1131 | err = Successful85; |
1132 | if (!cPtr((LFWXIclosurePtr)data)->current.list_started) { |
1133 | err = (*fpe_functions[fpe->type].start_list_fonts_with_info) |
1134 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, cPtr((LFWXIclosurePtr)data)->current.pattern, |
1135 | cPtr((LFWXIclosurePtr)data)->current.patlen, cPtr((LFWXIclosurePtr)data)->current.max_names, |
1136 | &cPtr((LFWXIclosurePtr)data)->current.private); |
1137 | if (err == Suspended84) { |
1138 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
1139 | ClientSleep(client, do_list_fonts_with_info, |
1140 | (pointer) cPtr((LFWXIclosurePtr)data)); |
1141 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
1142 | } |
1143 | return TRUE1; |
1144 | } |
1145 | if (err == Successful85) |
1146 | cPtr((LFWXIclosurePtr)data)->current.list_started = TRUE1; |
1147 | } |
1148 | if (err == Successful85) { |
1149 | name = NULL((void *)0); |
1150 | pFontInfo = &fontInfo; |
1151 | err = (*fpe_functions[fpe->type].list_next_font_with_info) |
1152 | ((pointer) cPtr((LFWXIclosurePtr)data)->client, fpe, &name, &namelen, |
1153 | &pFontInfo, &numFonts, cPtr((LFWXIclosurePtr)data)->current.private); |
1154 | if (err == Suspended84) { |
1155 | if (!cPtr((LFWXIclosurePtr)data)->slept) { |
1156 | ClientSleep(client, do_list_fonts_with_info, |
1157 | (pointer) cPtr((LFWXIclosurePtr)data)); |
1158 | cPtr((LFWXIclosurePtr)data)->slept = TRUE1; |
1159 | } |
1160 | return TRUE1; |
1161 | } |
1162 | } |
1163 | /* |
1164 | * When we get an alias back, save our state and reset back to the |
1165 | * start of the FPE looking for the specified name. As soon as a real |
1166 | * font is found for the alias, pop back to the old state |
1167 | */ |
1168 | if (err == FontNameAlias82) { |
1169 | /* |
1170 | * when an alias recurses, we need to give |
1171 | * the last FPE a chance to clean up; so we call |
1172 | * it again, and assume that the error returned |
1173 | * is BadFontName, indicating the alias resolution |
1174 | * is complete. |
1175 | */ |
1176 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) |
1177 | { |
1178 | char *tmpname; |
1179 | int tmpnamelen; |
1180 | FontInfoPtr tmpFontInfo; |
1181 | |
1182 | tmpname = NULL((void *)0); |
1183 | tmpFontInfo = &fontInfo; |
1184 | (void) (*fpe_functions[fpe->type].list_next_font_with_info) |
1185 | ((pointer) client, fpe, &tmpname, &tmpnamelen, |
1186 | &tmpFontInfo, &numFonts, cPtr((LFWXIclosurePtr)data)->current.private); |
1187 | if (--aliascount <= 0) |
1188 | { |
1189 | err = BadFontName83; |
1190 | goto ContBadFontName; |
1191 | } |
1192 | } |
1193 | else |
1194 | { |
1195 | cPtr((LFWXIclosurePtr)data)->saved = cPtr((LFWXIclosurePtr)data)->current; |
1196 | cPtr((LFWXIclosurePtr)data)->haveSaved = TRUE1; |
1197 | cPtr((LFWXIclosurePtr)data)->savedNumFonts = numFonts; |
1198 | if (cPtr((LFWXIclosurePtr)data)->savedName) |
1199 | fsfree(cPtr->savedName)FSfree((pointer)((LFWXIclosurePtr)data)->savedName); |
1200 | cPtr((LFWXIclosurePtr)data)->savedName = (char *)fsalloc(namelen + 1)FSalloc((unsigned long)namelen + 1); |
1201 | if (cPtr((LFWXIclosurePtr)data)->savedName) |
1202 | memmove(cPtr->savedName, name, namelen + 1)__builtin___memmove_chk (((LFWXIclosurePtr)data)->savedName , name, namelen + 1, __builtin_object_size (((LFWXIclosurePtr )data)->savedName, 0)); |
1203 | aliascount = 20; |
1204 | } |
1205 | memmove(cPtr->current.pattern, name, namelen)__builtin___memmove_chk (((LFWXIclosurePtr)data)->current. pattern, name, namelen, __builtin_object_size (((LFWXIclosurePtr )data)->current.pattern, 0)); |
1206 | cPtr((LFWXIclosurePtr)data)->current.patlen = namelen; |
1207 | cPtr((LFWXIclosurePtr)data)->current.max_names = 1; |
1208 | cPtr((LFWXIclosurePtr)data)->current.current_fpe = 0; |
1209 | cPtr((LFWXIclosurePtr)data)->current.private = NULL((void *)0); |
1210 | cPtr((LFWXIclosurePtr)data)->current.list_started = FALSE0; |
1211 | } |
1212 | /* |
1213 | * At the end of this FPE, step to the next. If we've finished |
1214 | * processing an alias, pop state back. If we've sent enough font |
1215 | * names, quit. |
1216 | */ |
1217 | else if (err == BadFontName83) { |
1218 | ContBadFontName: ; |
1219 | cPtr((LFWXIclosurePtr)data)->current.list_started = FALSE0; |
1220 | cPtr((LFWXIclosurePtr)data)->current.current_fpe++; |
1221 | err = Successful85; |
1222 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) { |
1223 | if (cPtr((LFWXIclosurePtr)data)->current.max_names == 0 || |
1224 | cPtr((LFWXIclosurePtr)data)->current.current_fpe == cPtr((LFWXIclosurePtr)data)->num_fpes) { |
1225 | cPtr((LFWXIclosurePtr)data)->haveSaved = FALSE0; |
1226 | cPtr((LFWXIclosurePtr)data)->saved.max_names -= (1 - cPtr((LFWXIclosurePtr)data)->current.max_names); |
1227 | cPtr((LFWXIclosurePtr)data)->current = cPtr((LFWXIclosurePtr)data)->saved; |
1228 | } |
1229 | } |
1230 | else if (cPtr((LFWXIclosurePtr)data)->current.max_names == 0) |
1231 | break; |
1232 | } else if (err == Successful85) { |
1233 | /* XXX why is it xFontProp ? */ |
1234 | length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp); |
1235 | reply = cPtr((LFWXIclosurePtr)data)->reply; |
1236 | if (cPtr((LFWXIclosurePtr)data)->length < length) { |
1237 | reply = (fsListFontsWithXInfoReply *) fsrealloc(cPtr->reply, length)FSrealloc((pointer)((LFWXIclosurePtr)data)->reply, (unsigned long)length); |
1238 | if (!reply) { |
1239 | err = AllocError80; |
1240 | break; |
1241 | } |
1242 | cPtr((LFWXIclosurePtr)data)->reply = reply; |
1243 | cPtr((LFWXIclosurePtr)data)->length = length; |
1244 | } |
1245 | if (cPtr((LFWXIclosurePtr)data)->haveSaved) { |
1246 | numFonts = cPtr((LFWXIclosurePtr)data)->savedNumFonts; |
1247 | name = cPtr((LFWXIclosurePtr)data)->savedName; |
1248 | namelen = strlen(name); |
1249 | } |
1250 | fsPack_XFontInfoHeader(pFontInfo, reply, client->major_version)(reply)->font_header_flags = ((pFontInfo)->allExist) ? ( 1L << 0) : 0; (reply)->font_header_draw_direction = ( (pFontInfo)->drawDirection == 0) ? 0 : 1; if ((pFontInfo)-> inkInside) (reply)->font_header_flags |= (1L << 1); if (client->major_version > 1) { (reply)->font_hdr_char_range_min_char_high = (pFontInfo)->firstRow; (reply)->font_hdr_char_range_min_char_low = (pFontInfo)->firstCol; (reply)->font_hdr_char_range_max_char_high = (pFontInfo)->lastRow; (reply)->font_hdr_char_range_max_char_low = (pFontInfo)->lastCol; (reply)->font_header_default_char_high = (pFontInfo)->defaultCh >> 8; (reply)->font_header_default_char_low = (pFontInfo)->defaultCh & 0xff; } else { (reply)-> font_hdr_char_range_min_char_high = (pFontInfo)->firstCol; (reply)->font_hdr_char_range_min_char_low = (pFontInfo)-> firstRow; (reply)->font_hdr_char_range_max_char_high = (pFontInfo )->lastCol; (reply)->font_hdr_char_range_max_char_low = (pFontInfo)->lastRow; (reply)->font_header_default_char_high = (pFontInfo)->defaultCh & 0xff; (reply)->font_header_default_char_low = (pFontInfo)->defaultCh >> 8; } (reply)->font_header_min_bounds_left = (&(pFontInfo)->ink_minbounds)->leftSideBearing; ( reply)->font_header_min_bounds_right = (&(pFontInfo)-> ink_minbounds)->rightSideBearing; (reply)->font_header_min_bounds_width = (&(pFontInfo)->ink_minbounds)->characterWidth; ( reply)->font_header_min_bounds_ascent = (&(pFontInfo)-> ink_minbounds)->ascent; (reply)->font_header_min_bounds_descent = (&(pFontInfo)->ink_minbounds)->descent; (reply)-> font_header_min_bounds_attributes = (&(pFontInfo)->ink_minbounds )->attributes; (reply)->font_header_max_bounds_left = ( &(pFontInfo)->ink_maxbounds)->leftSideBearing; (reply )->font_header_max_bounds_right = (&(pFontInfo)->ink_maxbounds )->rightSideBearing; (reply)->font_header_max_bounds_width = (&(pFontInfo)->ink_maxbounds)->characterWidth; ( reply)->font_header_max_bounds_ascent = (&(pFontInfo)-> ink_maxbounds)->ascent; (reply)->font_header_max_bounds_descent = (&(pFontInfo)->ink_maxbounds)->descent; (reply)-> font_header_max_bounds_attributes = (&(pFontInfo)->ink_maxbounds )->attributes; (reply)->font_header_font_ascent = (pFontInfo )->fontAscent; (reply)->font_header_font_descent = (pFontInfo )->fontDescent; |
1251 | err = convert_props(pFontInfo, &prop_info); |
1252 | if (err != Successful85) |
1253 | break; |
1254 | lenpropdata = SIZEOF(fsPropInfo)8 + |
1255 | prop_info->num_offsets * SIZEOF(fsPropOffset)20 + |
1256 | prop_info->data_len; |
1257 | |
1258 | reply->type = FS_Reply0; |
1259 | reply->length = |
1260 | (SIZEOF(fsListFontsWithXInfoReply)(12 + 40) + |
1261 | lenpropdata + namelen + 3) >> 2; |
1262 | reply->sequenceNumber = client->sequence; |
1263 | reply->nameLength = namelen; |
1264 | reply->nReplies = numFonts; |
1265 | WriteReplyToClient(client, SIZEOF(fsListFontsWithXInfoReply), reply)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)((12 + 40)), reply); else (void)WriteToClient(client, (int)((12 + 40)), ( char *)(reply));; |
1266 | if (client->swapped) |
1267 | SwapPropInfo(prop_info); |
1268 | if (client->major_version > 1) |
1269 | { |
1270 | (void)WriteToClientUnpadded(client, lenpropdata, (char *) prop_info); |
1271 | (void)WriteToClientUnpadded(client, namelen, name); |
1272 | (void)WriteToClientUnpadded(client, |
1273 | padlength[(lenpropdata+namelen)&3], |
1274 | padding); |
1275 | } else { |
1276 | (void) WriteToClient(client, namelen, name); |
1277 | (void) WriteToClient(client, lenpropdata, (char *) prop_info); |
1278 | } |
1279 | if (pFontInfo == &fontInfo) { |
1280 | fsfree(fontInfo.props)FSfree((pointer)fontInfo.props); |
1281 | fsfree(fontInfo.isStringProp)FSfree((pointer)fontInfo.isStringProp); |
1282 | } |
1283 | fsfree(prop_info)FSfree((pointer)prop_info); |
1284 | |
1285 | --cPtr((LFWXIclosurePtr)data)->current.max_names; |
1286 | if (cPtr((LFWXIclosurePtr)data)->current.max_names < 0) |
1287 | break; |
1288 | } |
1289 | } |
1290 | |
1291 | /* |
1292 | * send the final reply |
1293 | */ |
1294 | if (err == Successful85) { |
1295 | fsGenericReply *final_reply; |
1296 | |
1297 | final_reply = (fsGenericReply *)cPtr((LFWXIclosurePtr)data)->reply; |
1298 | if (client->major_version > 1) |
1299 | length = SIZEOF(fsGenericReply)8; |
1300 | else |
1301 | length = SIZEOF(fsListFontsWithXInfoReply)(12 + 40); |
1302 | if (cPtr((LFWXIclosurePtr)data)->length < length) { |
1303 | final_reply = (fsGenericReply *) fsrealloc(cPtr->reply, length)FSrealloc((pointer)((LFWXIclosurePtr)data)->reply, (unsigned long)length); |
1304 | if (final_reply) { |
1305 | cPtr((LFWXIclosurePtr)data)->reply = (fsListFontsWithXInfoReply *)final_reply; |
1306 | cPtr((LFWXIclosurePtr)data)->length = length; |
1307 | } else |
1308 | err = AllocError80; |
1309 | } |
1310 | if (err == Successful85) { |
1311 | final_reply->type = FS_Reply0; |
1312 | final_reply->data1 = 0; /* notes that this is final */ |
1313 | final_reply->sequenceNumber = client->sequence; |
1314 | final_reply->length = length >> 2; |
1315 | WriteReplyToClient(client, length, final_reply)if ((client)->swapped) (*ReplySwapVector[((fsReq *)(client )->requestBuffer)->reqType]) (client, (int)(length), final_reply ); else (void)WriteToClient(client, (int)(length), (char *)(final_reply ));; |
1316 | } |
1317 | } |
1318 | if (err != Successful85) |
1319 | SendErrToClientDoSendErrToClient(client, FontToFSError(err), (pointer) 0); |
1320 | bail: |
1321 | if (cPtr((LFWXIclosurePtr)data)->slept) |
1322 | ClientWakeup(client); |
1323 | for (i = 0; i < cPtr((LFWXIclosurePtr)data)->num_fpes; i++) |
1324 | FreeFPE(cPtr((LFWXIclosurePtr)data)->fpe_list[i]); |
1325 | fsfree(cPtr->fpe_list)FSfree((pointer)((LFWXIclosurePtr)data)->fpe_list); |
1326 | if (cPtr((LFWXIclosurePtr)data)->savedName) fsfree(cPtr->savedName)FSfree((pointer)((LFWXIclosurePtr)data)->savedName); |
1327 | fsfree(cPtr->reply)FSfree((pointer)((LFWXIclosurePtr)data)->reply); |
1328 | fsfree(cPtr)FSfree((pointer)((LFWXIclosurePtr)data)); |
1329 | return TRUE1; |
1330 | } |
1331 | |
1332 | int |
1333 | StartListFontsWithInfo( |
1334 | ClientPtr client, |
1335 | int length, |
1336 | unsigned char *pattern, |
1337 | int maxNames) |
1338 | { |
1339 | int i; |
1340 | LFWXIclosurePtr c; |
1341 | |
1342 | /* |
1343 | * The right error to return here would be BadName, however the |
1344 | * specification does not allow for a Name error on this request. |
1345 | * Perhaps a better solution would be to return a nil list, i.e. |
1346 | * a list containing zero fontnames. |
1347 | */ |
1348 | if (length > XLFDMAXFONTNAMELEN256) { |
1349 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
1350 | return TRUE1; |
1351 | } |
1352 | |
1353 | if (!(c = (LFWXIclosurePtr) fsalloc(sizeof *c)FSalloc((unsigned long)sizeof *c))) |
1354 | goto badAlloc; |
1355 | c->fpe_list = (FontPathElementPtr *) |
1356 | fsalloc(sizeof(FontPathElementPtr) * num_fpes)FSalloc((unsigned long)sizeof(FontPathElementPtr) * num_fpes); |
1357 | if (!c->fpe_list) { |
1358 | fsfree(c)FSfree((pointer)c); |
1359 | goto badAlloc; |
1360 | } |
1361 | memmove( c->current.pattern, pattern, length)__builtin___memmove_chk (c->current.pattern, pattern, length , __builtin_object_size (c->current.pattern, 0)); |
1362 | for (i = 0; i < num_fpes; i++) { |
1363 | c->fpe_list[i] = font_path_elements[i]; |
1364 | UseFPE(c->fpe_list[i]); |
1365 | } |
1366 | c->client = client; |
1367 | c->num_fpes = num_fpes; |
1368 | c->reply = NULL((void *)0); |
1369 | c->length = 0; |
1370 | c->current.patlen = length; |
1371 | c->current.current_fpe = 0; |
1372 | c->current.max_names = maxNames; |
1373 | c->current.list_started = FALSE0; |
1374 | c->current.private = NULL((void *)0); |
1375 | c->savedNumFonts = 0; |
1376 | c->haveSaved = FALSE0; |
1377 | c->slept = FALSE0; |
1378 | c->savedName = NULL((void *)0); |
1379 | do_list_fonts_with_info(client, (pointer) c); |
1380 | return TRUE1; |
1381 | badAlloc: |
1382 | SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0); |
1383 | return TRUE1; |
1384 | } |
1385 | |
1386 | int |
1387 | LoadGlyphRanges( |
1388 | ClientPtr client, |
1389 | FontPtr pfont, |
1390 | Bool range_flag, |
1391 | int num_ranges, |
1392 | int item_size, |
1393 | fsChar2b *data) |
1394 | { |
1395 | /* either returns Successful, Suspended, or some nasty error */ |
1396 | if (fpe_functions[pfont->fpe->type].load_glyphs) |
1397 | return (*fpe_functions[pfont->fpe->type].load_glyphs)( |
1398 | (pointer)client, pfont, range_flag, num_ranges, item_size, |
1399 | (unsigned char *)data); |
1400 | else |
1401 | return Successful85; |
1402 | } |
1403 | |
1404 | |
1405 | int |
1406 | RegisterFPEFunctions( |
1407 | NameCheckFunc name_func, |
1408 | InitFpeFunc init_func, |
1409 | FreeFpeFunc free_func, |
1410 | ResetFpeFunc reset_func, |
1411 | OpenFontFunc open_func, |
1412 | CloseFontFunc close_func, |
1413 | ListFontsFunc list_func, |
1414 | StartLfwiFunc start_lfwi_func, |
1415 | NextLfwiFunc next_lfwi_func, |
1416 | WakeupFpeFunc wakeup_func, |
1417 | ClientDiedFunc client_died, |
1418 | LoadGlyphsFunc load_glyphs, |
1419 | StartLaFunc start_list_alias_func, |
1420 | NextLaFunc next_list_alias_func, |
1421 | SetPathFunc set_path_func) |
1422 | { |
1423 | FPEFunctions *new; |
1424 | |
1425 | /* grow the list */ |
1426 | new = (FPEFunctions *) fsrealloc(fpe_functions,FSrealloc((pointer)fpe_functions, (unsigned long)(num_fpe_types + 1) * sizeof(FPEFunctions)) |
1427 | (num_fpe_types + 1) * sizeof(FPEFunctions))FSrealloc((pointer)fpe_functions, (unsigned long)(num_fpe_types + 1) * sizeof(FPEFunctions)); |
1428 | if (!new) |
1429 | return -1; |
1430 | fpe_functions = new; |
1431 | |
1432 | fpe_functions[num_fpe_types].name_check = name_func; |
1433 | fpe_functions[num_fpe_types].open_font = open_func; |
1434 | fpe_functions[num_fpe_types].close_font = close_func; |
1435 | fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func; |
1436 | fpe_functions[num_fpe_types].list_fonts = list_func; |
1437 | fpe_functions[num_fpe_types].start_list_fonts_with_info = |
1438 | start_lfwi_func; |
1439 | fpe_functions[num_fpe_types].list_next_font_with_info = |
1440 | next_lfwi_func; |
1441 | fpe_functions[num_fpe_types].init_fpe = init_func; |
1442 | fpe_functions[num_fpe_types].free_fpe = free_func; |
1443 | fpe_functions[num_fpe_types].reset_fpe = reset_func; |
1444 | |
1445 | fpe_functions[num_fpe_types].client_died = client_died; |
1446 | fpe_functions[num_fpe_types].load_glyphs = load_glyphs; |
1447 | fpe_functions[num_fpe_types].start_list_fonts_and_aliases = |
1448 | start_list_alias_func; |
1449 | fpe_functions[num_fpe_types].list_next_font_or_alias = |
1450 | next_list_alias_func; |
1451 | fpe_functions[num_fpe_types].set_path_hook = set_path_func; |
1452 | |
1453 | return num_fpe_types++; |
1454 | } |
1455 | |
1456 | |
1457 | /* convenience functions for FS interface */ |
1458 | |
1459 | FontPtr |
1460 | find_old_font(FSID id) |
1461 | { |
1462 | return (FontPtr) LookupIDByType(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0)); |
1463 | } |
1464 | |
1465 | Font |
1466 | GetNewFontClientID(void) |
1467 | { |
1468 | return (Font) FakeClientID(SERVER_CLIENT0); |
1469 | } |
1470 | |
1471 | int |
1472 | StoreFontClientFont( |
1473 | FontPtr pfont, |
1474 | Font id) |
1475 | { |
1476 | return AddResource(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0), (pointer) pfont); |
1477 | } |
1478 | |
1479 | void |
1480 | DeleteFontClientID(Font id) |
1481 | { |
1482 | FreeResource(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0)); |
1483 | } |
1484 | |
1485 | static int fs_handlers_installed = 0; |
1486 | static unsigned int last_server_gen; |
1487 | |
1488 | int |
1489 | init_fs_handlers( |
1490 | FontPathElementPtr fpe, |
1491 | BlockHandlerProcPtr block_handler) |
1492 | { |
1493 | /* if server has reset, make sure the b&w handlers are reinstalled */ |
1494 | if (last_server_gen < serverGeneration) { |
1495 | last_server_gen = serverGeneration; |
1496 | fs_handlers_installed = 0; |
1497 | } |
1498 | if (fs_handlers_installed == 0) { |
1499 | |
1500 | #ifdef DEBUG |
1501 | fprintf(stderr__stderrp, "adding FS b & w handlers\n"); |
1502 | #endif |
1503 | |
1504 | if (!RegisterBlockAndWakeupHandlers(block_handler, |
1505 | FontWakeup, (pointer) 0)) |
1506 | return AllocError80; |
1507 | fs_handlers_installed++; |
1508 | } |
1509 | QueueFontWakeup(fpe); |
1510 | return Successful85; |
1511 | } |
1512 | |
1513 | void |
1514 | remove_fs_handlers( |
1515 | FontPathElementPtr fpe, |
1516 | BlockHandlerProcPtr block_handler, |
1517 | Bool all) |
1518 | { |
1519 | if (all) { |
1520 | /* remove the handlers if no one else is using them */ |
1521 | if (--fs_handlers_installed == 0) { |
1522 | |
1523 | #ifdef DEBUG |
1524 | fprintf(stderr__stderrp, "removing FS b & w handlers\n"); |
1525 | #endif |
1526 | |
1527 | RemoveBlockAndWakeupHandlers(block_handler, FontWakeup, |
1528 | (pointer) 0); |
1529 | } |
1530 | } |
1531 | RemoveFontWakeup(fpe); |
1532 | } |
1533 | |
1534 | void |
1535 | DeleteClientFontStuff(ClientPtr client) |
1536 | { |
1537 | int i; |
1538 | FontPathElementPtr fpe; |
1539 | |
1540 | for (i = 0; i < num_fpes; i++) |
1541 | { |
1542 | fpe = font_path_elements[i]; |
1543 | |
1544 | if (fpe_functions[fpe->type].client_died) |
1545 | (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); |
1546 | } |
1547 | } |