aboutsummaryrefslogtreecommitdiff
path: root/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch
diff options
context:
space:
mode:
Diffstat (limited to 'doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch')
-rw-r--r--doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch892
1 files changed, 892 insertions, 0 deletions
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch
new file mode 100644
index 000000000..f491948f0
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch
@@ -0,0 +1,892 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original 2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c 2015-02-13 14:03:44.744441510 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/* */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
++/* */
++/* NXAGENT, NX protocol compression and NX extensions to this software */
++/* are copyright of NoMachine. Redistribution and use of the present */
++/* software is allowed according to terms specified in the file LICENSE */
++/* which comes in the source distribution. */
++/* */
++/* Check http://www.nomachine.com/licensing.html for applicability. */
++/* */
++/* NX and NoMachine are trademarks of Medialogic S.p.A. */
++/* */
++/* All rights reserved. */
++/* */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+ /* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+ /************************************************************************
+@@ -68,12 +85,84 @@
+ #include "dixfontstr.h"
+ #include "closestr.h"
+
++/*
++#define NXAGENT_DEBUG
++*/
++
+ #ifdef DEBUG
+ #include <stdio.h>
+ #endif
+
++#include "Agent.h"
++#include "Font.h"
++
++#ifndef NX_TRANS_SOCKET
++
++#define NX_TRANS_SOCKET
++
++#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:
++
++ strncpy(_NXFontPath, path, 1023);
++ _NXFontPath[1023] = '\0';
++
++#ifdef NX_TRANS_TEST
++ fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
++#endif
++
++ return _NXFontPath;
++}
++
++#endif
++
+ #ifdef PANORAMIX
+-#include "panoramiX.h"
++#include "../../Xext/panoramiX.h"
++#include "../../Xext/panoramiXsrv.h"
+ #endif
+
+ #ifdef LBX
+@@ -245,6 +334,9 @@
+ *newname;
+ int newlen;
+ int aliascount = 20;
++ char nxagentOrigFontName[256];
++ int nxagentOrigFontNameLen;
++
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+@@ -276,6 +368,13 @@
+
+ BitmapFormatScanlineUnit8;
+
++
++ nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
++
++ memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
++
++ nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
++
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+@@ -324,6 +423,9 @@
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
++#endif
+ }
+ return TRUE;
+ }
+@@ -352,10 +454,15 @@
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+- if (!(*pScr->RealizeFont) (pScr, pfont))
++
++ /* NXAGENT uses useless screen pointer to pass the original font name
++ * to realizeFont, could be a source of problems in the future.
++ */
++
++ if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+- err = AllocError;
++ err=BadFontName;
+ goto bail;
+ }
+ }
+@@ -365,8 +472,19 @@
+ err = AllocError;
+ goto bail;
+ }
++ if( nxagentFontPriv(pfont) -> mirrorID == 0 )
++ {
++ extern RESTYPE RT_NX_FONT;
++
++ nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
++ if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
++ FreeResource(c->fontid, RT_NONE);
++ err = AllocError;
++ goto bail;
++ }
++ }
+ if (patternCache && pfont != c->non_cachable_font)
+- CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
++ CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+ pfont);
+ bail:
+ if (err != Successful && c->client != serverClient) {
+@@ -374,7 +492,12 @@
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
++ {
+ ClientWakeup(c->client);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
++#endif
++ }
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+@@ -502,7 +625,10 @@
+ LbxFreeFontTag(pfont);
+ #endif
+ #ifdef XF86BIGFONT
+- XF86BigfontFreeFontShm(pfont);
++ {
++ extern void XF86BigfontFreeFontShm(FontPtr);
++ XF86BigfontFreeFontShm(pfont);
++ }
+ #endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+@@ -631,6 +757,9 @@
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
++#endif
+ }
+ return TRUE;
+ }
+@@ -677,6 +806,12 @@
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
++#endif
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
++#endif
+ }
+ return TRUE;
+ }
+@@ -813,6 +948,24 @@
+ reply.nFonts--;
+ else
+ {
++ {
++ /* dirty hack: don't list to client fonts not existing on the remote side */
++ char tmp[256];
++
++ memcpy(tmp, names->names[i], names->length[i]);
++ tmp[ names->length[i] ] = 0;
++
++ if (nxagentFontLookUp(tmp) == 0)
++ {
++#ifdef NXAGENT_FONTMATCH_DEBUG
++ fprintf(stderr, "doListFontsAndAliases:\n");
++ fprintf(stderr, " removing font: %s \n", tmp);
++#endif
++ reply.nFonts--;
++ stringLens -= names->length[i];
++ continue;
++ }
++ }
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+@@ -827,7 +980,12 @@
+
+ bail:
+ if (c->slept)
++ {
+ ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
++#endif
++ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+@@ -862,7 +1020,7 @@
+ xfree(c);
+ return BadAlloc;
+ }
+- c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
++ c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+@@ -933,6 +1091,9 @@
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
++#endif
+ }
+ return TRUE;
+ }
+@@ -954,6 +1115,9 @@
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
++#endif
+ }
+ return TRUE;
+ }
+@@ -1035,6 +1199,23 @@
+ }
+ else if (err == Successful)
+ {
++
++ if (c->haveSaved)
++ {
++ numFonts = c->savedNumFonts;
++ name = c->savedName;
++ namelen = strlen(name);
++ }
++
++ if (nxagentFontLookUp(name) == 0)
++ {
++#ifdef NXAGENT_FONTMATCH_DEBUG
++ fprintf(stderr, "doListFontsAndAliases (with info):\n");
++ fprintf(stderr, " removing font: %s \n", name);
++#endif
++ continue;
++ }
++
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+@@ -1048,12 +1229,6 @@
+ 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) +
+@@ -1100,7 +1275,12 @@
+ WriteSwappedDataToClient(client, length, &finalReply);
+ bail:
+ if (c->slept)
++ {
+ ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
++#endif
++ }
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+@@ -1347,6 +1527,11 @@
+ 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 |
+@@ -1371,6 +1556,9 @@
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) 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;
+@@ -1419,6 +1607,9 @@
+ 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 */
+@@ -1535,6 +1726,11 @@
+ 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 |
+@@ -1553,6 +1749,10 @@
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
++#endif
++
+ }
+ return TRUE;
+ }
+@@ -1575,6 +1775,9 @@
+ 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 */
+@@ -1751,11 +1954,13 @@
+ 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);
+ }
+@@ -1817,11 +2022,19 @@
+ 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 == ',') {
+@@ -2148,3 +2361,445 @@
+ }
+
+ #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;
++ 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)nxdoListFontsAndAliases,
++ (pointer) fss);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
++#endif
++ }
++ 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)nxdoListFontsAndAliases,
++ (pointer) fss);
++ c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
++#endif
++ }
++ 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)nxdoListFontsAndAliases,
++ (pointer) fss);
++ c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
++#endif
++ }
++ return TRUE;
++ }
++ if (err == FontNameAlias) {
++ if (resolved) xfree(resolved);
++ resolved = (char *) xalloc(resolvedlen + 1);
++ if (resolved)
++ {
++ memmove(resolved, tmpname, resolvedlen);
++ resolved[resolvedlen] = '\0';
++ }
++ }
++ }
++
++ if (err == Successful)
++ {
++ if (c->haveSaved)
++ {
++ if (c->savedName)
++ {
++ memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
++ tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
++ if (nxagentFontLookUp(tmp))
++ break;
++ else tmp[0]=0;
++ }
++ }
++ else
++ {
++ memcpy(tmp,name,namelen>255?255:namelen);
++ tmp[namelen>255?256:namelen]=0;
++ if (nxagentFontLookUp(tmp))
++ break;
++ else tmp[0]=0;
++ }
++ }
++
++ /*
++ * 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)
++ xfree(c->savedName);
++ c->savedName = (char *)xalloc(namelen + 1);
++ if (c->savedName)
++ {
++ memmove(c->savedName, name, namelen);
++ c->savedName[namelen] = '\0';
++ }
++ 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
++ */
++bail:
++finish:
++ if (strlen(tmp))
++ {
++#ifdef NXAGENT_FONTMATCH_DEBUG
++ fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
++#endif
++ memcpy(oc->fontname, tmp, strlen(tmp));
++ oc->fnamelen = strlen(tmp);
++
++ oc->origFontName = oc->fontname;
++ oc->origFontNameLen = oc->fnamelen;
++
++ }
++ else
++ {
++ for (i = 0; i < c->names->nnames; i++)
++ {
++ if (c->names->length[i] > 255)
++ continue;
++ else
++ {
++ memcpy(tmp, c->names->names[i], c->names->length[i]);
++ tmp[ c->names->length[i] ] = 0;
++ if (nxagentFontLookUp(tmp) == 0)
++ continue;
++ memcpy(oc->fontname, tmp, strlen(tmp));
++ oc->fnamelen = strlen(tmp);
++
++ oc->origFontName = oc->fontname;
++ oc->origFontNameLen = oc->fnamelen;
++
++#ifdef NXAGENT_FONTMATCH_DEBUG
++ fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
++#endif
++ break;
++ }
++ }
++ }
++
++ if (c->slept)
++ {
++ ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++ fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
++#endif
++ }
++ for (i = 0; i < c->num_fpes; i++)
++ FreeFPE(c->fpe_list[i]);
++ xfree(c->fpe_list);
++ if (c->savedName) xfree(c->savedName);
++ FreeFontNames(c->names);
++ xfree(c);
++ xfree(fss);
++ if (resolved) xfree(resolved);
++
++ return doOpenFont(client, oc);
++}
++
++int
++nxOpenFont(client, fid, flags, lenfname, pfontname)
++ ClientPtr client;
++ XID fid;
++ Mask flags;
++ unsigned lenfname;
++ char *pfontname;
++{
++ nxFsPtr fss;
++ LFclosurePtr c;
++ OFclosurePtr oc;
++ 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, (pointer) cached))
++ return BadAlloc;
++ cached->refcnt++;
++ return Success;
++ }
++ }
++ if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
++ return BadAlloc;
++
++ if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
++ {
++ xfree(fss);
++ return BadAlloc;
++ }
++ c->fpe_list = (FontPathElementPtr *)
++ xalloc(sizeof(FontPathElementPtr) * num_fpes);
++ if (!c->fpe_list) {
++ xfree(c);
++ xfree(fss);
++ return BadAlloc;
++ }
++ c->names = MakeFontNamesRecord(100);
++ if (!c->names)
++ {
++ xfree(c->fpe_list);
++ xfree(c);
++ xfree(fss);
++ return BadAlloc;
++ }
++ memmove( c->current.pattern, 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->num_fpes = num_fpes;
++ c->current.patlen = lenfname;
++ c->current.current_fpe = 0;
++ c->current.max_names = nxagentMaxFontNames;
++ c->current.list_started = FALSE;
++ c->current.private = 0;
++ c->haveSaved = FALSE;
++ c->slept = FALSE;
++ c->savedName = 0;
++
++ oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
++ if (!oc)
++ {
++ for (i = 0; i < c->num_fpes; i++)
++ FreeFPE(c->fpe_list[i]);
++ xfree(c->fpe_list);
++ xfree(c);
++ xfree(fss);
++ return BadAlloc;
++ }
++ oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
++ oc->origFontName = pfontname;
++ oc->origFontNameLen = lenfname;
++ if (!oc->fontname) {
++ for (i = 0; i < c->num_fpes; i++)
++ FreeFPE(c->fpe_list[i]);
++ xfree(c->fpe_list);
++ xfree(c);
++ xfree(oc);
++ xfree(fss);
++ 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
++ */
++ oc->fpe_list = (FontPathElementPtr *)
++ xalloc(sizeof(FontPathElementPtr) * num_fpes);
++ if (!oc->fpe_list) {
++ xfree(oc->fontname);
++ xfree(oc);
++ for (i = 0; i < c->num_fpes; i++)
++ FreeFPE(c->fpe_list[i]);
++ xfree(c->fpe_list);
++ xfree(c);
++ xfree(fss);
++ return BadAlloc;
++ }
++ memmove(oc->fontname, pfontname, lenfname);
++ for (i = 0; i < num_fpes; i++) {
++ oc->fpe_list[i] = font_path_elements[i];
++ UseFPE(oc->fpe_list[i]);
++ }
++ oc->client = client;
++ oc->fontid = fid;
++ oc->current_fpe = 0;
++ oc->num_fpes = num_fpes;
++ oc->fnamelen = lenfname;
++ oc->slept = FALSE;
++ oc->flags = flags;
++ oc->non_cachable_font = cached;
++ fss->c=c;
++ fss->oc=oc;
++ nxdoListFontsAndAliases(client, fss);
++ return Success;
++}
++