summaryrefslogtreecommitdiff
path: root/hw/dmx/dmxfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/dmx/dmxfont.c')
-rw-r--r--hw/dmx/dmxfont.c597
1 files changed, 309 insertions, 288 deletions
diff --git a/hw/dmx/dmxfont.c b/hw/dmx/dmxfont.c
index 34161f214..7ef7ad971 100644
--- a/hw/dmx/dmxfont.c
+++ b/hw/dmx/dmxfont.c
@@ -49,36 +49,38 @@
#include "dixfont.h"
#include "dixstruct.h"
-static int (*dmxSaveProcVector[256])(ClientPtr);
-static int dmxFontLastError;
+static int (*dmxSaveProcVector[256]) (ClientPtr);
+static int dmxFontLastError;
-static int dmxFontErrorHandler(Display *dpy, XErrorEvent *ev)
+static int
+dmxFontErrorHandler(Display * dpy, XErrorEvent * ev)
{
dmxFontLastError = ev->error_code;
return 0;
}
-static char **dmxGetFontPath(int *npaths)
+static char **
+dmxGetFontPath(int *npaths)
{
- char **fp;
- unsigned char *c, *paths;
- char *newfp;
- int len, l, i;
+ char **fp;
+ unsigned char *c, *paths;
+ char *newfp;
+ int len, l, i;
GetFontPath(serverClient, npaths, &len, &paths);
newfp = malloc(*npaths + len);
- c = (unsigned char *)newfp;
+ c = (unsigned char *) newfp;
fp = malloc(*npaths * sizeof(*fp));
- memmove(newfp, paths+1, *npaths + len - 1);
+ memmove(newfp, paths + 1, *npaths + len - 1);
l = *paths;
for (i = 0; i < *npaths; i++) {
- fp[i] = (char *)c;
- c += l;
- l = *c;
- *c++ = '\0';
+ fp[i] = (char *) c;
+ c += l;
+ l = *c;
+ *c++ = '\0';
}
#if DMX_FONTPATH_DEBUG
@@ -89,18 +91,20 @@ static char **dmxGetFontPath(int *npaths)
return fp;
}
-static void dmxFreeFontPath(char **fp)
+static void
+dmxFreeFontPath(char **fp)
{
free(fp[0]);
free(fp);
}
-static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
+static Bool
+dmxCheckFontPathElement(DMXScreenInfo * dmxScreen, char *fp)
{
- int (*oldErrorHandler)(Display *, XErrorEvent *);
+ int (*oldErrorHandler) (Display *, XErrorEvent *);
if (!dmxScreen->beDisplay)
- return TRUE;
+ return TRUE;
dmxFontLastError = 0;
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
@@ -111,18 +115,20 @@ static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
return dmxFontLastError == 0;
}
-static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
+static int
+dmxSetFontPath(DMXScreenInfo * dmxScreen)
{
- int (*oldErrorHandler)(Display *, XErrorEvent *);
+ int (*oldErrorHandler) (Display *, XErrorEvent *);
char **fp;
- int result = Success;
- int npaths;
+ int result = Success;
+ int npaths;
if (!dmxScreen->beDisplay)
- return result;
+ return result;
fp = dmxGetFontPath(&npaths);
- if (!fp) return BadAlloc;
+ if (!fp)
+ return BadAlloc;
dmxFontLastError = 0;
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
@@ -131,12 +137,12 @@ static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
XSetErrorHandler(oldErrorHandler);
if (dmxFontLastError) {
- result = dmxFontLastError;
- /* We could set *error here to the offending path, but it is
- * ignored, so we don't bother figuring out which path is bad.
- * If we do add this support in the future, we'll need to add
- * error to the function's argument list.
- */
+ result = dmxFontLastError;
+ /* We could set *error here to the offending path, but it is
+ * ignored, so we don't bother figuring out which path is bad.
+ * If we do add this support in the future, we'll need to add
+ * error to the function's argument list.
+ */
}
dmxFreeFontPath(fp);
@@ -144,14 +150,15 @@ static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
return result;
}
-static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
+static int
+dmxCheckFontPath(DMXScreenInfo * dmxScreen, int *error)
{
char **oldFontPath;
- int nOldPaths;
- int result = Success;
+ int nOldPaths;
+ int result = Success;
if (!dmxScreen->beDisplay)
- return result;
+ return result;
/* Save old font path */
oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
@@ -166,29 +173,31 @@ static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
return result;
}
-static int dmxProcSetFontPath(ClientPtr client)
+static int
+dmxProcSetFontPath(ClientPtr client)
{
unsigned char *ptr;
- unsigned long nbytes, total, n;
- long nfonts;
- int i, result;
+ unsigned long nbytes, total, n;
+ long nfonts;
+ int i, result;
unsigned char *oldFontPath, *tmpFontPath;
- int nOldPaths;
- int lenOldPaths;
+ int nOldPaths;
+ int lenOldPaths;
+
REQUEST(xSetFontPathReq);
-
+
REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
-
+
nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
total = nbytes;
- ptr = (unsigned char *)&stuff[1];
+ ptr = (unsigned char *) &stuff[1];
nfonts = stuff->nFonts;
while (--nfonts >= 0) {
- if ((total == 0) || (total < (n = (*ptr + 1))))
- return BadLength;
- total -= n;
- ptr += n;
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return BadLength;
+ total -= n;
+ ptr += n;
}
if (total >= 4)
return BadLength;
@@ -197,18 +206,19 @@ static int dmxProcSetFontPath(ClientPtr client)
oldFontPath = malloc(nOldPaths + lenOldPaths);
memmove(oldFontPath, tmpFontPath, nOldPaths + lenOldPaths);
- result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
if (!result) {
- int error = 0;
- for (i = 0; i < dmxNumScreens; i++)
- if ((result = dmxCheckFontPath(&dmxScreens[i], &error)))
- break;
-
- if (result) {
- /* Restore old fontpath in the DMX server */
- SetFontPath(client, nOldPaths, oldFontPath);
- client->errorValue = error;
- }
+ int error = 0;
+
+ for (i = 0; i < dmxNumScreens; i++)
+ if ((result = dmxCheckFontPath(&dmxScreens[i], &error)))
+ break;
+
+ if (result) {
+ /* Restore old fontpath in the DMX server */
+ SetFontPath(client, nOldPaths, oldFontPath);
+ client->errorValue = error;
+ }
}
free(oldFontPath);
@@ -219,47 +229,50 @@ static int dmxProcSetFontPath(ClientPtr client)
* pointers, DMX also hooks in at the ProcVector[] level. Here the old
* ProcVector function pointers are saved and the new ProcVector
* function pointers are initialized. */
-void dmxInitFonts(void)
+void
+dmxInitFonts(void)
{
- int i;
+ int i;
for (i = 0; i < 256; i++)
- dmxSaveProcVector[i] = ProcVector[i];
+ dmxSaveProcVector[i] = ProcVector[i];
ProcVector[X_SetFontPath] = dmxProcSetFontPath;
}
/** Reset font support by restoring the original ProcVector function
* pointers. */
-void dmxResetFonts(void)
+void
+dmxResetFonts(void)
{
- int i;
+ int i;
for (i = 0; i < 256; i++)
- ProcVector[i] = dmxSaveProcVector[i];
+ ProcVector[i] = dmxSaveProcVector[i];
}
/** Load the font, \a pFont, on the back-end server associated with \a
* pScreen. When a font is loaded, the font path on back-end server is
* first initialized to that specified on the command line with the
* -fontpath options, and then the font is loaded. */
-Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
+Bool
+dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
- const char *name;
- char **oldFontPath = NULL;
- int nOldPaths;
- Atom name_atom, value_atom;
- int i;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
+ const char *name;
+ char **oldFontPath = NULL;
+ int nOldPaths;
+ Atom name_atom, value_atom;
+ int i;
/* Make sure we have a font private struct to work with */
if (!pFontPriv)
- return FALSE;
+ return FALSE;
/* Don't load a font over top of itself */
if (pFontPriv->font[pScreen->myNum]) {
- return TRUE; /* Already loaded font */
+ return TRUE; /* Already loaded font */
}
/* Save old font path */
@@ -267,132 +280,131 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
/* Set the font path for the font about to be loaded on the back-end */
if (dmxSetFontPath(dmxScreen)) {
- char **fp;
- int npaths;
- Bool *goodfps;
-
- /* This could fail only when first starting the X server and
- * loading the default font. If it fails here, then the default
- * font path is invalid, no default font path will be set, the
- * DMX server will fail to load the default font, and it will
- * exit with an error unless we remove the offending font paths
- * with the -ignorebadfontpaths command line option.
- */
-
- fp = dmxGetFontPath(&npaths);
- if (!fp) {
- dmxLog(dmxError,
- "No default font path set.\n");
- dmxLog(dmxError,
- "Please see the Xdmx man page for information on how to\n");
- dmxLog(dmxError,
- "initialize the DMX server's default font path.\n");
- XFreeFontPath(oldFontPath);
- return FALSE;
- }
-
- if (!dmxFontPath)
- dmxLog(dmxWarning, "No default font path is set.\n");
-
- goodfps = malloc(npaths * sizeof(*goodfps));
-
- dmxLog(dmxError,
- "The DMX server failed to set the following font paths on "
- "screen #%d:\n", pScreen->myNum);
-
- for (i = 0; i < npaths; i++)
- if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
- dmxLog(dmxError, " %s\n", fp[i]);
-
- if (dmxIgnoreBadFontPaths) {
- char *newfp;
- int newnpaths = 0;
- int len = 0;
- int j = 0;
-
- dmxLog(dmxError,
- "These font paths will not be used because the "
- "\"-ignorebadfontpaths\"\n");
- dmxLog(dmxError,
- "option is set.\n");
-
- for (i = 0; i < npaths; i++)
- if (goodfps[i]) {
- len += strlen(fp[i]) + 1;
- newnpaths++;
- }
-
- if (!newnpaths) {
- /* No valid font paths were found */
- dmxLog(dmxError,
- "After removing the font paths above, no valid font "
- "paths were\n");
- dmxLog(dmxError,
- "available. Please check that the font paths set on "
- "the command\n");
- dmxLog(dmxError,
- "line or in the configuration file via the "
- "\"-fontpath\" option\n");
- dmxLog(dmxError,
- "are valid on all back-end servers. See the Xdmx man "
- "page for\n");
- dmxLog(dmxError,
- "more information on font paths.\n");
- dmxFreeFontPath(fp);
- XFreeFontPath(oldFontPath);
- free(goodfps);
- return FALSE;
- }
-
- newfp = malloc(len * sizeof(*newfp));
- for (i = 0; i < npaths; i++) {
- if (goodfps[i]) {
- int n = strlen(fp[i]);
- newfp[j++] = n;
- strncpy(&newfp[j], fp[i], n);
- j += n;
- }
- }
-
- if (SetFontPath(serverClient, newnpaths, (unsigned char *)newfp)) {
- /* Note that this should never happen since all of the
- * FPEs were previously valid. */
- dmxLog(dmxError, "Cannot reset the default font path.\n");
- }
- } else if (dmxFontPath) {
- dmxLog(dmxError,
- "Please remove these font paths from the command line "
- "or\n");
- dmxLog(dmxError,
- "configuration file, or set the \"-ignorebadfontpaths\" "
- "option to\n");
- dmxLog(dmxError,
- "ignore them. For more information on these options, see "
- "the\n");
- dmxLog(dmxError,
- "Xdmx man page.\n");
- } else {
- dmxLog(dmxError,
- "Please specify the font paths that are available on all "
- "back-end\n");
- dmxLog(dmxError,
- "servers with the \"-fontpath\" option, or use the "
+ char **fp;
+ int npaths;
+ Bool *goodfps;
+
+ /* This could fail only when first starting the X server and
+ * loading the default font. If it fails here, then the default
+ * font path is invalid, no default font path will be set, the
+ * DMX server will fail to load the default font, and it will
+ * exit with an error unless we remove the offending font paths
+ * with the -ignorebadfontpaths command line option.
+ */
+
+ fp = dmxGetFontPath(&npaths);
+ if (!fp) {
+ dmxLog(dmxError, "No default font path set.\n");
+ dmxLog(dmxError,
+ "Please see the Xdmx man page for information on how to\n");
+ dmxLog(dmxError,
+ "initialize the DMX server's default font path.\n");
+ XFreeFontPath(oldFontPath);
+ return FALSE;
+ }
+
+ if (!dmxFontPath)
+ dmxLog(dmxWarning, "No default font path is set.\n");
+
+ goodfps = malloc(npaths * sizeof(*goodfps));
+
+ dmxLog(dmxError,
+ "The DMX server failed to set the following font paths on "
+ "screen #%d:\n", pScreen->myNum);
+
+ for (i = 0; i < npaths; i++)
+ if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
+ dmxLog(dmxError, " %s\n", fp[i]);
+
+ if (dmxIgnoreBadFontPaths) {
+ char *newfp;
+ int newnpaths = 0;
+ int len = 0;
+ int j = 0;
+
+ dmxLog(dmxError,
+ "These font paths will not be used because the "
+ "\"-ignorebadfontpaths\"\n");
+ dmxLog(dmxError, "option is set.\n");
+
+ for (i = 0; i < npaths; i++)
+ if (goodfps[i]) {
+ len += strlen(fp[i]) + 1;
+ newnpaths++;
+ }
+
+ if (!newnpaths) {
+ /* No valid font paths were found */
+ dmxLog(dmxError,
+ "After removing the font paths above, no valid font "
+ "paths were\n");
+ dmxLog(dmxError,
+ "available. Please check that the font paths set on "
+ "the command\n");
+ dmxLog(dmxError,
+ "line or in the configuration file via the "
+ "\"-fontpath\" option\n");
+ dmxLog(dmxError,
+ "are valid on all back-end servers. See the Xdmx man "
+ "page for\n");
+ dmxLog(dmxError, "more information on font paths.\n");
+ dmxFreeFontPath(fp);
+ XFreeFontPath(oldFontPath);
+ free(goodfps);
+ return FALSE;
+ }
+
+ newfp = malloc(len * sizeof(*newfp));
+ for (i = 0; i < npaths; i++) {
+ if (goodfps[i]) {
+ int n = strlen(fp[i]);
+
+ newfp[j++] = n;
+ strncpy(&newfp[j], fp[i], n);
+ j += n;
+ }
+ }
+
+ if (SetFontPath(serverClient, newnpaths, (unsigned char *) newfp)) {
+ /* Note that this should never happen since all of the
+ * FPEs were previously valid. */
+ dmxLog(dmxError, "Cannot reset the default font path.\n");
+ }
+ }
+ else if (dmxFontPath) {
+ dmxLog(dmxError,
+ "Please remove these font paths from the command line "
+ "or\n");
+ dmxLog(dmxError,
+ "configuration file, or set the \"-ignorebadfontpaths\" "
+ "option to\n");
+ dmxLog(dmxError,
+ "ignore them. For more information on these options, see "
+ "the\n");
+ dmxLog(dmxError, "Xdmx man page.\n");
+ }
+ else {
+ dmxLog(dmxError,
+ "Please specify the font paths that are available on all "
+ "back-end\n");
+ dmxLog(dmxError,
+ "servers with the \"-fontpath\" option, or use the "
"\"-ignorebadfontpaths\"\n");
dmxLog(dmxError,
"to ignore bad defaults. For more information on "
"these and other\n");
- dmxLog(dmxError,
- "font-path-related options, see the Xdmx man page.\n");
- }
-
- if (!dmxIgnoreBadFontPaths ||
- (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
- /* We still have errors so return with error */
- dmxFreeFontPath(fp);
- XFreeFontPath(oldFontPath);
- free(goodfps);
- return FALSE;
- }
+ dmxLog(dmxError,
+ "font-path-related options, see the Xdmx man page.\n");
+ }
+
+ if (!dmxIgnoreBadFontPaths ||
+ (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
+ /* We still have errors so return with error */
+ dmxFreeFontPath(fp);
+ XFreeFontPath(oldFontPath);
+ free(goodfps);
+ return FALSE;
+ }
}
/* Find requested font on back-end server */
@@ -400,73 +412,80 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
value_atom = 0L;
for (i = 0; i < pFont->info.nprops; i++) {
- if ((Atom)pFont->info.props[i].name == name_atom) {
- value_atom = pFont->info.props[i].value;
- break;
- }
+ if ((Atom) pFont->info.props[i].name == name_atom) {
+ value_atom = pFont->info.props[i].value;
+ break;
+ }
}
- if (!value_atom) return FALSE;
+ if (!value_atom)
+ return FALSE;
name = NameForAtom(value_atom);
- if (!name) return FALSE;
+ if (!name)
+ return FALSE;
- pFontPriv->font[pScreen->myNum] =
- XLoadQueryFont(dmxScreen->beDisplay, name);
+ pFontPriv->font[pScreen->myNum] =
+ XLoadQueryFont(dmxScreen->beDisplay, name);
/* Restore old font path */
XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
XFreeFontPath(oldFontPath);
dmxSync(dmxScreen, FALSE);
- if (!pFontPriv->font[pScreen->myNum]) return FALSE;
+ if (!pFontPriv->font[pScreen->myNum])
+ return FALSE;
return TRUE;
}
/** Realize the font, \a pFont, on the back-end server associated with
* \a pScreen. */
-Bool dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+Bool
+dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv;
if (!(pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- pFontPriv = malloc(sizeof(dmxFontPrivRec));
- if (!pFontPriv) return FALSE;
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ pFontPriv = malloc(sizeof(dmxFontPrivRec));
+ if (!pFontPriv)
+ return FALSE;
pFontPriv->font = NULL;
MAXSCREENSALLOC(pFontPriv->font);
if (!pFontPriv->font) {
free(pFontPriv);
return FALSE;
}
- pFontPriv->refcnt = 0;
+ pFontPriv->refcnt = 0;
}
- FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer)pFontPriv);
+ FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer) pFontPriv);
if (dmxScreen->beDisplay) {
- if (!dmxBELoadFont(pScreen, pFont))
- return FALSE;
+ if (!dmxBELoadFont(pScreen, pFont))
+ return FALSE;
- pFontPriv->refcnt++;
- } else {
- pFontPriv->font[pScreen->myNum] = NULL;
+ pFontPriv->refcnt++;
+ }
+ else {
+ pFontPriv->font[pScreen->myNum] = NULL;
}
return TRUE;
}
/** Free \a pFont on the back-end associated with \a pScreen. */
-Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
+Bool
+dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
if (pFontPriv && pFontPriv->font[pScreen->myNum]) {
- XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
- pFontPriv->font[pScreen->myNum] = NULL;
- return TRUE;
+ XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
+ pFontPriv->font[pScreen->myNum] = NULL;
+ return TRUE;
}
return FALSE;
@@ -474,77 +493,79 @@ Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
/** Unrealize the font, \a pFont, on the back-end server associated with
* \a pScreen. */
-Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+Bool
+dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv;
if ((pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
- /* In case the font failed to load properly */
- if (!pFontPriv->refcnt) {
+ /* In case the font failed to load properly */
+ if (!pFontPriv->refcnt) {
MAXSCREENSFREE(pFontPriv->font);
- free(pFontPriv);
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- } else if (pFontPriv->font[pScreen->myNum]) {
- if (dmxScreen->beDisplay)
- dmxBEFreeFont(pScreen, pFont);
-
- /* The code below is non-obvious, so here's an explanation...
- *
- * When creating the default GC, the server opens up the
- * default font once for each screen, which in turn calls
- * the RealizeFont function pointer once for each screen.
- * During this process both dix's font refcnt and DMX's font
- * refcnt are incremented once for each screen.
- *
- * Later, when shutting down the X server, dix shuts down
- * each screen in reverse order. During this shutdown
- * procedure, each screen's default GC is freed and then
- * that screen is closed by calling the CloseScreen function
- * pointer. screenInfo.numScreens is then decremented after
- * closing each screen. This procedure means that the dix's
- * font refcnt for the font used by the default GC's is
- * decremented once for each screen # greater than 0.
- * However, since dix's refcnt for the default font is not
- * yet 0 for each screen greater than 0, no call to the
- * UnrealizeFont function pointer is made for those screens.
- * Then, when screen 0 is being closed, dix's font refcnt
- * for the default GC's font is finally 0 and the font is
- * unrealized. However, since screenInfo.numScreens has
- * been decremented already down to 1, only one call to
- * UnrealizeFont is made (for screen 0). Thus, even though
- * RealizeFont was called once for each screen,
- * UnrealizeFont is only called for screen 0.
- *
- * This is a bug in dix.
- *
- * To avoid the memory leak of pFontPriv for each server
- * generation, we can also free pFontPriv if the refcnt is
- * not yet 0 but the # of screens is 1 -- i.e., the case
- * described in the dix bug above. This is only a temporary
- * workaround until the bug in dix is solved.
- *
- * The other problem is that the font structure allocated by
- * XLoadQueryFont() above is not freed for screens > 0.
- * This problem cannot be worked around here since the back-
- * end displays for screens > 0 have already been closed by
- * the time this code is called from dix.
- *
- * When the bug in dix described above is fixed, then we can
- * remove the "|| screenInfo.numScreens == 1" code below and
- * the memory leaks will be eliminated.
- */
- if (--pFontPriv->refcnt == 0
+ free(pFontPriv);
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ }
+ else if (pFontPriv->font[pScreen->myNum]) {
+ if (dmxScreen->beDisplay)
+ dmxBEFreeFont(pScreen, pFont);
+
+ /* The code below is non-obvious, so here's an explanation...
+ *
+ * When creating the default GC, the server opens up the
+ * default font once for each screen, which in turn calls
+ * the RealizeFont function pointer once for each screen.
+ * During this process both dix's font refcnt and DMX's font
+ * refcnt are incremented once for each screen.
+ *
+ * Later, when shutting down the X server, dix shuts down
+ * each screen in reverse order. During this shutdown
+ * procedure, each screen's default GC is freed and then
+ * that screen is closed by calling the CloseScreen function
+ * pointer. screenInfo.numScreens is then decremented after
+ * closing each screen. This procedure means that the dix's
+ * font refcnt for the font used by the default GC's is
+ * decremented once for each screen # greater than 0.
+ * However, since dix's refcnt for the default font is not
+ * yet 0 for each screen greater than 0, no call to the
+ * UnrealizeFont function pointer is made for those screens.
+ * Then, when screen 0 is being closed, dix's font refcnt
+ * for the default GC's font is finally 0 and the font is
+ * unrealized. However, since screenInfo.numScreens has
+ * been decremented already down to 1, only one call to
+ * UnrealizeFont is made (for screen 0). Thus, even though
+ * RealizeFont was called once for each screen,
+ * UnrealizeFont is only called for screen 0.
+ *
+ * This is a bug in dix.
+ *
+ * To avoid the memory leak of pFontPriv for each server
+ * generation, we can also free pFontPriv if the refcnt is
+ * not yet 0 but the # of screens is 1 -- i.e., the case
+ * described in the dix bug above. This is only a temporary
+ * workaround until the bug in dix is solved.
+ *
+ * The other problem is that the font structure allocated by
+ * XLoadQueryFont() above is not freed for screens > 0.
+ * This problem cannot be worked around here since the back-
+ * end displays for screens > 0 have already been closed by
+ * the time this code is called from dix.
+ *
+ * When the bug in dix described above is fixed, then we can
+ * remove the "|| screenInfo.numScreens == 1" code below and
+ * the memory leaks will be eliminated.
+ */
+ if (--pFontPriv->refcnt == 0
#if 1
- /* Remove this code when the dix bug is fixed */
- || screenInfo.numScreens == 1
+ /* Remove this code when the dix bug is fixed */
+ || screenInfo.numScreens == 1
#endif
- ) {
+ ) {
MAXSCREENSFREE(pFontPriv->font);
- free(pFontPriv);
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- }
- }
+ free(pFontPriv);
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ }
+ }
}
return TRUE;