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