Font.c revision e9fcaa8a
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 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/xf86bigfstr.h> 48#endif 49 50#include "Xlcint.h" 51#include "XlcPubI.h" 52 53 54static 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. */ 63typedef 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 72static XF86BigfontCodes *_XF86BigfontCodes( 73 Display* /* dpy */ 74); 75 76static XFontStruct *_XF86BigfontQueryFont( 77 Display* /* dpy */, 78 XF86BigfontCodes* /* extcodes */, 79 Font /* fid */, 80 unsigned long /* seq */ 81); 82 83void _XF86BigfontFreeFontMetrics( 84 XFontStruct* /* fs */ 85); 86 87#endif /* USE_XF86BIGFONT */ 88 89 90XFontStruct *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 126XFontStruct *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 149int 150XFreeFont( 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 179static 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. */ 324static int XF86BigfontNumber = 1040697125; 325 326static 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 337static 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 422static int 423_XF86BigfontFreeNop ( 424 XExtData *extension) 425{ 426 return 0; 427} 428 429static 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 651void 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 671int _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} 731