1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056 |
- /************************************************************************
- Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- All Rights Reserved
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the name of Digital not be
- used in advertising or publicity pertaining to distribution of the
- software without specific, written prior permission.
- DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ************************************************************************/
- /* The panoramix components contained the following notice */
- /*
- Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software.
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
- BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of Digital Equipment Corporation
- shall not be used in advertising or otherwise to promote the sale, use or other
- dealings in this Software without prior written authorization from Digital
- Equipment Corporation.
- ******************************************************************/
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include <X11/X.h>
- #include <X11/Xmd.h>
- #include <X11/Xproto.h>
- #include "scrnintstr.h"
- #include "resource.h"
- #include "dixstruct.h"
- #include "cursorstr.h"
- #include "misc.h"
- #include "opaque.h"
- #include "dixfontstr.h"
- #include "closestr.h"
- #ifdef XF86BIGFONT
- #define _XF86BIGFONT_SERVER_
- #include <X11/extensions/xf86bigfont.h>
- #include "xf86bigfontsrv.h"
- #endif
- #define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
- extern pointer fosNaturalParams;
- extern FontPtr defaultFont;
- static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
- static int num_fpes = 0;
- _X_EXPORT FPEFunctions *fpe_functions = (FPEFunctions *) 0;
- static int num_fpe_types = 0;
- static unsigned char *font_path_string;
- static int num_slept_fpes = 0;
- static int size_slept_fpes = 0;
- static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
- static FontPatternCachePtr patternCache;
- _X_EXPORT int
- FontToXError(err)
- int err;
- {
- switch (err) {
- case Successful:
- return Success;
- case AllocError:
- return BadAlloc;
- case BadFontName:
- return BadName;
- case BadFontPath:
- case BadFontFormat: /* is there something better? */
- case BadCharRange:
- return BadValue;
- default:
- return err;
- }
- }
- /*
- * adding RT_FONT prevents conflict with default cursor font
- */
- Bool
- SetDefaultFont(char *defaultfontname)
- {
- int err;
- FontPtr pf;
- XID fid;
- fid = FakeClientID(0);
- err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
- (unsigned) strlen(defaultfontname), defaultfontname);
- if (err != Success)
- return FALSE;
- pf = (FontPtr) LookupIDByType(fid, RT_FONT);
- if (pf == (FontPtr) NULL)
- return FALSE;
- defaultFont = pf;
- return TRUE;
- }
- /*
- * note that the font wakeup queue is not refcounted. this is because
- * an fpe needs to be added when it's inited, and removed when it's finally
- * freed, in order to handle any data that isn't requested, like FS events.
- *
- * since the only thing that should call these routines is the renderer's
- * init_fpe() and free_fpe(), there shouldn't be any problem in using
- * freed data.
- */
- void
- QueueFontWakeup(FontPathElementPtr fpe)
- {
- int i;
- FontPathElementPtr *new;
- for (i = 0; i < num_slept_fpes; i++) {
- if (slept_fpes[i] == fpe) {
- return;
- }
- }
- if (num_slept_fpes == size_slept_fpes) {
- new = (FontPathElementPtr *)
- realloc(slept_fpes,
- sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
- if (!new)
- return;
- slept_fpes = new;
- size_slept_fpes += 4;
- }
- slept_fpes[num_slept_fpes] = fpe;
- num_slept_fpes++;
- }
- void
- RemoveFontWakeup(FontPathElementPtr fpe)
- {
- int i, j;
- for (i = 0; i < num_slept_fpes; i++) {
- if (slept_fpes[i] == fpe) {
- for (j = i; j < num_slept_fpes; j++) {
- slept_fpes[j] = slept_fpes[j + 1];
- }
- num_slept_fpes--;
- return;
- }
- }
- }
- void
- FontWakeup(pointer data, int count, pointer LastSelectMask)
- {
- int i;
- FontPathElementPtr fpe;
- if (count < 0)
- return;
- /* wake up any fpe's that may be waiting for information */
- for (i = 0; i < num_slept_fpes; i++) {
- fpe = slept_fpes[i];
- (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
- }
- }
- /* XXX -- these two funcs may want to be broken into macros */
- static void
- UseFPE(FontPathElementPtr fpe)
- {
- fpe->refcount++;
- }
- static void
- FreeFPE(FontPathElementPtr fpe)
- {
- fpe->refcount--;
- if (fpe->refcount == 0) {
- (*fpe_functions[fpe->type].free_fpe) (fpe);
- free(fpe->name);
- free(fpe);
- }
- }
- static Bool
- doOpenFont(ClientPtr client, OFclosurePtr c)
- {
- FontPtr pfont = NullFont;
- FontPathElementPtr fpe = NULL;
- ScreenPtr pScr;
- int err = Successful;
- int i;
- char *alias, *newname;
- int newlen;
- int aliascount = 20;
- /*
- * Decide at runtime what FontFormat to use.
- */
- Mask FontFormat =
- ((screenInfo.imageByteOrder == LSBFirst) ?
- BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
- ((screenInfo.bitmapBitOrder == LSBFirst) ?
- BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
- BitmapFormatImageRectMin |
- #if GLYPHPADBYTES == 1
- BitmapFormatScanlinePad8 |
- #endif
- #if GLYPHPADBYTES == 2
- BitmapFormatScanlinePad16 |
- #endif
- #if GLYPHPADBYTES == 4
- BitmapFormatScanlinePad32 |
- #endif
- #if GLYPHPADBYTES == 8
- BitmapFormatScanlinePad64 |
- #endif
- BitmapFormatScanlineUnit8;
- if (client->clientGone) {
- if (c->current_fpe < c->num_fpes) {
- fpe = c->fpe_list[c->current_fpe];
- (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
- }
- err = Successful;
- goto bail;
- }
- while (c->current_fpe < c->num_fpes) {
- fpe = c->fpe_list[c->current_fpe];
- err = (*fpe_functions[fpe->type].open_font)
- ((pointer) client, fpe, c->flags,
- c->fontname, c->fnamelen, FontFormat,
- BitmapFormatMaskByte |
- BitmapFormatMaskBit |
- BitmapFormatMaskImageRectangle |
- BitmapFormatMaskScanLinePad |
- BitmapFormatMaskScanLineUnit,
- c->fontid, &pfont, &alias,
- c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
- c->non_cachable_font : (FontPtr) 0);
- if (err == FontNameAlias && alias) {
- newlen = strlen(alias);
- newname = (char *) realloc(c->fontname, newlen);
- if (!newname) {
- err = AllocError;
- break;
- }
- memmove(newname, alias, newlen);
- c->fontname = newname;
- c->fnamelen = newlen;
- c->current_fpe = 0;
- if (--aliascount <= 0)
- break;
- continue;
- }
- if (err == BadFontName) {
- c->current_fpe++;
- continue;
- }
- if (err == Suspended) {
- if (!c->slept) {
- c->slept = TRUE;
- ClientSleep(client, (ClientSleepProcPtr) doOpenFont,
- (pointer) c);
- }
- return TRUE;
- }
- break;
- }
- if (err != Successful)
- goto bail;
- if (!pfont) {
- err = BadFontName;
- goto bail;
- }
- if (!pfont->fpe)
- pfont->fpe = fpe;
- pfont->refcnt++;
- if (pfont->refcnt == 1) {
- UseFPE(pfont->fpe);
- for (i = 0; i < screenInfo.numScreens; i++) {
- pScr = screenInfo.screens[i];
- if (pScr->RealizeFont) {
- if (!(*pScr->RealizeFont) (pScr, pfont)) {
- CloseFont(pfont, (Font) 0);
- err = AllocError;
- goto bail;
- }
- }
- }
- }
- if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
- err = AllocError;
- goto bail;
- }
- if (patternCache && pfont != c->non_cachable_font)
- CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
- pfont);
- bail:
- if (err != Successful && c->client != serverClient) {
- SendErrorToClient(c->client, X_OpenFont, 0,
- c->fontid, FontToXError(err));
- }
- if (c->slept)
- ClientWakeup(c->client);
- for (i = 0; i < c->num_fpes; i++) {
- FreeFPE(c->fpe_list[i]);
- }
- free(c->fpe_list);
- free(c->fontname);
- free(c);
- return TRUE;
- }
- int
- OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname,
- char *pfontname)
- {
- OFclosurePtr c;
- int i;
- FontPtr cached = (FontPtr) 0;
- #ifdef FONTDEBUG
- char *f;
- f = malloc(lenfname + 1);
- memmove(f, pfontname, lenfname);
- f[lenfname] = '\0';
- ErrorF("OpenFont: fontname is \"%s\"\n", f);
- free(f);
- #endif
- if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
- return BadName;
- if (patternCache) {
- /*
- ** Check name cache. If we find a cached version of this font that
- ** is cachable, immediately satisfy the request with it. If we find
- ** a cached version of this font that is non-cachable, we do not
- ** satisfy the request with it. Instead, we pass the FontPtr to the
- ** FPE's open_font code (the fontfile FPE in turn passes the
- ** information to the rasterizer; the fserve FPE ignores it).
- **
- ** Presumably, the font is marked non-cachable because the FPE has
- ** put some licensing restrictions on it. If the FPE, using
- ** whatever logic it relies on, determines that it is willing to
- ** share this existing font with the client, then it has the option
- ** to return the FontPtr we passed it as the newly-opened font.
- ** This allows the FPE to exercise its licensing logic without
- ** having to create another instance of a font that already exists.
- */
- cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
- if (cached && cached->info.cachable) {
- if (!AddResource(fid, RT_FONT, (pointer) cached))
- return BadAlloc;
- cached->refcnt++;
- return Success;
- }
- }
- c = malloc(sizeof(OFclosureRec));
- if (!c)
- return BadAlloc;
- c->fontname = malloc(lenfname);
- c->origFontName = pfontname;
- c->origFontNameLen = lenfname;
- if (!c->fontname) {
- free(c);
- return BadAlloc;
- }
- /*
- * copy the current FPE list, so that if it gets changed by another client
- * while we're blocking, the request still appears atomic
- */
- c->fpe_list = (FontPathElementPtr *)
- malloc(sizeof(FontPathElementPtr) * num_fpes);
- if (!c->fpe_list) {
- free(c->fontname);
- free(c);
- return BadAlloc;
- }
- memmove(c->fontname, pfontname, lenfname);
- for (i = 0; i < num_fpes; i++) {
- c->fpe_list[i] = font_path_elements[i];
- UseFPE(c->fpe_list[i]);
- }
- c->client = client;
- c->fontid = fid;
- c->current_fpe = 0;
- c->num_fpes = num_fpes;
- c->fnamelen = lenfname;
- c->slept = FALSE;
- c->flags = flags;
- c->non_cachable_font = cached;
- (void) doOpenFont(client, c);
- return Success;
- }
- /**
- * Decrement font's ref count, and free storage if ref count equals zero
- *
- * \param value must conform to DeleteType
- */
- _X_EXPORT int
- CloseFont(pointer value, XID fid)
- {
- int nscr;
- ScreenPtr pscr;
- FontPathElementPtr fpe;
- FontPtr pfont = (FontPtr) value;
- if (pfont == NullFont)
- return (Success);
- if (--pfont->refcnt == 0) {
- if (patternCache)
- RemoveCachedFontPattern(patternCache, pfont);
- /*
- * since the last reference is gone, ask each screen to free any
- * storage it may have allocated locally for it.
- */
- for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
- pscr = screenInfo.screens[nscr];
- if (pscr->UnrealizeFont)
- (*pscr->UnrealizeFont) (pscr, pfont);
- }
- if (pfont == defaultFont)
- defaultFont = NULL;
- #ifdef XF86BIGFONT
- XF86BigfontFreeFontShm(pfont);
- #endif
- fpe = pfont->fpe;
- (*fpe_functions[fpe->type].close_font) (fpe, pfont);
- FreeFPE(fpe);
- }
- return (Success);
- }
- /***====================================================================***/
- /**
- * Sets up pReply as the correct QueryFontReply for pFont with the first
- * nProtoCCIStructs char infos.
- *
- * \param pReply caller must allocate this storage
- */
- void
- QueryFont(FontPtr pFont, xQueryFontReply * pReply, int nProtoCCIStructs)
- {
- FontPropPtr pFP;
- int r, c, i;
- xFontProp *prFP;
- xCharInfo *prCI;
- xCharInfo *charInfos[256];
- unsigned char chars[512];
- int ninfos;
- unsigned long ncols;
- unsigned long count;
- /* pr->length set in dispatch */
- pReply->minCharOrByte2 = pFont->info.firstCol;
- pReply->defaultChar = pFont->info.defaultCh;
- pReply->maxCharOrByte2 = pFont->info.lastCol;
- pReply->drawDirection = pFont->info.drawDirection;
- pReply->allCharsExist = pFont->info.allExist;
- pReply->minByte1 = pFont->info.firstRow;
- pReply->maxByte1 = pFont->info.lastRow;
- pReply->fontAscent = pFont->info.fontAscent;
- pReply->fontDescent = pFont->info.fontDescent;
- pReply->minBounds = pFont->info.ink_minbounds;
- pReply->maxBounds = pFont->info.ink_maxbounds;
- pReply->nFontProps = pFont->info.nprops;
- pReply->nCharInfos = nProtoCCIStructs;
- for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
- i < pFont->info.nprops; i++, pFP++, prFP++) {
- prFP->name = pFP->name;
- prFP->value = pFP->value;
- }
- ninfos = 0;
- ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
- prCI = (xCharInfo *) (prFP);
- for (r = pFont->info.firstRow;
- ninfos < nProtoCCIStructs && r <= (int) pFont->info.lastRow; r++) {
- i = 0;
- for (c = pFont->info.firstCol; c <= (int) pFont->info.lastCol; c++) {
- chars[i++] = r;
- chars[i++] = c;
- }
- (*pFont->get_metrics) (pFont, ncols, chars,
- TwoD16Bit, &count, charInfos);
- for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
- *prCI = *charInfos[i];
- prCI++;
- ninfos++;
- }
- }
- return;
- }
- static Bool
- doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
- {
- 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 = 0;
- 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)
- free(resolved);
- resolved = malloc(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[XLFDMAXFONTNAMELEN];
- /*
- * 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)
- free(c->savedName);
- c->savedName = malloc(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;
- memset(&reply, 0, sizeof(xListFontsReply));
- 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]);
- free(c->fpe_list);
- if (c->savedName)
- free(c->savedName);
- FreeFontNames(names);
- free(c);
- if (resolved)
- free(resolved);
- return TRUE;
- }
- int
- ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
- unsigned max_names)
- {
- int i;
- LFclosurePtr c;
- /*
- * The right error to return here would be BadName, however the
- * specification does not allow for a Name error on this request.
- * Perhaps a better solution would be to return a nil list, i.e.
- * a list containing zero fontnames.
- */
- if (length > XLFDMAXFONTNAMELEN)
- return BadAlloc;
- if (!(c = malloc(sizeof *c)))
- return BadAlloc;
- c->fpe_list = (FontPathElementPtr *)
- malloc(sizeof(FontPathElementPtr) * num_fpes);
- if (!c->fpe_list) {
- free(c);
- return BadAlloc;
- }
- c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
- if (!c->names) {
- free(c->fpe_list);
- free(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;
- }
- int
- doListFontsWithInfo(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 = 0;
- 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;
- if (c->savedName)
- free(c->savedName);
- c->savedName = malloc(namelen + 1);
- if (c->savedName)
- memmove(c->savedName, name, namelen + 1);
- 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 *) realloc(c->reply, length);
- if (!reply) {
- err = AllocError;
- goto bail;
- }
- memset(reply + c->length, 0, length - c->length);
- 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) {
- free(fontInfo.props);
- free(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 (err == AllocError && c->client != serverClient) {
- SendErrorToClient(c->client, X_ListFontsWithInfo, 0,
- 0, FontToXError(err));
- }
- if (c->slept)
- ClientWakeup(client);
- for (i = 0; i < c->num_fpes; i++)
- FreeFPE(c->fpe_list[i]);
- free(c->reply);
- free(c->fpe_list);
- if (c->savedName)
- free(c->savedName);
- free(c);
- return TRUE;
- }
- int
- StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
- int max_names)
- {
- int i;
- LFWIclosurePtr c;
- /*
- * The right error to return here would be BadName, however the
- * specification does not allow for a Name error on this request.
- * Perhaps a better solution would be to return a nil list, i.e.
- * a list containing zero fontnames.
- */
- if (length > XLFDMAXFONTNAMELEN)
- return BadAlloc;
- if (!(c = malloc(sizeof *c)))
- goto badAlloc;
- c->fpe_list = (FontPathElementPtr *)
- malloc(sizeof(FontPathElementPtr) * num_fpes);
- if (!c->fpe_list) {
- free(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;
- c->savedName = 0;
- doListFontsWithInfo(client, c);
- return Success;
- badAlloc:
- return BadAlloc;
- }
- #define TextEltHeader 2
- #define FontShiftSize 5
- static XID clearGC[] = { CT_NONE };
- #define clearGCmask (GCClipMask)
- int
- doPolyText(ClientPtr client, register PTclosurePtr c)
- {
- FontPtr pFont = c->pGC->font, oldpFont;
- Font fid;
- int err = Success, lgerr; /* err is in X error, not font error, space */
- enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
- FontPathElementPtr fpe;
- GC *origGC = NULL;
- 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;
- 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;
- /* 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 = malloc(sizeof(PTclosureRec));
- if (!new_closure) {
- err = BadAlloc;
- goto bail;
- }
- *new_closure = *c;
- len = new_closure->endReq - new_closure->pElt;
- new_closure->data = malloc(len);
- if (!new_closure->data) {
- free(new_closure);
- err = BadAlloc;
- goto bail;
- }
- memmove(new_closure->data, new_closure->pElt, len);
- new_closure->pElt = new_closure->data;
- new_closure->endReq = new_closure->pElt + len;
- /* Step 2 */
- pGC = GetScratchGC(new_closure->pGC->depth, new_closure->pGC->pScreen);
- if (!pGC) {
- free(new_closure->data);
- free(new_closure);
- err = BadAlloc;
- goto bail;
- }
- if ((err = CopyGC(new_closure->pGC, pGC, GCFunction |
- GCPlaneMask | GCForeground |
- GCBackground | GCFillStyle |
- GCTile | GCStipple |
- GCTileStipXOrigin |
- GCTileStipYOrigin | GCFont |
- GCSubwindowMode | GCClipXOrigin |
- GCClipYOrigin | GCClipMask)) != Success) {
- FreeScratchGC(pGC);
- free(new_closure->data);
- free(new_closure);
- err = BadAlloc;
- goto bail;
- }
- c = new_closure;
- 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);
- free(c->data);
- free(c);
- }
- return TRUE;
- }
- int
- PolyText(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 FontShiftSize
- int
- doImageText(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;
- ITclosurePtr old_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 = malloc(sizeof(ITclosureRec));
- if (!new_closure) {
- err = BadAlloc;
- goto bail;
- }
- old_closure = c;
- *new_closure = *c;
- c = new_closure;
- data = malloc(c->nChars * c->itemSize);
- if (!data) {
- free(c);
- c = old_closure;
- 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) {
- free(c->data);
- free(c);
- c = old_closure;
- 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);
- free(c->data);
- free(c);
- c = old_closure;
- 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);
- free(c->data);
- free(c);
- }
- return TRUE;
- }
- int
- ImageText(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
- DetermineFPEType(char *pathname)
- {
- int i;
- for (i = 0; i < num_fpe_types; i++) {
- if ((*fpe_functions[i].name_check) (pathname))
- return i;
- }
- return -1;
- }
- static void
- FreeFontPath(FontPathElementPtr * list, int n, Bool force)
- {
- 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) {
- list[i]->refcount = found; /* ensure it will get freed */
- }
- }
- FreeFPE(list[i]);
- }
- free((char *) list);
- }
- static FontPathElementPtr
- find_existing_fpe(FontPathElementPtr * list, int num, unsigned char *name,
- int len)
- {
- 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
- SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
- {
- int i, err = 0;
- int valid_paths = 0;
- unsigned int len;
- unsigned char *cp = paths;
- FontPathElementPtr fpe = NULL, *fplist;
- fplist = (FontPathElementPtr *)
- malloc(sizeof(FontPathElementPtr) * npaths);
- if (!fplist) {
- *bad = 0;
- return BadAlloc;
- }
- for (i = 0; i < num_fpe_types; i++) {
- if (fpe_functions[i].set_path_hook)
- (*fpe_functions[i].set_path_hook) ();
- }
- for (i = 0; i < npaths; i++) {
- len = (unsigned int) (*cp++);
- if (len == 0) {
- if (persist)
- ErrorF
- ("Removing empty element from the valid list of fontpaths\n");
- err = BadValue;
- }
- else {
- /* if it's already in our active list, just reset it */
- /*
- * note that this can miss FPE's in limbo -- may be worth catching
- * them, though it'd muck up refcounting
- */
- fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
- if (fpe) {
- err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
- if (err == Successful) {
- UseFPE(fpe); /* since it'll be decref'd later when freed
- * from the old list */
- }
- else
- fpe = 0;
- }
- /* if error or can't do it, act like it's a new one */
- if (!fpe) {
- fpe = malloc(sizeof(FontPathElementRec));
- if (!fpe) {
- err = BadAlloc;
- goto bail;
- }
- fpe->name = malloc(len + 1);
- if (!fpe->name) {
- free(fpe);
- err = BadAlloc;
- goto bail;
- }
- fpe->refcount = 1;
- strncpy(fpe->name, (char *) cp, (int) len);
- fpe->name[len] = '\0';
- fpe->name_length = len;
- fpe->type = DetermineFPEType(fpe->name);
- if (fpe->type == -1)
- err = BadValue;
- else
- err = (*fpe_functions[fpe->type].init_fpe) (fpe);
- if (err != Successful) {
- if (persist) {
- ErrorF
- ("Could not init font path element %s, removing from list!\n",
- fpe->name);
- }
- free(fpe->name);
- free(fpe);
- }
- }
- }
- if (err != Successful) {
- if (!persist)
- goto bail;
- }
- else {
- fplist[valid_paths++] = fpe;
- }
- cp += len;
- }
- FreeFontPath(font_path_elements, num_fpes, FALSE);
- font_path_elements = fplist;
- if (patternCache)
- EmptyFontPatternCache(patternCache);
- num_fpes = valid_paths;
- return Success;
- bail:
- *bad = i;
- while (--valid_paths >= 0)
- FreeFPE(fplist[valid_paths]);
- free(fplist);
- return FontToXError(err);
- }
- /* XXX -- do we need to pass error down to each renderer? */
- int
- SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
- {
- int err = Success;
- if (npaths == 0) {
- if (SetDefaultFontPath(defaultFontPath) != Success)
- return BadValue;
- }
- else {
- err = SetFontPathElements(npaths, paths, error, FALSE);
- }
- return err;
- }
- int
- SetDefaultFontPath(char *path)
- {
- unsigned char *cp, *pp, *nump, *newpath;
- int num = 1, len, err, size = 0, bad;
- /* get enough for string, plus values -- use up commas */
- len = strlen(path) + 1;
- nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
- if (!newpath)
- return BadAlloc;
- pp = (unsigned char *) path;
- cp++;
- while (*pp) {
- if (*pp == ',') {
- *nump = (unsigned char) size;
- nump = cp++;
- pp++;
- num++;
- size = 0;
- }
- else {
- *cp++ = *pp++;
- size++;
- }
- }
- *nump = (unsigned char) size;
- err = SetFontPathElements(num, newpath, &bad, TRUE);
- DEALLOCATE_LOCAL(newpath);
- return err;
- }
- unsigned char *
- GetFontPath(int *count, int *length)
- {
- int i;
- unsigned char *c;
- int len;
- FontPathElementPtr fpe;
- len = 0;
- for (i = 0; i < num_fpes; i++) {
- fpe = font_path_elements[i];
- len += fpe->name_length + 1;
- }
- font_path_string = (unsigned char *) realloc(font_path_string, len);
- if (!font_path_string)
- return NULL;
- c = font_path_string;
- *length = 0;
- for (i = 0; i < num_fpes; i++) {
- fpe = font_path_elements[i];
- *c = fpe->name_length;
- *length += *c++;
- memmove(c, fpe->name, fpe->name_length);
- c += fpe->name_length;
- }
- *count = num_fpes;
- return font_path_string;
- }
- _X_EXPORT int
- LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size,
- unsigned char *data)
- {
- if (fpe_functions[pfont->fpe->type].load_glyphs)
- return (*fpe_functions[pfont->fpe->type].load_glyphs)
- (client, pfont, 0, nchars, item_size, data);
- else
- return Successful;
- }
- void
- DeleteClientFontStuff(ClientPtr client)
- {
- int i;
- FontPathElementPtr fpe;
- for (i = 0; i < num_fpes; i++) {
- fpe = font_path_elements[i];
- if (fpe_functions[fpe->type].client_died)
- (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
- }
- }
- void
- InitFonts()
- {
- patternCache = MakeFontPatternCache();
- {
- #ifdef KDRIVESERVER
- BuiltinRegisterFpeFunctions();
- #endif
- FontFileRegisterFpeFunctions();
- }
- }
- _X_EXPORT XFONT_LTO
- int
- GetDefaultPointSize()
- {
- return 120;
- }
- _X_EXPORT XFONT_LTO
- FontResolutionPtr
- GetClientResolutions(int *num)
- {
- if (requestingClient && requestingClient->fontResFunc != NULL &&
- !requestingClient->clientGone) {
- return (*requestingClient->fontResFunc) (requestingClient, num);
- }
- else {
- static struct _FontResolution res;
- ScreenPtr pScreen;
- pScreen = screenInfo.screens[0];
- res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
- /*
- * XXX - we'll want this as long as bitmap instances are prevalent
- so that we can match them from scalable fonts
- */
- if (res.x_resolution < 88)
- res.x_resolution = 75;
- else
- res.x_resolution = 100;
- res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
- if (res.y_resolution < 88)
- res.y_resolution = 75;
- else
- res.y_resolution = 100;
- res.point_size = 120;
- *num = 1;
- return &res;
- }
- }
- /*
- * returns the type index of the new fpe
- *
- * should be called (only once!) by each type of fpe when initialized
- */
- _X_EXPORT XFONT_LTO
- int
- RegisterFPEFunctions(NameCheckFunc name_func,
- InitFpeFunc init_func,
- FreeFpeFunc free_func,
- ResetFpeFunc reset_func,
- OpenFontFunc open_func,
- CloseFontFunc close_func,
- ListFontsFunc list_func,
- StartLfwiFunc start_lfwi_func,
- NextLfwiFunc next_lfwi_func,
- WakeupFpeFunc wakeup_func,
- ClientDiedFunc client_died,
- LoadGlyphsFunc load_glyphs,
- StartLaFunc start_list_alias_func,
- NextLaFunc next_list_alias_func, SetPathFunc set_path_func)
- {
- FPEFunctions *new;
- /* grow the list */
- new = (FPEFunctions *) realloc(fpe_functions,
- (num_fpe_types + 1) * sizeof(FPEFunctions));
- if (!new)
- return -1;
- fpe_functions = new;
- fpe_functions[num_fpe_types].name_check = name_func;
- fpe_functions[num_fpe_types].open_font = open_func;
- fpe_functions[num_fpe_types].close_font = close_func;
- fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
- fpe_functions[num_fpe_types].list_fonts = list_func;
- fpe_functions[num_fpe_types].start_list_fonts_with_info = start_lfwi_func;
- fpe_functions[num_fpe_types].list_next_font_with_info = next_lfwi_func;
- fpe_functions[num_fpe_types].init_fpe = init_func;
- fpe_functions[num_fpe_types].free_fpe = free_func;
- fpe_functions[num_fpe_types].reset_fpe = reset_func;
- fpe_functions[num_fpe_types].client_died = client_died;
- fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
- fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
- start_list_alias_func;
- fpe_functions[num_fpe_types].list_next_font_or_alias = next_list_alias_func;
- fpe_functions[num_fpe_types].set_path_hook = set_path_func;
- return num_fpe_types++;
- }
- void
- FreeFonts()
- {
- if (patternCache) {
- FreeFontPatternCache(patternCache);
- patternCache = 0;
- }
- FreeFontPath(font_path_elements, num_fpes, TRUE);
- font_path_elements = 0;
- num_fpes = 0;
- free(fpe_functions);
- num_fpe_types = 0;
- fpe_functions = (FPEFunctions *) 0;
- }
- /* convenience functions for FS interface */
- FontPtr
- find_old_font(XID id)
- {
- return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
- SecurityUnknownAccess);
- }
- _X_EXPORT XFONT_LTO
- Font
- GetNewFontClientID()
- {
- return FakeClientID(0);
- }
- _X_EXPORT XFONT_LTO
- int
- StoreFontClientFont(FontPtr pfont, Font id)
- {
- return AddResource(id, RT_NONE, (pointer) pfont);
- }
- _X_EXPORT XFONT_LTO
- void
- DeleteFontClientID(Font id)
- {
- FreeResource(id, RT_NONE);
- }
- _X_EXPORT XFONT_LTO
- int
- client_auth_generation(ClientPtr client)
- {
- return 0;
- }
- static int fs_handlers_installed = 0;
- static unsigned int last_server_gen;
- _X_EXPORT XFONT_LTO
- int
- init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
- {
- /* if server has reset, make sure the b&w handlers are reinstalled */
- if (last_server_gen < serverGeneration) {
- last_server_gen = serverGeneration;
- fs_handlers_installed = 0;
- }
- if (fs_handlers_installed == 0) {
- if (!RegisterBlockAndWakeupHandlers(block_handler,
- FontWakeup, (pointer) 0))
- return AllocError;
- fs_handlers_installed++;
- }
- QueueFontWakeup(fpe);
- return Successful;
- }
- _X_EXPORT XFONT_LTO
- void
- remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler,
- Bool all)
- {
- if (all) {
- /* remove the handlers if no one else is using them */
- if (--fs_handlers_installed == 0) {
- RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
- (pointer) 0);
- }
- }
- RemoveFontWakeup(fpe);
- }
|