upload tizen2.0 source
[framework/uifw/xorg/lib/libx11.git] / src / Font.c
1 /*
2
3 Copyright 1986, 1998  The Open Group
4 Copyright (c) 2000  The XFree86 Project, Inc.
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 X CONSORTIUM OR THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
22
23 Except as contained in this notice, the name of the X Consortium or of the
24 XFree86 Project shall not be used in advertising or otherwise to promote the
25 sale, use or other dealings in this Software without prior written
26 authorization from the X Consortium and the XFree86 Project.
27
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 #include "Xlibint.h"
34
35 #if defined(XF86BIGFONT) && !defined(MUSTCOPY)
36 #define USE_XF86BIGFONT
37 #endif
38 #ifdef USE_XF86BIGFONT
39 #include <sys/types.h>
40 #ifdef HAS_SHM
41 #include <sys/ipc.h>
42 #include <sys/shm.h>
43 #endif
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <X11/extensions/xf86bigfproto.h>
48 #endif
49
50 #include "Xlcint.h"
51 #include "XlcPubI.h"
52
53
54 static XFontStruct *_XQueryFont(
55     Display*            /* dpy */,
56     Font                /* fid */,
57     unsigned long       /* seq */
58 );
59
60 #ifdef USE_XF86BIGFONT
61
62 /* Private data for this extension. */
63 typedef struct {
64     XExtCodes *codes;
65     CARD32 serverSignature;
66     CARD32 serverCapabilities;
67 } XF86BigfontCodes;
68
69 /* Additional bit masks that can be set in serverCapabilities */
70 #define CAP_VerifiedLocal 256
71
72 static XF86BigfontCodes *_XF86BigfontCodes(
73     Display*            /* dpy */
74 );
75
76 static XFontStruct *_XF86BigfontQueryFont(
77     Display*            /* dpy */,
78     XF86BigfontCodes*   /* extcodes */,
79     Font                /* fid */,
80     unsigned long       /* seq */
81 );
82
83 void _XF86BigfontFreeFontMetrics(
84     XFontStruct*        /* fs */
85 );
86
87 #endif /* USE_XF86BIGFONT */
88
89
90 XFontStruct *XLoadQueryFont(
91    register Display *dpy,
92    _Xconst char *name)
93 {
94     XFontStruct *font_result;
95     register long nbytes;
96     Font fid;
97     xOpenFontReq *req;
98     unsigned long seq;
99 #ifdef USE_XF86BIGFONT
100     XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
101 #endif
102
103     if (_XF86LoadQueryLocaleFont(dpy, name, &font_result, (Font *)0))
104       return font_result;
105     LockDisplay(dpy);
106     GetReq(OpenFont, req);
107     seq = dpy->request;
108     nbytes = req->nbytes  = name ? strlen(name) : 0;
109     req->fid = fid = XAllocID(dpy);
110     req->length += (nbytes+3)>>2;
111     Data (dpy, name, nbytes);
112     font_result = NULL;
113 #ifdef USE_XF86BIGFONT
114     if (extcodes) {
115         font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, seq);
116         seq = 0;
117     }
118 #endif
119     if (!font_result)
120         font_result = _XQueryFont(dpy, fid, seq);
121     UnlockDisplay(dpy);
122     SyncHandle();
123     return font_result;
124 }
125
126 XFontStruct *XQueryFont (
127     register Display *dpy,
128     Font fid)
129 {
130     XFontStruct *font_result;
131 #ifdef USE_XF86BIGFONT
132     XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
133 #endif
134
135     LockDisplay(dpy);
136     font_result = NULL;
137 #ifdef USE_XF86BIGFONT
138     if (extcodes) {
139         font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, 0L);
140     }
141 #endif
142     if (!font_result)
143         font_result = _XQueryFont(dpy, fid, 0L);
144     UnlockDisplay(dpy);
145     SyncHandle();
146     return font_result;
147 }
148
149 int
150 XFreeFont(
151     register Display *dpy,
152     XFontStruct *fs)
153 {
154     register xResourceReq *req;
155     register _XExtension *ext;
156
157     LockDisplay(dpy);
158     /* call out to any extensions interested */
159     for (ext = dpy->ext_procs; ext; ext = ext->next)
160         if (ext->free_Font) (*ext->free_Font)(dpy, fs, &ext->codes);
161     GetResReq (CloseFont, fs->fid, req);
162     UnlockDisplay(dpy);
163     SyncHandle();
164     if (fs->per_char) {
165 #ifdef USE_XF86BIGFONT
166         _XF86BigfontFreeFontMetrics(fs);
167 #else
168         Xfree ((char *) fs->per_char);
169 #endif
170     }
171     _XFreeExtData(fs->ext_data);
172     if (fs->properties)
173         Xfree ((char *) fs->properties);
174     Xfree ((char *) fs);
175     return 1;
176 }
177
178
179 static XFontStruct *
180 _XQueryFont (
181     register Display *dpy,
182     Font fid,
183     unsigned long seq)
184 {
185     register XFontStruct *fs;
186     register long nbytes;
187     xQueryFontReply reply;
188     register xResourceReq *req;
189     register _XExtension *ext;
190     _XAsyncHandler async;
191     _XAsyncErrorState async_state;
192
193     if (seq) {
194         async_state.min_sequence_number = seq;
195         async_state.max_sequence_number = seq;
196         async_state.error_code = BadName;
197         async_state.major_opcode = X_OpenFont;
198         async_state.minor_opcode = 0;
199         async_state.error_count = 0;
200         async.next = dpy->async_handlers;
201         async.handler = _XAsyncErrorHandler;
202         async.data = (XPointer)&async_state;
203         dpy->async_handlers = &async;
204     }
205     GetResReq(QueryFont, fid, req);
206     if (!_XReply (dpy, (xReply *) &reply,
207        ((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
208         if (seq)
209             DeqAsyncHandler(dpy, &async);
210         return (XFontStruct *)NULL;
211     }
212     if (seq)
213         DeqAsyncHandler(dpy, &async);
214     if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
215         _XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) +
216                                        reply.nCharInfos * SIZEOF(xCharInfo)));
217         return (XFontStruct *)NULL;
218     }
219     fs->ext_data                = NULL;
220     fs->fid                     = fid;
221     fs->direction               = reply.drawDirection;
222     fs->min_char_or_byte2       = reply.minCharOrByte2;
223     fs->max_char_or_byte2       = reply.maxCharOrByte2;
224     fs->min_byte1               = reply.minByte1;
225     fs->max_byte1               = reply.maxByte1;
226     fs->default_char            = reply.defaultChar;
227     fs->all_chars_exist         = reply.allCharsExist;
228     fs->ascent                  = cvtINT16toInt (reply.fontAscent);
229     fs->descent                 = cvtINT16toInt (reply.fontDescent);
230
231 #ifdef MUSTCOPY
232     {
233         xCharInfo *xcip;
234
235         xcip = (xCharInfo *) &reply.minBounds;
236         fs->min_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing);
237         fs->min_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing);
238         fs->min_bounds.width = cvtINT16toShort(xcip->characterWidth);
239         fs->min_bounds.ascent = cvtINT16toShort(xcip->ascent);
240         fs->min_bounds.descent = cvtINT16toShort(xcip->descent);
241         fs->min_bounds.attributes = xcip->attributes;
242
243         xcip = (xCharInfo *) &reply.maxBounds;
244         fs->max_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing);
245         fs->max_bounds.rbearing =  cvtINT16toShort(xcip->rightSideBearing);
246         fs->max_bounds.width =  cvtINT16toShort(xcip->characterWidth);
247         fs->max_bounds.ascent =  cvtINT16toShort(xcip->ascent);
248         fs->max_bounds.descent =  cvtINT16toShort(xcip->descent);
249         fs->max_bounds.attributes = xcip->attributes;
250     }
251 #else
252     /* XXX the next two statements won't work if short isn't 16 bits */
253     fs->min_bounds = * (XCharStruct *) &reply.minBounds;
254     fs->max_bounds = * (XCharStruct *) &reply.maxBounds;
255 #endif /* MUSTCOPY */
256
257     fs->n_properties = reply.nFontProps;
258     /*
259      * if no properties defined for the font, then it is bad
260      * font, but shouldn't try to read nothing.
261      */
262     fs->properties = NULL;
263     if (fs->n_properties > 0) {
264             nbytes = reply.nFontProps * sizeof(XFontProp);
265             fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes);
266             nbytes = reply.nFontProps * SIZEOF(xFontProp);
267             if (! fs->properties) {
268                 Xfree((char *) fs);
269                 _XEatData(dpy, (unsigned long)
270                           (nbytes + reply.nCharInfos * SIZEOF(xCharInfo)));
271                 return (XFontStruct *)NULL;
272             }
273             _XRead32 (dpy, (long *)fs->properties, nbytes);
274     }
275     /*
276      * If no characters in font, then it is a bad font, but
277      * shouldn't try to read nothing.
278      */
279     /* have to unpack charinfos on some machines (CRAY) */
280     fs->per_char = NULL;
281     if (reply.nCharInfos > 0){
282         nbytes = reply.nCharInfos * sizeof(XCharStruct);
283         if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) {
284             if (fs->properties) Xfree((char *) fs->properties);
285             Xfree((char *) fs);
286             _XEatData(dpy, (unsigned long)
287                             (reply.nCharInfos * SIZEOF(xCharInfo)));
288             return (XFontStruct *)NULL;
289         }
290
291 #ifdef MUSTCOPY
292         {
293             register XCharStruct *cs = fs->per_char;
294             register int i;
295
296             for (i = 0; i < reply.nCharInfos; i++, cs++) {
297                 xCharInfo xcip;
298
299                 _XRead(dpy, (char *)&xcip, SIZEOF(xCharInfo));
300                 cs->lbearing = cvtINT16toShort(xcip.leftSideBearing);
301                 cs->rbearing = cvtINT16toShort(xcip.rightSideBearing);
302                 cs->width =  cvtINT16toShort(xcip.characterWidth);
303                 cs->ascent =  cvtINT16toShort(xcip.ascent);
304                 cs->descent =  cvtINT16toShort(xcip.descent);
305                 cs->attributes = xcip.attributes;
306             }
307         }
308 #else
309         nbytes = reply.nCharInfos * SIZEOF(xCharInfo);
310         _XRead16 (dpy, (char *)fs->per_char, nbytes);
311 #endif
312     }
313
314     /* call out to any extensions interested */
315     for (ext = dpy->ext_procs; ext; ext = ext->next)
316         if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes);
317     return fs;
318 }
319
320 #ifdef USE_XF86BIGFONT
321
322 /* Magic cookie for finding the right XExtData structure on the display's
323    extension list. */
324 static int XF86BigfontNumber = 1040697125;
325
326 static int
327 _XF86BigfontFreeCodes (
328     XExtData *extension)
329 {
330     /* Don't Xfree(extension->private_data) because it is on the same malloc
331        chunk as extension. */
332     /* Don't Xfree(extension->private_data->codes) because this is shared with
333        the display's ext_procs list. */
334     return 0;
335 }
336
337 static XF86BigfontCodes *
338 _XF86BigfontCodes (
339     register Display *dpy)
340 {
341     XEDataObject dpy_union;
342     XExtData *pData;
343     XF86BigfontCodes *pCodes;
344     char *envval;
345
346     dpy_union.display = dpy;
347
348     /* If the server is known to support the XF86Bigfont extension,
349      * return the extension codes. If the server is known to not support
350      * the extension, don't bother checking again.
351      */
352     pData = XFindOnExtensionList(XEHeadOfExtensionList(dpy_union),
353                                  XF86BigfontNumber);
354     if (pData)
355         return (XF86BigfontCodes *) pData->private_data;
356
357     pData = (XExtData *) Xmalloc(sizeof(XExtData) + sizeof(XF86BigfontCodes));
358     if (!pData) {
359         /* Out of luck. */
360         return (XF86BigfontCodes *) NULL;
361     }
362
363     /* See if the server supports the XF86Bigfont extension. */
364     envval = getenv("XF86BIGFONT_DISABLE"); /* Let the user disable it. */
365     if (envval != NULL && envval[0] != '\0')
366         pCodes = NULL;
367     else {
368         XExtCodes *codes = XInitExtension(dpy, XF86BIGFONTNAME);
369         if (codes == NULL)
370             pCodes = NULL;
371         else {
372             pCodes = (XF86BigfontCodes *) &pData[1];
373             pCodes->codes = codes;
374         }
375     }
376     pData->number = XF86BigfontNumber;
377     pData->private_data = (XPointer) pCodes;
378     pData->free_private = _XF86BigfontFreeCodes;
379     XAddToExtensionList(XEHeadOfExtensionList(dpy_union), pData);
380     if (pCodes) {
381         int result;
382
383         /* See if the server supports the XF86BigfontQueryFont request. */
384         xXF86BigfontQueryVersionReply reply;
385         register xXF86BigfontQueryVersionReq *req;
386
387         LockDisplay(dpy);
388
389         GetReq(XF86BigfontQueryVersion, req);
390         req->reqType = pCodes->codes->major_opcode;
391         req->xf86bigfontReqType = X_XF86BigfontQueryVersion;
392
393         result = _XReply (dpy, (xReply *) &reply,
394                 (SIZEOF(xXF86BigfontQueryVersionReply) - SIZEOF(xReply)) >> 2,
395                 xFalse);
396
397         UnlockDisplay(dpy);
398         SyncHandle();
399
400         if(!result)
401             goto ignore_extension;
402
403         /* No need to provide backward compatibility with version 1.0. It
404            was never widely distributed. */
405         if (!(reply.majorVersion > 1
406               || (reply.majorVersion == 1 && reply.minorVersion >= 1)))
407             goto ignore_extension;
408
409         pCodes->serverSignature = reply.signature;
410         pCodes->serverCapabilities = reply.capabilities;
411     }
412     return pCodes;
413
414   ignore_extension:
415     /* No need to Xfree(pCodes) or Xfree(pCodes->codes), see
416        _XF86BigfontFreeCodes comment. */
417     pCodes = (XF86BigfontCodes *) NULL;
418     pData->private_data = (XPointer) pCodes;
419     return pCodes;
420 }
421
422 static int
423 _XF86BigfontFreeNop (
424     XExtData *extension)
425 {
426     return 0;
427 }
428
429 static XFontStruct *
430 _XF86BigfontQueryFont (
431     register Display *dpy,
432     XF86BigfontCodes *extcodes,
433     Font fid,
434     unsigned long seq)
435 {
436     register XFontStruct *fs;
437     register long nbytes;
438     xXF86BigfontQueryFontReply reply;
439     register xXF86BigfontQueryFontReq *req;
440     register _XExtension *ext;
441     _XAsyncHandler async1;
442     _XAsyncErrorState async1_state;
443     _XAsyncHandler async2;
444     _XAsyncErrorState async2_state;
445
446     if (seq) {
447         async1_state.min_sequence_number = seq;
448         async1_state.max_sequence_number = seq;
449         async1_state.error_code = BadName;
450         async1_state.major_opcode = X_OpenFont;
451         async1_state.minor_opcode = 0;
452         async1_state.error_count = 0;
453         async1.next = dpy->async_handlers;
454         async1.handler = _XAsyncErrorHandler;
455         async1.data = (XPointer)&async1_state;
456         dpy->async_handlers = &async1;
457     }
458
459     GetReq(XF86BigfontQueryFont, req);
460     req->reqType = extcodes->codes->major_opcode;
461     req->xf86bigfontReqType = X_XF86BigfontQueryFont;
462     req->id = fid;
463     req->flags = (extcodes->serverCapabilities & XF86Bigfont_CAP_LocalShm
464                   ? XF86Bigfont_FLAGS_Shm : 0);
465
466     /* The function _XQueryFont benefits from a "magic" error handler for
467        BadFont coming from a X_QueryFont request. (See function _XReply.)
468        We have to establish an error handler ourselves. */
469     async2_state.min_sequence_number = dpy->request;
470     async2_state.max_sequence_number = dpy->request;
471     async2_state.error_code = BadFont;
472     async2_state.major_opcode = extcodes->codes->major_opcode;
473     async2_state.minor_opcode = X_XF86BigfontQueryFont;
474     async2_state.error_count = 0;
475     async2.next = dpy->async_handlers;
476     async2.handler = _XAsyncErrorHandler;
477     async2.data = (XPointer)&async2_state;
478     dpy->async_handlers = &async2;
479
480     if (!_XReply (dpy, (xReply *) &reply,
481        ((SIZEOF(xXF86BigfontQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
482         DeqAsyncHandler(dpy, &async2);
483         if (seq)
484             DeqAsyncHandler(dpy, &async1);
485         return (XFontStruct *)NULL;
486     }
487     DeqAsyncHandler(dpy, &async2);
488     if (seq)
489         DeqAsyncHandler(dpy, &async1);
490     if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
491         _XEatData(dpy,
492                   reply.nFontProps * SIZEOF(xFontProp)
493                   + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1)
494                      ? reply.nUniqCharInfos * SIZEOF(xCharInfo)
495                        + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16)
496                      : 0));
497         return (XFontStruct *)NULL;
498     }
499     fs->ext_data                = NULL;
500     fs->fid                     = fid;
501     fs->direction               = reply.drawDirection;
502     fs->min_char_or_byte2       = reply.minCharOrByte2;
503     fs->max_char_or_byte2       = reply.maxCharOrByte2;
504     fs->min_byte1               = reply.minByte1;
505     fs->max_byte1               = reply.maxByte1;
506     fs->default_char            = reply.defaultChar;
507     fs->all_chars_exist         = reply.allCharsExist;
508     fs->ascent                  = cvtINT16toInt (reply.fontAscent);
509     fs->descent                 = cvtINT16toInt (reply.fontDescent);
510
511     /* XXX the next two statements won't work if short isn't 16 bits */
512     fs->min_bounds = * (XCharStruct *) &reply.minBounds;
513     fs->max_bounds = * (XCharStruct *) &reply.maxBounds;
514
515     fs->n_properties = reply.nFontProps;
516     /*
517      * if no properties defined for the font, then it is bad
518      * font, but shouldn't try to read nothing.
519      */
520     fs->properties = NULL;
521     if (fs->n_properties > 0) {
522         nbytes = reply.nFontProps * sizeof(XFontProp);
523         fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes);
524         nbytes = reply.nFontProps * SIZEOF(xFontProp);
525         if (! fs->properties) {
526             Xfree((char *) fs);
527             _XEatData(dpy,
528                       nbytes
529                       + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1)
530                          ? reply.nUniqCharInfos * SIZEOF(xCharInfo)
531                            + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16)
532                          : 0));
533             return (XFontStruct *)NULL;
534         }
535         _XRead32 (dpy, (long *)fs->properties, nbytes);
536     }
537
538     fs->per_char = NULL;
539     if (reply.nCharInfos > 0) {
540         /* fprintf(stderr, "received font metrics, nCharInfos = %d, nUniqCharInfos = %d, shmid = %d\n", reply.nCharInfos, reply.nUniqCharInfos, reply.shmid); */
541         if (reply.shmid == (CARD32)(-1)) {
542             xCharInfo* pUniqCI;
543             CARD16* pIndex2UniqIndex;
544             int i;
545
546             nbytes = reply.nUniqCharInfos * SIZEOF(xCharInfo)
547                      + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16);
548             pUniqCI = (xCharInfo *) Xmalloc (nbytes);
549             if (!pUniqCI) {
550                 if (fs->properties) Xfree((char *) fs->properties);
551                 Xfree((char *) fs);
552                 _XEatData(dpy, nbytes);
553                 return (XFontStruct *)NULL;
554             }
555             if (! (fs->per_char = (XCharStruct *) Xmalloc (reply.nCharInfos * sizeof(XCharStruct)))) {
556                 Xfree((char *) pUniqCI);
557                 if (fs->properties) Xfree((char *) fs->properties);
558                 Xfree((char *) fs);
559                 _XEatData(dpy, nbytes);
560                 return (XFontStruct *)NULL;
561             }
562             _XRead16 (dpy, (char *) pUniqCI, nbytes);
563             pIndex2UniqIndex = (CARD16*) (pUniqCI + reply.nUniqCharInfos);
564             for (i = 0; i < reply.nCharInfos; i++) {
565                 if (pIndex2UniqIndex[i] >= reply.nUniqCharInfos) {
566                     fprintf(stderr, "_XF86BigfontQueryFont: server returned wrong data\n");
567                     Xfree((char *) pUniqCI);
568                     if (fs->properties) Xfree((char *) fs->properties);
569                     Xfree((char *) fs);
570                     return (XFontStruct *)NULL;
571                 }
572                 /* XXX the next statement won't work if short isn't 16 bits */
573                 fs->per_char[i] = * (XCharStruct *) &pUniqCI[pIndex2UniqIndex[i]];
574             }
575             Xfree((char *) pUniqCI);
576         } else {
577 #ifdef HAS_SHM
578             XExtData *pData;
579             XEDataObject fs_union;
580             char *addr;
581
582             pData = (XExtData *) Xmalloc(sizeof(XExtData));
583             if (!pData) {
584                 if (fs->properties) Xfree((char *) fs->properties);
585                 Xfree((char *) fs);
586                 return (XFontStruct *)NULL;
587             }
588
589             /* In some cases (e.g. an ssh daemon forwarding an X session to
590                a remote machine) it is possible that the X server thinks we
591                are running on the same machine (because getpeername() and
592                LocalClient() cannot know about the forwarding) but we are
593                not really local. Therefore, when we attach the first shared
594                memory segment, we verify that we are on the same machine as
595                the X server by checking that 1. shmat() succeeds, 2. the
596                segment has a sufficient size, 3. it contains the X server's
597                signature. Then we set the CAP_VerifiedLocal bit to indicate
598                the verification was successful. */
599
600             if ((addr = shmat(reply.shmid, NULL, SHM_RDONLY)) == (char *)-1) {
601                 if (extcodes->serverCapabilities & CAP_VerifiedLocal)
602                     fprintf(stderr, "_XF86BigfontQueryFont: could not attach shm segment\n");
603                 Xfree((char *) pData);
604                 if (fs->properties) Xfree((char *) fs->properties);
605                 Xfree((char *) fs);
606                 /* Stop requesting shared memory transport from now on. */
607                 extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
608                 return (XFontStruct *)NULL;
609             }
610
611             if (!(extcodes->serverCapabilities & CAP_VerifiedLocal)) {
612                 struct shmid_ds buf;
613                 if (!(shmctl(reply.shmid, IPC_STAT, &buf) >= 0
614                       && buf.shm_segsz >= reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct) + sizeof(CARD32)
615                       && *(CARD32 *)(addr + reply.shmsegoffset + reply.nCharInfos * sizeof(XCharStruct)) == extcodes->serverSignature)) {
616                     shmdt(addr);
617                     Xfree((char *) pData);
618                     if (fs->properties) Xfree((char *) fs->properties);
619                     Xfree((char *) fs);
620                     /* Stop requesting shared memory transport from now on. */
621                     extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
622                     return (XFontStruct *)NULL;
623                 }
624                 extcodes->serverCapabilities |= CAP_VerifiedLocal;
625             }
626
627             pData->number = XF86BigfontNumber;
628             pData->private_data = (XPointer) addr;
629             pData->free_private = _XF86BigfontFreeNop;
630             fs_union.font = fs;
631             XAddToExtensionList(XEHeadOfExtensionList(fs_union), pData);
632
633             fs->per_char = (XCharStruct *) (addr + reply.shmsegoffset);
634 #else
635             fprintf(stderr, "_XF86BigfontQueryFont: try recompiling libX11 with HasShm, Xserver has shm support\n");
636             if (fs->properties) Xfree((char *) fs->properties);
637             Xfree((char *) fs);
638             /* Stop requesting shared memory transport from now on. */
639             extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
640             return (XFontStruct *)NULL;
641 #endif
642         }
643     }
644
645     /* call out to any extensions interested */
646     for (ext = dpy->ext_procs; ext; ext = ext->next)
647         if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes);
648     return fs;
649 }
650
651 void
652 _XF86BigfontFreeFontMetrics (XFontStruct *fs)
653 {
654 #ifdef HAS_SHM
655     XExtData *pData;
656     XEDataObject fs_union;
657
658     fs_union.font = fs;
659     if ((pData = XFindOnExtensionList(XEHeadOfExtensionList(fs_union),
660                                       XF86BigfontNumber)))
661         shmdt ((char *) pData->private_data);
662     else
663         Xfree ((char *) fs->per_char);
664 #else
665     Xfree ((char *) fs->per_char);
666 #endif
667 }
668
669 #endif /* USE_XF86BIGFONT */
670
671 int _XF86LoadQueryLocaleFont(
672    Display *dpy,
673    _Xconst char *name,
674    XFontStruct **xfp,
675    Font *fidp)
676 {
677     int l;
678     const char *charset, *p;
679     char buf[256];
680     XFontStruct *fs;
681     XLCd lcd;
682
683     if (!name)
684         return 0;
685     l = strlen(name);
686     if (l < 2 || name[l - 1] != '*' || name[l - 2] != '-')
687         return 0;
688     charset = NULL;
689     /* next three lines stolen from _XkbGetCharset() */
690     lcd = _XlcCurrentLC();
691     if ((lcd = _XlcCurrentLC()) != 0)
692         charset = XLC_PUBLIC(lcd, encoding_name);
693     if (!charset || (p = strrchr(charset, '-')) == 0 || p == charset || p[1] == 0 || (p[1] == '*' && p[2] == 0)) {
694         /* prefer latin1 if no encoding found */
695         charset = "ISO8859-1";
696         p = charset + 7;
697     }
698     if (l - 2 - (p - charset) < 0)
699         return 0;
700     if (_XlcNCompareISOLatin1(name + l - 2 - (p - charset), charset, p - charset))
701         return 0;
702     if (strlen(p + 1) + l - 1 >= sizeof(buf) - 1)
703         return 0;
704     strcpy(buf, name);
705     strcpy(buf + l - 1, p + 1);
706     fs = XLoadQueryFont(dpy, buf);
707     if (!fs)
708         return 0;
709     if (xfp) {
710         *xfp = fs;
711         if (fidp)
712             *fidp = fs->fid;
713     } else if (fidp) {
714         if (fs->per_char) {
715 #ifdef USE_XF86BIGFONT
716             _XF86BigfontFreeFontMetrics(fs);
717 #else
718             Xfree ((char *) fs->per_char);
719 #endif
720         }
721         _XFreeExtData(fs->ext_data);
722         if (fs->properties)
723             Xfree ((char *) fs->properties);
724         *fidp = fs->fid;
725         Xfree ((char *) fs);
726     } else {
727         XFreeFont(dpy, fs);
728     }
729     return 1;
730 }