📄 dixfonts.c
字号:
intdoPolyText(client, c) ClientPtr client; register PTclosurePtr c;{ register FontPtr pFont = c->pGC->font, oldpFont; Font fid, oldfid; int err = Success, lgerr; /* err is in X error, not font error, space */ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state; FontPathElementPtr fpe; GC *origGC; if (client->clientGone) { fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); if (c->slept) { /* Client has died, but we cannot bail out right now. We need to clean up after the work we did when going to sleep. Setting the drawable pointer to 0 makes this happen without any attempts to render or perform other unnecessary activities. */ c->pDraw = (DrawablePtr)0; } else { err = Success; goto bail; } } /* Make sure our drawable hasn't disappeared while we slept. */ if (c->slept && c->pDraw && c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did, RC_DRAWABLE, SecurityWriteAccess)) { /* Our drawable has disappeared. Treat like client died... ask the FPE code to clean up after client and avoid further rendering while we clean up after ourself. */ fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); c->pDraw = (DrawablePtr)0; } client_state = c->slept ? SLEEPING : NEVER_SLEPT; while (c->endReq - c->pElt > TextEltHeader) { if (*c->pElt == FontChange) { if (c->endReq - c->pElt < FontShiftSize) { err = BadLength; goto bail; } oldpFont = pFont; oldfid = fid; fid = ((Font)*(c->pElt+4)) /* big-endian */ | ((Font)*(c->pElt+3)) << 8 | ((Font)*(c->pElt+2)) << 16 | ((Font)*(c->pElt+1)) << 24; pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT, SecurityReadAccess); if (!pFont) { client->errorValue = fid; err = BadFont; /* restore pFont and fid for step 4 (described below) */ pFont = oldpFont; fid = oldfid; /* If we're in START_SLEEP mode, the following step shortens the request... in the unlikely event that the fid somehow becomes valid before we come through again to actually execute the polytext, which would then mess up our refcounting scheme badly. */ c->err = err; c->endReq = c->pElt; goto bail; } /* Step 3 (described below) on our new font */ if (client_state == START_SLEEP) pFont->refcnt++; else { if (pFont != c->pGC->font && c->pDraw) { ChangeGC( c->pGC, GCFont, &fid); ValidateGC(c->pDraw, c->pGC); if (c->reqType == X_PolyText8) c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8; else c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16; } /* Undo the refcnt++ we performed when going to sleep */ if (client_state == SLEEPING) (void)CloseFont(c->pGC->font, (Font)0); } c->pElt += FontShiftSize; } else /* print a string */ { unsigned char *pNextElt; pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize; if ( pNextElt > c->endReq) { err = BadLength; goto bail; } if (client_state == START_SLEEP) { c->pElt = pNextElt; continue; } if (c->pDraw) { lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize, c->pElt + TextEltHeader); } else lgerr = Successful; if (lgerr == Suspended) { if (!c->slept) { int len; GC *pGC; PTclosurePtr new_closure; /* We're putting the client to sleep. We need to do a few things to ensure successful and atomic-appearing execution of the remainder of the request. First, copy the remainder of the request into a safe malloc'd area. Second, create a scratch GC to use for the remainder of the request. Third, mark all fonts referenced in the remainder of the request to prevent their deallocation. Fourth, make the original GC look like the request has completed... set its font to the final font value from this request. These GC manipulations are for the unlikely (but possible) event that some other client is using the GC. Steps 3 and 4 are performed by running this procedure through the remainder of the request in a special no-render mode indicated by client_state = START_SLEEP. */ /* Step 1 */ /* Allocate a malloc'd closure structure to replace the local one we were passed */ new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec)); if (!new_closure) { err = BadAlloc; goto bail; } *new_closure = *c; c = new_closure; len = c->endReq - c->pElt; c->data = (unsigned char *)xalloc(len); if (!c->data) { xfree(c); err = BadAlloc; goto bail; } memmove(c->data, c->pElt, len); c->pElt = c->data; c->endReq = c->pElt + len; /* Step 2 */ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen); if (!pGC) { xfree(c->data); xfree(c); err = BadAlloc; goto bail; } if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCFillStyle | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask)) != Success) { FreeScratchGC(pGC); xfree(c->data); xfree(c); err = BadAlloc; goto bail; } origGC = c->pGC; c->pGC = pGC; ValidateGC(c->pDraw, c->pGC); c->slept = TRUE; ClientSleep(client, (ClientSleepProcPtr)doPolyText, (pointer) c); /* Set up to perform steps 3 and 4 */ client_state = START_SLEEP; continue; /* on to steps 3 and 4 */ } return TRUE; } else if (lgerr != Successful) { err = FontToXError(lgerr); goto bail; } if (c->pDraw) { c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg, *c->pElt, c->pElt + TextEltHeader); } c->pElt = pNextElt; } }bail: if (client_state == START_SLEEP) { /* Step 4 */ if (pFont != origGC->font) { ChangeGC(origGC, GCFont, &fid); ValidateGC(c->pDraw, origGC); } /* restore pElt pointer for execution of remainder of the request */ c->pElt = c->data; return TRUE; } if (c->err != Success) err = c->err; if (err != Success && c->client != serverClient) { SendErrorToClient(c->client, c->reqType, 0, 0, err); } if (c->slept) { ClientWakeup(c->client); ChangeGC(c->pGC, clearGCmask, clearGC); /* Unreference the font from the scratch GC */ CloseFont(c->pGC->font, (Font)0); c->pGC->font = NullFont; FreeScratchGC(c->pGC); xfree(c->data); xfree(c); } return TRUE;}intPolyText(client, pDraw, pGC, pElt, endReq, xorg, yorg, reqType, did) ClientPtr client; DrawablePtr pDraw; GC *pGC; unsigned char *pElt; unsigned char *endReq; int xorg; int yorg; int reqType; XID did;{ PTclosureRec local_closure; local_closure.pElt = pElt; local_closure.endReq = endReq; local_closure.client = client; local_closure.pDraw = pDraw; local_closure.xorg = xorg; local_closure.yorg = yorg; if ((local_closure.reqType = reqType) == X_PolyText8) { local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8; local_closure.itemSize = 1; } else { local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16; local_closure.itemSize = 2; } local_closure.pGC = pGC; local_closure.did = did; local_closure.err = Success; local_closure.slept = FALSE; (void) doPolyText(client, &local_closure); return Success;}#undef TextEltHeader#undef FontShiftSizeintdoImageText(client, c) ClientPtr client; register ITclosurePtr c;{ int err = Success, lgerr; /* err is in X error, not font error, space */ FontPathElementPtr fpe; if (client->clientGone) { fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); err = Success; goto bail; } /* Make sure our drawable hasn't disappeared while we slept. */ if (c->slept && c->pDraw && c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did, RC_DRAWABLE, SecurityWriteAccess)) { /* Our drawable has disappeared. Treat like client died... ask the FPE code to clean up after client. */ fpe = c->pGC->font->fpe; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); err = Success; goto bail; } lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data); if (lgerr == Suspended) { if (!c->slept) { GC *pGC; unsigned char *data; ITclosurePtr new_closure; /* We're putting the client to sleep. We need to save some state. Similar problem to that handled in doPolyText, but much simpler because the request structure is much simpler. */ new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec)); if (!new_closure) { err = BadAlloc; goto bail; } *new_closure = *c; c = new_closure; data = (unsigned char *)xalloc(c->nChars * c->itemSize); if (!data) { xfree(c); err = BadAlloc; goto bail; } memmove(data, c->data, c->nChars * c->itemSize); c->data = data; pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen); if (!pGC) { xfree(c->data); xfree(c); err = BadAlloc; goto bail; } if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask | GCForeground | GCBackground | GCFillStyle | GCTile | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin | GCFont | GCSubwindowMode | GCClipXOrigin | GCClipYOrigin | GCClipMask)) != Success) { FreeScratchGC(pGC); xfree(c->data); xfree(c); err = BadAlloc; goto bail; } c->pGC = pGC; ValidateGC(c->pDraw, c->pGC); c->slept = TRUE; ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c); } return TRUE; } else if (lgerr != Successful) { err = FontToXError(lgerr); goto bail; } if (c->pDraw) { (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg, c->nChars, c->data); }bail: if (err != Success && c->client != serverClient) { SendErrorToClient(c->client, c->reqType, 0, 0, err); } if (c->slept) { ClientWakeup(c->client); ChangeGC(c->pGC, clearGCmask, clearGC); /* Unreference the font from the scratch GC */ CloseFont(c->pGC->font, (Font)0); c->pGC->font = NullFont; FreeScratchGC(c->pGC); xfree(c->data); xfree(c); } return TRUE;}intImageText(client, pDraw, pGC, nChars, data, xorg, yorg, reqType, did) ClientPtr client; DrawablePtr pDraw; GC *pGC; int nChars; unsigned char *data; int xorg; int yorg; int reqType; XID did;{ ITclosureRec local_closure; local_closure.client = client; local_closure.pDraw = pDraw; local_closure.pGC = pGC; local_closure.nChars = nChars; local_closure.data = data; local_closure.xorg = xorg; local_closure.yorg = yorg; if ((local_closure.reqType = reqType) == X_ImageText8) { local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8; local_closure.itemSize = 1; } else { local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16; local_closure.itemSize = 2; } local_closure.did = did; local_closure.slept = FALSE; (void) doImageText(client, &local_closure); return Success;}/* does the necessary magic to figure out the fpe type */static int#if NeedFunctionPrototypesDetermineFPEType(char *pathname)#elseDetermineFPEType(pathname) char *pathname;#endif{ int i; for (i = 0; i < num_fpe_types; i++) { if ((*fpe_functions[i].name_check) (pathname)) return i; } return -1;}static void#if NeedFunctionPrototypesFreeFontPath(FontPathElementPtr *list, int n, Bool force)#elseFreeFontPath(list, n, force) FontPathElementPtr *list; Bool force; int n;#endif{ int i; for (i = 0; i < n; i++) { if (force) { /* Sanity check that all refcounts will be 0 by the time we get to the end of the list. */ int found = 1; /* the first reference is us */ int j; for (j = i+1; j < n; j++) { if (list[j] == list[i]) found++; } if (list[i]->refcount != found) { ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n", list[i]->name_length, list[i]->name, list[i]->refcount, found); list[i]->refcount = found; /* ensure it will get freed */ } } FreeFPE(list[i]); } xfree((char *) list);}static FontPathElementPtr#if NeedFunctionPrototypesfind_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)#elsefind_existing_fpe(list, num, name, len) FontPathElementPtr *list; int num; unsigned char *name; int len;#endif{ FontPathElementPtr fpe; int i; for (i = 0; i < num; i++) { fpe = list[i]; if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0) return fpe; } return (FontPathElementPtr) 0;}static int#if NeedFunctionPrototypesSetFontPathElements(int npaths, unsigned char *paths, int *bad)#elseSetFontPathElements(npaths, paths, bad) int npaths; unsigned char *paths; int *bad;#endif{ int i, err; int valid_paths = 0; unsigned int len; unsigned char *cp = paths; FontPathElementPtr fpe, *fplist; fplist = (FontPathElementPtr *) xalloc(sizeof(FontPathElementPtr) * npaths);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -