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