📄 dixfonts.c
字号:
doListFontsAndAliases(client, c) ClientPtr client; LFclosurePtr c;#endif{ FontPathElementPtr fpe; int err = Successful; FontNamesPtr names = NULL; char *name, *resolved=NULL; int namelen, resolvedlen; int nnames; int stringLens; int i; xListFontsReply reply; char *bufptr; char *bufferStart; int aliascount; if (client->clientGone) { if (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); } err = Successful; goto bail; } if (!c->current.patlen) goto finish; while (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; err = Successful; if (!fpe_functions[fpe->type].start_list_fonts_and_aliases) { /* This FPE doesn't support/require list_fonts_and_aliases */ err = (*fpe_functions[fpe->type].list_fonts) ((pointer) c->client, fpe, c->current.pattern, c->current.patlen, c->current.max_names - c->names->nnames, c->names); if (err == Suspended) { if (!c->slept) { c->slept = TRUE; ClientSleep(client, (ClientSleepProcPtr)doListFontsAndAliases, (pointer) c); } return TRUE; } err = BadFontName; } else { /* Start of list_fonts_and_aliases functionality. Modeled after list_fonts_with_info in that it resolves aliases, except that the information collected from FPEs is just names, not font info. Each list_next_font_or_alias() returns either a name into name/namelen or an alias into name/namelen and its target name into resolved/resolvedlen. The code at this level then resolves the alias by polling the FPEs. */ if (!c->current.list_started) { err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases) ((pointer) c->client, fpe, c->current.pattern, c->current.patlen, c->current.max_names - c->names->nnames, &c->current.private); if (err == Suspended) { if (!c->slept) { ClientSleep(client, (ClientSleepProcPtr)doListFontsAndAliases, (pointer) c); c->slept = TRUE; } return TRUE; } if (err == Successful) c->current.list_started = TRUE; } if (err == Successful) { char *tmpname; name = 0; err = (*fpe_functions[fpe->type].list_next_font_or_alias) ((pointer) c->client, fpe, &name, &namelen, &tmpname, &resolvedlen, c->current.private); if (err == Suspended) { if (!c->slept) { ClientSleep(client, (ClientSleepProcPtr)doListFontsAndAliases, (pointer) c); c->slept = TRUE; } return TRUE; } if (err == FontNameAlias) { if (resolved) xfree(resolved); resolved = (char *) xalloc(resolvedlen + 1); if (resolved) memmove(resolved, tmpname, resolvedlen + 1); } } if (err == Successful) { if (c->haveSaved) { if (c->savedName) (void)AddFontNamesName(c->names, c->savedName, c->savedNameLen); } else (void)AddFontNamesName(c->names, name, namelen); } /* * When we get an alias back, save our state and reset back to * the start of the FPE looking for the specified name. As * soon as a real font is found for the alias, pop back to the * old state */ else if (err == FontNameAlias) { char tmp_pattern[256]; /* * when an alias recurses, we need to give * the last FPE a chance to clean up; so we call * it again, and assume that the error returned * is BadFontName, indicating the alias resolution * is complete. */ memmove(tmp_pattern, resolved, resolvedlen); if (c->haveSaved) { char *tmpname; int tmpnamelen; tmpname = 0; (void) (*fpe_functions[fpe->type].list_next_font_or_alias) ((pointer) c->client, fpe, &tmpname, &tmpnamelen, &tmpname, &tmpnamelen, c->current.private); if (--aliascount <= 0) { err = BadFontName; goto ContBadFontName; } } else { c->saved = c->current; c->haveSaved = TRUE; if (c->savedName) xfree(c->savedName); c->savedName = (char *)xalloc(namelen + 1); if (c->savedName) memmove(c->savedName, name, namelen + 1); c->savedNameLen = namelen; aliascount = 20; } memmove(c->current.pattern, tmp_pattern, resolvedlen); c->current.patlen = resolvedlen; c->current.max_names = c->names->nnames + 1; c->current.current_fpe = -1; c->current.private = 0; err = BadFontName; } } /* * At the end of this FPE, step to the next. If we've finished * processing an alias, pop state back. If we've collected enough * font names, quit. */ if (err == BadFontName) { ContBadFontName: ; c->current.list_started = FALSE; c->current.current_fpe++; err = Successful; if (c->haveSaved) { if (c->names->nnames == c->current.max_names || c->current.current_fpe == c->num_fpes) { c->haveSaved = FALSE; c->current = c->saved; /* Give the saved namelist a chance to clean itself up */ continue; } } if (c->names->nnames == c->current.max_names) break; } } /* * send the reply */ if (err != Successful) { SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err)); goto bail; }finish: names = c->names; nnames = names->nnames; client = c->client; stringLens = 0; for (i = 0; i < nnames; i++) stringLens += (names->length[i] <= 255) ? names->length[i] : 0; reply.type = X_Reply; reply.length = (stringLens + nnames + 3) >> 2; reply.nFonts = nnames; reply.sequenceNumber = client->sequence; bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2); if (!bufptr && reply.length) { SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc); goto bail; } /* * since WriteToClient long word aligns things, copy to temp buffer and * write all at once */ for (i = 0; i < nnames; i++) { if (names->length[i] > 255) reply.nFonts--; else { *bufptr++ = names->length[i]; memmove( bufptr, names->names[i], names->length[i]); bufptr += names->length[i]; } } nnames = reply.nFonts; reply.length = (stringLens + nnames + 3) >> 2; client->pSwapReplyFunc = ReplySwapVector[X_ListFonts]; WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply); (void) WriteToClient(client, stringLens + nnames, bufferStart); DEALLOCATE_LOCAL(bufferStart);bail: if (c->slept) ClientWakeup(client); for (i = 0; i < c->num_fpes; i++) FreeFPE(c->fpe_list[i]); xfree(c->fpe_list); if (c->savedName) xfree(c->savedName); FreeFontNames(names); xfree(c); if (resolved) xfree(resolved); return TRUE;}intListFonts(client, pattern, length, max_names) ClientPtr client; unsigned char *pattern; unsigned int length; unsigned int max_names;{ int i; LFclosurePtr c; if (!(c = (LFclosurePtr) xalloc(sizeof *c))) return BadAlloc; c->fpe_list = (FontPathElementPtr *) xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c); return BadAlloc; } c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100); if (!c->names) { xfree(c->fpe_list); xfree(c); return BadAlloc; } memmove( c->current.pattern, pattern, length); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->num_fpes = num_fpes; c->current.patlen = length; c->current.current_fpe = 0; c->current.max_names = max_names; c->current.list_started = FALSE; c->current.private = 0; c->haveSaved = FALSE; c->slept = FALSE; c->savedName = 0; doListFontsAndAliases(client, c); return Success;}intdoListFontsWithInfo(client, c) ClientPtr client; LFWIclosurePtr c;{ FontPathElementPtr fpe; int err = Successful; char *name; int namelen; int numFonts; FontInfoRec fontInfo, *pFontInfo; xListFontsWithInfoReply *reply; int length; xFontProp *pFP; int i; int aliascount; xListFontsWithInfoReply finalReply; if (client->clientGone) { if (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); } err = Successful; goto bail; } client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo]; if (!c->current.patlen) goto finish; while (c->current.current_fpe < c->num_fpes) { fpe = c->fpe_list[c->current.current_fpe]; err = Successful; if (!c->current.list_started) { err = (*fpe_functions[fpe->type].start_list_fonts_with_info) (client, fpe, c->current.pattern, c->current.patlen, c->current.max_names, &c->current.private); if (err == Suspended) { if (!c->slept) { ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c); c->slept = TRUE; } return TRUE; } if (err == Successful) c->current.list_started = TRUE; } if (err == Successful) { name = 0; pFontInfo = &fontInfo; err = (*fpe_functions[fpe->type].list_next_font_with_info) (client, fpe, &name, &namelen, &pFontInfo, &numFonts, c->current.private); if (err == Suspended) { if (!c->slept) { ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c); c->slept = TRUE; } return TRUE; } } /* * When we get an alias back, save our state and reset back to the * start of the FPE looking for the specified name. As soon as a real * font is found for the alias, pop back to the old state */ if (err == FontNameAlias) { /* * when an alias recurses, we need to give * the last FPE a chance to clean up; so we call * it again, and assume that the error returned * is BadFontName, indicating the alias resolution * is complete. */ if (c->haveSaved) { char *tmpname; int tmpnamelen; FontInfoPtr tmpFontInfo; tmpname = 0; tmpFontInfo = &fontInfo; (void) (*fpe_functions[fpe->type].list_next_font_with_info) (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo, &numFonts, c->current.private); if (--aliascount <= 0) { err = BadFontName; goto ContBadFontName; } } else { c->saved = c->current; c->haveSaved = TRUE; c->savedNumFonts = numFonts; c->savedName = (char *) pFontInfo; aliascount = 20; } memmove(c->current.pattern, name, namelen); c->current.patlen = namelen; c->current.max_names = 1; c->current.current_fpe = 0; c->current.private = 0; c->current.list_started = FALSE; } /* * At the end of this FPE, step to the next. If we've finished * processing an alias, pop state back. If we've sent enough font * names, quit. Always wait for BadFontName to let the FPE * have a chance to clean up. */ else if (err == BadFontName) { ContBadFontName: ; c->current.list_started = FALSE; c->current.current_fpe++; err = Successful; if (c->haveSaved) { if (c->current.max_names == 0 || c->current.current_fpe == c->num_fpes) { c->haveSaved = FALSE; c->saved.max_names -= (1 - c->current.max_names); c->current = c->saved; } } else if (c->current.max_names == 0) break; } else if (err == Successful) { length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp); reply = c->reply; if (c->length < length) { reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length); if (!reply) { err = AllocError; break; } c->reply = reply; c->length = length; } if (c->haveSaved) { numFonts = c->savedNumFonts; name = c->savedName; namelen = strlen(name); } reply->type = X_Reply; reply->length = (sizeof *reply - sizeof(xGenericReply) + pFontInfo->nprops * sizeof(xFontProp) + namelen + 3) >> 2; reply->sequenceNumber = client->sequence; reply->nameLength = namelen; reply->minBounds = pFontInfo->ink_minbounds; reply->maxBounds = pFontInfo->ink_maxbounds; reply->minCharOrByte2 = pFontInfo->firstCol; reply->maxCharOrByte2 = pFontInfo->lastCol; reply->defaultChar = pFontInfo->defaultCh; reply->nFontProps = pFontInfo->nprops; reply->drawDirection = pFontInfo->drawDirection; reply->minByte1 = pFontInfo->firstRow; reply->maxByte1 = pFontInfo->lastRow; reply->allCharsExist = pFontInfo->allExist; reply->fontAscent = pFontInfo->fontAscent; reply->fontDescent = pFontInfo->fontDescent; reply->nReplies = numFonts; pFP = (xFontProp *) (reply + 1); for (i = 0; i < pFontInfo->nprops; i++) { pFP->name = pFontInfo->props[i].name; pFP->value = pFontInfo->props[i].value; pFP++; } WriteSwappedDataToClient(client, length, reply); (void) WriteToClient(client, namelen, name); if (pFontInfo == &fontInfo) { xfree(fontInfo.props); xfree(fontInfo.isStringProp); } --c->current.max_names; } }finish: length = sizeof(xListFontsWithInfoReply); bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply)); finalReply.type = X_Reply; finalReply.sequenceNumber = client->sequence; finalReply.length = (sizeof(xListFontsWithInfoReply) - sizeof(xGenericReply)) >> 2; WriteSwappedDataToClient(client, length, &finalReply);bail: if (c->slept) ClientWakeup(client); for (i = 0; i < c->num_fpes; i++) FreeFPE(c->fpe_list[i]); xfree(c->reply); xfree(c->fpe_list); xfree(c); return TRUE;}intStartListFontsWithInfo(client, length, pattern, max_names) ClientPtr client; int length; unsigned char *pattern; int max_names;{ int i; LFWIclosurePtr c; if (!(c = (LFWIclosurePtr) xalloc(sizeof *c))) goto badAlloc; c->fpe_list = (FontPathElementPtr *) xalloc(sizeof(FontPathElementPtr) * num_fpes); if (!c->fpe_list) { xfree(c); goto badAlloc; } memmove(c->current.pattern, pattern, length); for (i = 0; i < num_fpes; i++) { c->fpe_list[i] = font_path_elements[i]; UseFPE(c->fpe_list[i]); } c->client = client; c->num_fpes = num_fpes; c->reply = 0; c->length = 0; c->current.patlen = length; c->current.current_fpe = 0; c->current.max_names = max_names; c->current.list_started = FALSE; c->current.private = 0; c->savedNumFonts = 0; c->haveSaved = FALSE; c->slept = FALSE; doListFontsWithInfo(client, c); return Success;badAlloc: return BadAlloc;}#define TextEltHeader 2#define FontShiftSize 5static XID clearGC[] = { CT_NONE };#define clearGCmask (GCClipMask)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -