/* Called upon fatal signal. */ void XF86BigfontCleanup() { #ifdef HAS_SHM while (ShmList) shmdealloc(ShmList); #endif }
/* Called when a font is closed. */ void XF86BigfontFreeFontShm(FontPtr pFont) { #ifdef HAS_SHM ShmDescPtr pDesc; /* If during shutdown of the server, XF86BigfontCleanup() has already * called shmdealloc() for all segments, we don't need to do it here. */ if (!ShmList) return; pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex); if (pDesc) shmdealloc(pDesc); #endif }
static int ProcXF86BigfontQueryFont( ClientPtr client) { FontPtr pFont; REQUEST(xXF86BigfontQueryFontReq); CARD32 stuff_flags; xCharInfo* pmax; xCharInfo* pmin; int nCharInfos; int shmid; #ifdef HAS_SHM ShmDescPtr pDesc; #else #define pDesc 0 #endif xCharInfo* pCI; CARD16* pIndex2UniqIndex; CARD16* pUniqIndex2Index; CARD32 nUniqCharInfos; #if 0 REQUEST_SIZE_MATCH(xXF86BigfontQueryFontReq); #else switch (client->req_len) { case 2: /* client with version 1.0 libX11 */ stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); break; case 3: /* client with version 1.1 libX11 */ stuff_flags = stuff->flags; break; default: return BadLength; } #endif client->errorValue = stuff->id; /* EITHER font or gc */ pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, SecurityReadAccess); if (!pFont) { /* can't use VERIFY_GC because it might return BadGC */ GC *pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC, SecurityReadAccess); if (!pGC) { client->errorValue = stuff->id; return BadFont; /* procotol spec says only error is BadFont */ } pFont = pGC->font; } pmax = FONTINKMAX(pFont); pmin = FONTINKMIN(pFont); nCharInfos = (pmax->rightSideBearing == pmin->rightSideBearing && pmax->leftSideBearing == pmin->leftSideBearing && pmax->descent == pmin->descent && pmax->ascent == pmin->ascent && pmax->characterWidth == pmin->characterWidth) ? 0 : N2dChars(pFont); shmid = -1; pCI = NULL; pIndex2UniqIndex = NULL; pUniqIndex2Index = NULL; nUniqCharInfos = 0; if (nCharInfos > 0) { #ifdef HAS_SHM pDesc = (ShmDescPtr) FontGetPrivate(pFont, FontShmdescIndex); if (pDesc) { pCI = (xCharInfo *) pDesc->attach_addr; if (stuff_flags & XF86Bigfont_FLAGS_Shm) shmid = pDesc->shmid; } else { if (stuff_flags & XF86Bigfont_FLAGS_Shm) pDesc = shmalloc(nCharInfos * sizeof(xCharInfo) + sizeof(CARD32)); if (pDesc) { pCI = (xCharInfo *) pDesc->attach_addr; shmid = pDesc->shmid; } else { #endif pCI = (xCharInfo *) ALLOCATE_LOCAL(nCharInfos * sizeof(xCharInfo)); if (!pCI) return BadAlloc; #ifdef HAS_SHM } #endif /* Fill nCharInfos starting at pCI. */ { xCharInfo* prCI = pCI; int ninfos = 0; int ncols = pFont->info.lastCol - pFont->info.firstCol + 1; int row; for (row = pFont->info.firstRow; row <= pFont->info.lastRow && ninfos < nCharInfos; row++) { unsigned char chars[512]; xCharInfo* tmpCharInfos[256]; unsigned long count; int col; unsigned long i; i = 0; for (col = pFont->info.firstCol; col <= pFont->info.lastCol; col++) { chars[i++] = row; chars[i++] = col; } (*pFont->get_metrics) (pFont, ncols, chars, TwoD16Bit, &count, tmpCharInfos); for (i = 0; i < count && ninfos < nCharInfos; i++) { *prCI++ = *tmpCharInfos[i]; ninfos++; } } } #ifdef HAS_SHM if (pDesc) { *(CARD32 *)(pCI + nCharInfos) = signature; if (!FontSetPrivate(pFont, FontShmdescIndex, pDesc)) { shmdealloc(pDesc); return BadAlloc; } } } #endif if (shmid == -1) { /* Cannot use shared memory, so remove-duplicates the xCharInfos using a temporary hash table. */ /* Note that CARD16 is suitable as index type, because nCharInfos <= 0x10000. */ CARD32 hashModulus; CARD16* pHash2UniqIndex; CARD16* pUniqIndex2NextUniqIndex; CARD32 NextIndex; CARD32 NextUniqIndex; CARD16* tmp; CARD32 i, j; hashModulus = 67; if (hashModulus > nCharInfos+1) hashModulus = nCharInfos+1; tmp = (CARD16*) ALLOCATE_LOCAL((4*nCharInfos+1) * sizeof(CARD16)); if (!tmp) { if (!pDesc) DEALLOCATE_LOCAL(pCI); return BadAlloc; } pIndex2UniqIndex = tmp; /* nCharInfos elements */ pUniqIndex2Index = tmp + nCharInfos; /* max. nCharInfos elements */ pUniqIndex2NextUniqIndex = tmp + 2*nCharInfos; /* max. nCharInfos elements */ pHash2UniqIndex = tmp + 3*nCharInfos; /* hashModulus (<= nCharInfos+1) elements */ /* Note that we can use 0xffff as end-of-list indicator, because even if nCharInfos = 0x10000, 0xffff can not occur as valid entry before the last element has been inserted. And once the last element has been inserted, we don't need the hash table any more. */ for (j = 0; j < hashModulus; j++) pHash2UniqIndex[j] = (CARD16)(-1); NextUniqIndex = 0; for (NextIndex = 0; NextIndex < nCharInfos; NextIndex++) { xCharInfo* p = &pCI[NextIndex]; CARD32 hashCode = hashCI(p) % hashModulus; for (i = pHash2UniqIndex[hashCode]; i != (CARD16)(-1); i = pUniqIndex2NextUniqIndex[i]) { j = pUniqIndex2Index[i]; if (pCI[j].leftSideBearing == p->leftSideBearing && pCI[j].rightSideBearing == p->rightSideBearing && pCI[j].characterWidth == p->characterWidth && pCI[j].ascent == p->ascent && pCI[j].descent == p->descent && pCI[j].attributes == p->attributes) break; } if (i != (CARD16)(-1)) { /* Found *p at Index j, UniqIndex i */ pIndex2UniqIndex[NextIndex] = i; } else { /* Allocate a new entry in the Uniq table */ if (hashModulus <= 2*NextUniqIndex && hashModulus < nCharInfos+1) { /* Time to increate hash table size */ hashModulus = 2*hashModulus+1; if (hashModulus > nCharInfos+1) hashModulus = nCharInfos+1; for (j = 0; j < hashModulus; j++) pHash2UniqIndex[j] = (CARD16)(-1); for (i = 0; i < NextUniqIndex; i++) pUniqIndex2NextUniqIndex[i] = (CARD16)(-1); for (i = 0; i < NextUniqIndex; i++) { j = pUniqIndex2Index[i]; p = &pCI[j]; hashCode = hashCI(p) % hashModulus; pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode]; pHash2UniqIndex[hashCode] = i; } p = &pCI[NextIndex]; hashCode = hashCI(p) % hashModulus; } i = NextUniqIndex++; pUniqIndex2NextUniqIndex[i] = pHash2UniqIndex[hashCode]; pHash2UniqIndex[hashCode] = i; pUniqIndex2Index[i] = NextIndex; pIndex2UniqIndex[NextIndex] = i; } } nUniqCharInfos = NextUniqIndex; /* fprintf(stderr, "font metrics: nCharInfos = %d, nUniqCharInfos = %d, hashModulus = %d\n", nCharInfos, nUniqCharInfos, hashModulus); */ } } { int nfontprops = pFont->info.nprops; int rlength = sizeof(xXF86BigfontQueryFontReply) + nfontprops * sizeof(xFontProp) + (nCharInfos > 0 && shmid == -1 ? nUniqCharInfos * sizeof(xCharInfo) + (nCharInfos+1)/2 * 2 * sizeof(CARD16) : 0); xXF86BigfontQueryFontReply* reply = (xXF86BigfontQueryFontReply *) ALLOCATE_LOCAL(rlength); char* p; if (!reply) { if (nCharInfos > 0) { if (shmid == -1) DEALLOCATE_LOCAL(pIndex2UniqIndex); if (!pDesc) DEALLOCATE_LOCAL(pCI); } return BadAlloc; } reply->type = X_Reply; reply->length = (rlength - sizeof(xGenericReply)) >> 2; reply->sequenceNumber = client->sequence; reply->minBounds = pFont->info.ink_minbounds; reply->maxBounds = pFont->info.ink_maxbounds; reply->minCharOrByte2 = pFont->info.firstCol; reply->maxCharOrByte2 = pFont->info.lastCol; reply->defaultChar = pFont->info.defaultCh; reply->nFontProps = pFont->info.nprops; reply->drawDirection = pFont->info.drawDirection; reply->minByte1 = pFont->info.firstRow; reply->maxByte1 = pFont->info.lastRow; reply->allCharsExist = pFont->info.allExist; reply->fontAscent = pFont->info.fontAscent; reply->fontDescent = pFont->info.fontDescent; reply->nCharInfos = nCharInfos; reply->nUniqCharInfos = nUniqCharInfos; reply->shmid = shmid; reply->shmsegoffset = 0; if (client->swapped) { char tmp; swaps(&reply->sequenceNumber, tmp); swapl(&reply->length, tmp); swapCharInfo(&reply->minBounds); swapCharInfo(&reply->maxBounds); swaps(&reply->minCharOrByte2, tmp); swaps(&reply->maxCharOrByte2, tmp); swaps(&reply->defaultChar, tmp); swaps(&reply->nFontProps, tmp); swaps(&reply->fontAscent, tmp); swaps(&reply->fontDescent, tmp); swapl(&reply->nCharInfos, tmp); swapl(&reply->nUniqCharInfos, tmp); swapl(&reply->shmid, tmp); swapl(&reply->shmsegoffset, tmp); } p = (char*) &reply[1]; { FontPropPtr pFP; xFontProp* prFP; int i; for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) p; i < nfontprops; i++, pFP++, prFP++) { prFP->name = pFP->name; prFP->value = pFP->value; if (client->swapped) { char tmp; swapl(&prFP->name, tmp); swapl(&prFP->value, tmp); } } p = (char*) prFP; } if (nCharInfos > 0 && shmid == -1) { xCharInfo* pci; CARD16* ps; int i, j; pci = (xCharInfo*) p; for (i = 0; i < nUniqCharInfos; i++, pci++) { *pci = pCI[pUniqIndex2Index[i]]; if (client->swapped) swapCharInfo(pci); } ps = (CARD16*) pci; for (j = 0; j < nCharInfos; j++, ps++) { *ps = pIndex2UniqIndex[j]; if (client->swapped) { char tmp; swaps(ps, tmp); } } } WriteToClient(client, rlength, (char *)reply); DEALLOCATE_LOCAL(reply); if (nCharInfos > 0) { if (shmid == -1) DEALLOCATE_LOCAL(pIndex2UniqIndex); if (!pDesc) DEALLOCATE_LOCAL(pCI); } return (client->noClientException); } }