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