Commit a5c7b248 authored by Mike Gabriel's avatar Mike Gabriel

hw/nxagent/NXdixfonts.c: Shrink file, drop duplicate code that can identically…

hw/nxagent/NXdixfonts.c: Shrink file, drop duplicate code that can identically be found in dix/dixfonts.c. Also remove NX'ish code from dix/dixfonts.c.
parent 2ba50086
......@@ -16,6 +16,7 @@ FFS_OBJ = ffs.o
#if (!(defined(NXAgentServer) && NXAgentServer))
NXAGENT_SKIP_SRCS = \
dispatch.c \
dixfonts.c \
events.c \
extension.c \
glyphcurs.c \
......@@ -25,6 +26,7 @@ NXAGENT_SKIP_SRCS = \
$(NULL)
NXAGENT_SKIP_OBJS = \
dispatch.o \
dixfonts.o \
events.o \
extension.o \
glyphcurs.o \
......@@ -50,7 +52,6 @@ SRCS = \
swapreq.c \
tables.c \
initatoms.c \
dixfonts.c \
privates.c \
pixmap.c \
$(NXAGENT_SKIP_SRCS) \
......@@ -72,7 +73,6 @@ OBJS = \
swapreq.o \
tables.o \
initatoms.o \
dixfonts.o \
privates.o \
pixmap.o \
$(NXAGENT_SKIP_OBJS) \
......
......@@ -72,63 +72,6 @@ Equipment Corporation.
#include <stdio.h>
#endif
#ifdef NX_TRANS_SOCKET
char _NXFontPath[1024];
/*
* Override the default font path and make
* it configurable at run time, based on
* the NX_FONT environment.
*/
static const char *_NXGetFontPath(const char *path)
{
const char *fontEnv;
/*
* Check the environment only once.
*/
if (*_NXFontPath != '\0')
{
return _NXFontPath;
}
fontEnv = getenv("NX_FONT");
if (fontEnv != NULL && *fontEnv != '\0')
{
if (strlen(fontEnv) + 1 > 1024)
{
#ifdef NX_TRANS_TEST
fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
#endif
goto _NXGetFontPathError;
}
strcpy(_NXFontPath, fontEnv);
#ifdef NX_TRANS_TEST
fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
#endif
return _NXFontPath;
}
_NXGetFontPathError:
strcpy(_NXFontPath, path);
#ifdef NX_TRANS_TEST
fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
#endif
return _NXFontPath;
}
#endif
#ifdef PANORAMIX
#include "panoramiX.h"
#endif
......@@ -288,6 +231,7 @@ FreeFPE (FontPathElementPtr fpe)
}
}
#ifndef NXAGENT_SERVER
static Bool
doOpenFont(ClientPtr client, OFclosurePtr c)
{
......@@ -438,6 +382,7 @@ bail:
xfree(c);
return TRUE;
}
#endif /* NXAGENT_SERVER */
int
OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
......@@ -634,6 +579,7 @@ QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
return;
}
#ifndef NXAGENT_SERVER
static Bool
doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
{
......@@ -1163,6 +1109,7 @@ bail:
xfree(c);
return TRUE;
}
#endif /* NXAGENT_SERVER */
int
StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
......@@ -1401,6 +1348,13 @@ doPolyText(ClientPtr client, register PTclosurePtr c)
err = BadAlloc;
goto bail;
}
#ifdef NXAGENT_SERVER
pGC->tileIsPixel = TRUE;
pGC->tile.pixel = 0;
pGC->stipple = NullPixmap;
#endif
if ((err = CopyGC(c->pGC, pGC, GCFunction |
GCPlaneMask | GCForeground |
GCBackground | GCFillStyle |
......@@ -1593,6 +1547,13 @@ doImageText(ClientPtr client, register ITclosurePtr c)
err = BadAlloc;
goto bail;
}
#ifdef NXAGENT_SERVER
pGC->tileIsPixel = TRUE;
pGC->tile.pixel = 0;
pGC->stipple = NullPixmap;
#endif
if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
GCForeground | GCBackground | GCFillStyle |
GCTile | GCStipple | GCTileStipXOrigin |
......@@ -1733,7 +1694,6 @@ find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int le
return (FontPathElementPtr) 0;
}
static int
SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
{
......@@ -1810,11 +1770,13 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
err = (*fpe_functions[fpe->type].init_fpe) (fpe);
if (err != Successful)
{
#ifndef NXAGENT_SERVER
if (persist)
{
ErrorF("Could not init font path element %s, removing from list!\n",
fpe->name);
}
#endif /* NXAGENT_SERVER */
xfree (fpe->name);
xfree (fpe);
}
......@@ -1862,6 +1824,7 @@ SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
return err;
}
#ifndef NXAGENT_SERVER
int
SetDefaultFontPath(char *path)
{
......@@ -1876,19 +1839,11 @@ SetDefaultFontPath(char *path)
bad;
/* get enough for string, plus values -- use up commas */
#ifdef NX_TRANS_SOCKET
len = strlen(_NXGetFontPath(path)) + 1;
#else
len = strlen(path) + 1;
#endif
nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
if (!newpath)
return BadAlloc;
#ifdef NX_TRANS_SOCKET
pp = (unsigned char *) _NXGetFontPath(path);
#else
pp = (unsigned char *) path;
#endif
cp++;
while (*pp) {
if (*pp == ',') {
......@@ -1910,6 +1865,7 @@ SetDefaultFontPath(char *path)
return err;
}
#endif /* NXAGENT_SERVER */
unsigned char *
GetFontPath(int *count, int *length)
......
......@@ -68,31 +68,18 @@ Equipment Corporation.
******************************************************************/
/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
#define NEED_REPLIES
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <nx-X11/X.h>
#include <nx-X11/Xmd.h>
#include <nx-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"
static Bool doOpenFont(ClientPtr client, OFclosurePtr c);
static Bool doListFontsAndAliases(ClientPtr client, LFclosurePtr c);
#include "../../dix/dixfonts.c"
/*
#define NXAGENT_DEBUG
*/
#ifdef DEBUG
#include <stdio.h>
#endif
#include "Agent.h"
#include "Font.h"
......@@ -160,170 +147,6 @@ _NXGetFontPathError:
#endif
#ifdef PANORAMIX
#include "../../Xext/panoramiX.h"
#include "../../Xext/panoramiXsrv.h"
#endif
#ifdef LBX
#include "lbxserve.h"
#endif
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
#include <nx-X11/extensions/xf86bigfont.h>
#endif
#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
extern void register_fpe_functions(void);
extern void * fosNaturalParams;
extern FontPtr defaultFont;
static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
static int num_fpes = 0;
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;
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) {
#ifdef DEBUG
fprintf(stderr, "re-queueing fpe wakeup\n");
#endif
return;
}
}
if (num_slept_fpes == size_slept_fpes) {
new = (FontPathElementPtr *)
xrealloc(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(void * data, int count, void * 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);
xfree(fpe->name);
xfree(fpe);
}
}
static Bool
doOpenFont(ClientPtr client, OFclosurePtr c)
{
......@@ -509,206 +332,6 @@ bail:
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 = (char *)xalloc(lenfname + 1);
memmove(f, pfontname, lenfname);
f[lenfname] = '\0';
ErrorF("OpenFont: fontname is \"%s\"\n", f);
xfree(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, (void *) cached))
return BadAlloc;
cached->refcnt++;
return Success;
}
}
c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
if (!c)
return BadAlloc;
c->fontname = (char *) xalloc(lenfname);
c->origFontName = pfontname;
c->origFontNameLen = lenfname;
if (!c->fontname) {
xfree(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 *)
xalloc(sizeof(FontPathElementPtr) * num_fpes);
if (!c->fpe_list) {
xfree(c->fontname);
xfree(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
*/
int
CloseFont(void * 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 LBX
LbxFreeFontTag(pfont);
#endif
#ifdef XF86BIGFONT
{
extern void XF86BigfontFreeFontShm(FontPtr);
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);
i = 0;
for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
*prCI = *charInfos[i];
prCI++;
ninfos++;
}
}
return;
}
static Bool
doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
......@@ -1294,1094 +917,82 @@ bail:
return TRUE;
}
int
StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
int max_names)
SetDefaultFontPath(char *path)
{
int i;
LFWIclosurePtr c;
unsigned char *cp,
*pp,
*nump,
*newpath;
int num = 1,
len,
err,
size = 0,
bad;
/*
* 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)
/* get enough for string, plus values -- use up commas */
#ifdef NX_TRANS_SOCKET
len = strlen(_NXGetFontPath(path)) + 1;
#else
len = strlen(path) + 1;
#endif
nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
if (!newpath)
return BadAlloc;
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;
#ifdef NX_TRANS_SOCKET
pp = (unsigned char *) _NXGetFontPath(path);
#else
pp = (unsigned char *) path;
#endif
cp++;
while (*pp) {
if (*pp == ',') {
*nump = (unsigned char) size;
nump = cp++;
pp++;
num++;
size = 0;
} else {
*cp++ = *pp++;
size++;
}
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;
*nump = (unsigned char) size;
err = SetFontPathElements(num, newpath, &bad, TRUE);
DEALLOCATE_LOCAL(newpath);
return err;
}
#define TextEltHeader 2
#define FontShiftSize 5
static XID clearGC[] = { CT_NONE };
#define clearGCmask (GCClipMask)
int
doPolyText(ClientPtr client, register PTclosurePtr c)
typedef struct
{
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 = NEVER_SLEPT;
FontPathElementPtr fpe;
GC *origGC = NULL;
LFclosurePtr c;
OFclosurePtr oc;
} nxFs,*nxFsPtr;
if (client->clientGone)
{
fpe = c->pGC->font->fpe;
(*fpe_functions[fpe->type].client_died) ((void *) 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) ((void *) 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;
}
pGC->tileIsPixel = TRUE;
pGC->tile.pixel = 0;
pGC->stipple = NullPixmap;
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,
(void *) c);
#ifdef NXAGENT_DEBUG
fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
#endif
/* 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) {
#ifdef PANORAMIX
if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
#endif
SendErrorToClient(c->client, c->reqType, 0, 0, err);
}
if (c->slept)
{
ClientWakeup(c->client);
#ifdef NXAGENT_DEBUG
fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
#endif
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;
}
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) ((void *) 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) ((void *) 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 = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
if (!new_closure)
{
err = BadAlloc;
goto bail;
}
old_closure = c;
*new_closure = *c;
c = new_closure;
data = (unsigned char *)xalloc(c->nChars * c->itemSize);
if (!data)
{
xfree(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)
{
xfree(c->data);
xfree(c);
c = old_closure;
err = BadAlloc;
goto bail;
}
pGC->tileIsPixel = TRUE;
pGC->tile.pixel = 0;
pGC->stipple = NullPixmap;
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);
c = old_closure;
err = BadAlloc;
goto bail;
}
c->pGC = pGC;
ValidateGC(c->pDraw, c->pGC);
c->slept = TRUE;
ClientSleep(client, (ClientSleepProcPtr)doImageText, (void *) c);
#ifdef NXAGENT_DEBUG
fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
#endif
}
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);
#ifdef NXAGENT_DEBUG
fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
#endif
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;
}
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) {
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
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 *)
xalloc(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 = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
if (!fpe)
{
err = BadAlloc;
goto bail;
}
fpe->name = (char *) xalloc(len + 1);
if (!fpe->name)
{
xfree(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)
{
#ifndef NXAGENT_SERVER
if (persist)
{
ErrorF("Could not init font path element %s, removing from list!\n",
fpe->name);
}
#endif
xfree (fpe->name);
xfree (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]);
xfree(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 */
#ifdef NX_TRANS_SOCKET
len = strlen(_NXGetFontPath(path)) + 1;
#else
len = strlen(path) + 1;
#endif
nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
if (!newpath)
return BadAlloc;
#ifdef NX_TRANS_SOCKET
pp = (unsigned char *) _NXGetFontPath(path);
#else
pp = (unsigned char *) path;
#endif
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 *) xrealloc(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;
}
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) ((void *) client, fpe);
}
}
void
InitFonts ()
{
patternCache = MakeFontPatternCache();
register_fpe_functions();
}
int
GetDefaultPointSize ()
{
return 120;
}
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
*/
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 *) xrealloc(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;
xfree(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);
}
Font
GetNewFontClientID()
{
return FakeClientID(0);
}
int
StoreFontClientFont(FontPtr pfont, Font id)
{
return AddResource(id, RT_NONE, (void *) pfont);
}
void
DeleteFontClientID(Font id)
{
FreeResource(id, RT_NONE);
}
int
client_auth_generation(ClientPtr client)
{
return 0;
}
static int fs_handlers_installed = 0;
static unsigned int last_server_gen;
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) {
#ifdef DEBUG
fprintf(stderr, "adding FS b & w handlers\n");
#endif
if (!RegisterBlockAndWakeupHandlers(block_handler,
FontWakeup, (void *) 0))
return AllocError;
fs_handlers_installed++;
}
QueueFontWakeup(fpe);
return Successful;
}
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) {
#ifdef DEBUG
fprintf(stderr, "removing FS b & w handlers\n");
#endif
RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
(void *) 0);
}
}
RemoveFontWakeup(fpe);
}
#ifdef DEBUG
#define GLWIDTHBYTESPADDED(bits,nbytes) \
((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
:(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
:(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
:(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
: 0)
#define GLYPH_SIZE(ch, nbytes) \
GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
(ch)->metrics.leftSideBearing, (nbytes))
void
dump_char_ascii(CharInfoPtr cip)
{
int r,
l;
int bpr;
int byte;
static unsigned maskTab[] = {
(1 << 7), (1 << 6), (1 << 5), (1 << 4),
(1 << 3), (1 << 2), (1 << 1), (1 << 0),
};
bpr = GLYPH_SIZE(cip, 4);
for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
void * row = (void *) cip->bits + r * bpr;
byte = 0;
for (l = 0; l <= (cip->metrics.rightSideBearing -
cip->metrics.leftSideBearing); l++) {
if (maskTab[l & 7] & (((int *)row)[l >> 3]))
putchar('X');
else
putchar('.');
}
putchar('\n');
}
}
#endif
typedef struct
{
LFclosurePtr c;
OFclosurePtr oc;
} nxFs,*nxFsPtr;
static Bool
#if NeedFunctionPrototypes
nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
#else
nxdoListFontsAndAliases(client, fss)
ClientPtr client;
nxFsPtr fss;
#endif
{
LFclosurePtr c=fss->c;
OFclosurePtr oc=fss->oc;
FontPathElementPtr fpe;
int err = Successful;
char *name, *resolved=NULL;
int namelen, resolvedlen;
int i;
int aliascount = 0;
char tmp[256];
tmp[0]=0;
static Bool
#if NeedFunctionPrototypes
nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
#else
nxdoListFontsAndAliases(client, fss)
ClientPtr client;
nxFsPtr fss;
#endif
{
LFclosurePtr c=fss->c;
OFclosurePtr oc=fss->oc;
FontPathElementPtr fpe;
int err = Successful;
char *name, *resolved=NULL;
int namelen, resolvedlen;
int i;
int aliascount = 0;
char tmp[256];
tmp[0]=0;
if (client->clientGone)
{
if (c->current.current_fpe < c->num_fpes)
......@@ -2796,4 +1407,3 @@ nxOpenFont(client, fid, flags, lenfname, pfontname)
nxdoListFontsAndAliases(client, fss);
return Success;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment