3 Copyright 1986, 1998 The Open Group
4 Copyright (c) 2000 The XFree86 Project, Inc.
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
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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
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.
35 #if defined(XF86BIGFONT) && !defined(MUSTCOPY)
36 #define USE_XF86BIGFONT
38 #ifdef USE_XF86BIGFONT
39 #include <sys/types.h>
47 #include <X11/extensions/xf86bigfproto.h>
54 static XFontStruct *_XQueryFont(
57 unsigned long /* seq */
60 #ifdef USE_XF86BIGFONT
62 /* Private data for this extension. */
65 CARD32 serverSignature;
66 CARD32 serverCapabilities;
69 /* Additional bit masks that can be set in serverCapabilities */
70 #define CAP_VerifiedLocal 256
72 static XF86BigfontCodes *_XF86BigfontCodes(
76 static XFontStruct *_XF86BigfontQueryFont(
78 XF86BigfontCodes* /* extcodes */,
80 unsigned long /* seq */
83 void _XF86BigfontFreeFontMetrics(
87 #endif /* USE_XF86BIGFONT */
90 XFontStruct *XLoadQueryFont(
91 register Display *dpy,
94 XFontStruct *font_result;
99 #ifdef USE_XF86BIGFONT
100 XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
103 if (_XF86LoadQueryLocaleFont(dpy, name, &font_result, (Font *)0))
106 GetReq(OpenFont, req);
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);
113 #ifdef USE_XF86BIGFONT
115 font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, seq);
120 font_result = _XQueryFont(dpy, fid, seq);
126 XFontStruct *XQueryFont (
127 register Display *dpy,
130 XFontStruct *font_result;
131 #ifdef USE_XF86BIGFONT
132 XF86BigfontCodes *extcodes = _XF86BigfontCodes(dpy);
137 #ifdef USE_XF86BIGFONT
139 font_result = _XF86BigfontQueryFont(dpy, extcodes, fid, 0L);
143 font_result = _XQueryFont(dpy, fid, 0L);
151 register Display *dpy,
154 register xResourceReq *req;
155 register _XExtension *ext;
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);
165 #ifdef USE_XF86BIGFONT
166 _XF86BigfontFreeFontMetrics(fs);
168 Xfree ((char *) fs->per_char);
171 _XFreeExtData(fs->ext_data);
173 Xfree ((char *) fs->properties);
181 register Display *dpy,
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;
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;
205 GetResReq(QueryFont, fid, req);
206 if (!_XReply (dpy, (xReply *) &reply,
207 ((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
209 DeqAsyncHandler(dpy, &async);
210 return (XFontStruct *)NULL;
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;
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);
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;
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;
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 */
257 fs->n_properties = reply.nFontProps;
259 * if no properties defined for the font, then it is bad
260 * font, but shouldn't try to read nothing.
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) {
269 _XEatData(dpy, (unsigned long)
270 (nbytes + reply.nCharInfos * SIZEOF(xCharInfo)));
271 return (XFontStruct *)NULL;
273 _XRead32 (dpy, (long *)fs->properties, nbytes);
276 * If no characters in font, then it is a bad font, but
277 * shouldn't try to read nothing.
279 /* have to unpack charinfos on some machines (CRAY) */
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);
286 _XEatData(dpy, (unsigned long)
287 (reply.nCharInfos * SIZEOF(xCharInfo)));
288 return (XFontStruct *)NULL;
293 register XCharStruct *cs = fs->per_char;
296 for (i = 0; i < reply.nCharInfos; i++, cs++) {
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;
309 nbytes = reply.nCharInfos * SIZEOF(xCharInfo);
310 _XRead16 (dpy, (char *)fs->per_char, nbytes);
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);
320 #ifdef USE_XF86BIGFONT
322 /* Magic cookie for finding the right XExtData structure on the display's
324 static int XF86BigfontNumber = 1040697125;
327 _XF86BigfontFreeCodes (
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. */
337 static XF86BigfontCodes *
339 register Display *dpy)
341 XEDataObject dpy_union;
343 XF86BigfontCodes *pCodes;
346 dpy_union.display = dpy;
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.
352 pData = XFindOnExtensionList(XEHeadOfExtensionList(dpy_union),
355 return (XF86BigfontCodes *) pData->private_data;
357 pData = (XExtData *) Xmalloc(sizeof(XExtData) + sizeof(XF86BigfontCodes));
360 return (XF86BigfontCodes *) NULL;
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')
368 XExtCodes *codes = XInitExtension(dpy, XF86BIGFONTNAME);
372 pCodes = (XF86BigfontCodes *) &pData[1];
373 pCodes->codes = codes;
376 pData->number = XF86BigfontNumber;
377 pData->private_data = (XPointer) pCodes;
378 pData->free_private = _XF86BigfontFreeCodes;
379 XAddToExtensionList(XEHeadOfExtensionList(dpy_union), pData);
383 /* See if the server supports the XF86BigfontQueryFont request. */
384 xXF86BigfontQueryVersionReply reply;
385 register xXF86BigfontQueryVersionReq *req;
389 GetReq(XF86BigfontQueryVersion, req);
390 req->reqType = pCodes->codes->major_opcode;
391 req->xf86bigfontReqType = X_XF86BigfontQueryVersion;
393 result = _XReply (dpy, (xReply *) &reply,
394 (SIZEOF(xXF86BigfontQueryVersionReply) - SIZEOF(xReply)) >> 2,
401 goto ignore_extension;
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;
409 pCodes->serverSignature = reply.signature;
410 pCodes->serverCapabilities = reply.capabilities;
415 /* No need to Xfree(pCodes) or Xfree(pCodes->codes), see
416 _XF86BigfontFreeCodes comment. */
417 pCodes = (XF86BigfontCodes *) NULL;
418 pData->private_data = (XPointer) pCodes;
423 _XF86BigfontFreeNop (
430 _XF86BigfontQueryFont (
431 register Display *dpy,
432 XF86BigfontCodes *extcodes,
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;
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;
459 GetReq(XF86BigfontQueryFont, req);
460 req->reqType = extcodes->codes->major_opcode;
461 req->xf86bigfontReqType = X_XF86BigfontQueryFont;
463 req->flags = (extcodes->serverCapabilities & XF86Bigfont_CAP_LocalShm
464 ? XF86Bigfont_FLAGS_Shm : 0);
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;
480 if (!_XReply (dpy, (xReply *) &reply,
481 ((SIZEOF(xXF86BigfontQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) {
482 DeqAsyncHandler(dpy, &async2);
484 DeqAsyncHandler(dpy, &async1);
485 return (XFontStruct *)NULL;
487 DeqAsyncHandler(dpy, &async2);
489 DeqAsyncHandler(dpy, &async1);
490 if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) {
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)
497 return (XFontStruct *)NULL;
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);
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;
515 fs->n_properties = reply.nFontProps;
517 * if no properties defined for the font, then it is bad
518 * font, but shouldn't try to read nothing.
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) {
529 + (reply.nCharInfos > 0 && reply.shmid == (CARD32)(-1)
530 ? reply.nUniqCharInfos * SIZEOF(xCharInfo)
531 + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16)
533 return (XFontStruct *)NULL;
535 _XRead32 (dpy, (long *)fs->properties, nbytes);
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)) {
543 CARD16* pIndex2UniqIndex;
546 nbytes = reply.nUniqCharInfos * SIZEOF(xCharInfo)
547 + (reply.nCharInfos+1)/2 * 2 * sizeof(CARD16);
548 pUniqCI = (xCharInfo *) Xmalloc (nbytes);
550 if (fs->properties) Xfree((char *) fs->properties);
552 _XEatData(dpy, nbytes);
553 return (XFontStruct *)NULL;
555 if (! (fs->per_char = (XCharStruct *) Xmalloc (reply.nCharInfos * sizeof(XCharStruct)))) {
556 Xfree((char *) pUniqCI);
557 if (fs->properties) Xfree((char *) fs->properties);
559 _XEatData(dpy, nbytes);
560 return (XFontStruct *)NULL;
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);
570 return (XFontStruct *)NULL;
572 /* XXX the next statement won't work if short isn't 16 bits */
573 fs->per_char[i] = * (XCharStruct *) &pUniqCI[pIndex2UniqIndex[i]];
575 Xfree((char *) pUniqCI);
579 XEDataObject fs_union;
582 pData = (XExtData *) Xmalloc(sizeof(XExtData));
584 if (fs->properties) Xfree((char *) fs->properties);
586 return (XFontStruct *)NULL;
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. */
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);
606 /* Stop requesting shared memory transport from now on. */
607 extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
608 return (XFontStruct *)NULL;
611 if (!(extcodes->serverCapabilities & CAP_VerifiedLocal)) {
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)) {
617 Xfree((char *) pData);
618 if (fs->properties) Xfree((char *) fs->properties);
620 /* Stop requesting shared memory transport from now on. */
621 extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
622 return (XFontStruct *)NULL;
624 extcodes->serverCapabilities |= CAP_VerifiedLocal;
627 pData->number = XF86BigfontNumber;
628 pData->private_data = (XPointer) addr;
629 pData->free_private = _XF86BigfontFreeNop;
631 XAddToExtensionList(XEHeadOfExtensionList(fs_union), pData);
633 fs->per_char = (XCharStruct *) (addr + reply.shmsegoffset);
635 fprintf(stderr, "_XF86BigfontQueryFont: try recompiling libX11 with HasShm, Xserver has shm support\n");
636 if (fs->properties) Xfree((char *) fs->properties);
638 /* Stop requesting shared memory transport from now on. */
639 extcodes->serverCapabilities &= ~ XF86Bigfont_CAP_LocalShm;
640 return (XFontStruct *)NULL;
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);
652 _XF86BigfontFreeFontMetrics (XFontStruct *fs)
656 XEDataObject fs_union;
659 if ((pData = XFindOnExtensionList(XEHeadOfExtensionList(fs_union),
661 shmdt ((char *) pData->private_data);
663 Xfree ((char *) fs->per_char);
665 Xfree ((char *) fs->per_char);
669 #endif /* USE_XF86BIGFONT */
671 int _XF86LoadQueryLocaleFont(
678 const char *charset, *p;
686 if (l < 2 || name[l - 1] != '*' || name[l - 2] != '-')
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";
698 if (l - 2 - (p - charset) < 0)
700 if (_XlcNCompareISOLatin1(name + l - 2 - (p - charset), charset, p - charset))
702 if (strlen(p + 1) + l - 1 >= sizeof(buf) - 1)
705 strcpy(buf + l - 1, p + 1);
706 fs = XLoadQueryFont(dpy, buf);
715 #ifdef USE_XF86BIGFONT
716 _XF86BigfontFreeFontMetrics(fs);
718 Xfree ((char *) fs->per_char);
721 _XFreeExtData(fs->ext_data);
723 Xfree ((char *) fs->properties);