Bug Summary

File:difs/fonts.c
Location:line 803, column 2
Description:Value stored to 'err' is never read

Annotated Source Code

1/*
2 * font control
3 */
4/*
5
6Copyright 1990, 1991, 1998 The Open Group
7
8Permission to use, copy, modify, distribute, and sell this software and its
9documentation for any purpose is hereby granted without fee, provided that
10the above copyright notice appear in all copies and that both that
11copyright notice and this permission notice appear in supporting
12documentation.
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in 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
67static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
68static int num_fpes = 0;
69static FPEFunctions *fpe_functions = (FPEFunctions *) 0;
70static int num_fpe_types = 0;
71
72static int num_slept_fpes = 0;
73static int size_slept_fpes = 0;
74static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
75
76#define NUM_IDS_PER_CLIENT5 5
77
78int
79FontToFSError(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
98static inline void
99UseFPE(FontPathElementPtr fpe)
100{
101 fpe->refcount++;
102}
103
104static inline void
105FreeFPE(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 */
124static void
125QueueFontWakeup(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
153static void
154RemoveFontWakeup(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 */
171static void
172FontWakeup(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
186static Bool
187add_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
207static void
208remove_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
226static FontIDListPtr
227make_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
246static void
247free_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
268static Bool
269do_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 }
407dropout:
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
422int
423OpenFont(
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
545static int
546close_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
562int
563CloseClientFont(
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 */
585static int
586determine_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
596static void
597free_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
607static FontPathElementPtr
608find_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 */
630static int
631set_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;
731bail:
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 */
742int
743SetFontCatalogue(
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
782static Bool
783do_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;
Value stored to 'err' is never read
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;
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
985finish:
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
1028bail:
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
1040int
1041ListFonts(
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;
1093badAlloc:
1094 SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0);
1095 return TRUE1;
1096}
1097
1098static int padlength[4] = {0, 3, 2, 1};
1099static char padding[3];
1100
1101#undef cPtr((LFWXIclosurePtr)data)
1102#define cPtr((LFWXIclosurePtr)data) ((LFWXIclosurePtr)data)
1103
1104static Bool
1105do_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);
1320bail:
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
1332int
1333StartListFontsWithInfo(
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;
1381badAlloc:
1382 SendErrToClientDoSendErrToClient(client, FSBadAlloc9, (pointer) 0);
1383 return TRUE1;
1384}
1385
1386int
1387LoadGlyphRanges(
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
1405int
1406RegisterFPEFunctions(
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
1459FontPtr
1460find_old_font(FSID id)
1461{
1462 return (FontPtr) LookupIDByType(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0));
1463}
1464
1465Font
1466GetNewFontClientID(void)
1467{
1468 return (Font) FakeClientID(SERVER_CLIENT0);
1469}
1470
1471int
1472StoreFontClientFont(
1473 FontPtr pfont,
1474 Font id)
1475{
1476 return AddResource(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0), (pointer) pfont);
1477}
1478
1479void
1480DeleteFontClientID(Font id)
1481{
1482 FreeResource(SERVER_CLIENT0, id, RT_NONE((RESTYPE)0));
1483}
1484
1485static int fs_handlers_installed = 0;
1486static unsigned int last_server_gen;
1487
1488int
1489init_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
1513void
1514remove_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
1534void
1535DeleteClientFontStuff(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}