Commit acd45283 authored by Ulrich Sibiller's avatar Ulrich Sibiller Committed by Mike Gabriel

Font.c: cleanup

reformat, whitespace, code simplification, FIXMEs
parent 92589f41
...@@ -113,15 +113,15 @@ static void printFontCacheDump(char*); ...@@ -113,15 +113,15 @@ static void printFontCacheDump(char*);
typedef struct _nxagentFontRec typedef struct _nxagentFontRec
{ {
char *name; char *name;
int status; int status;
} nxagentFontRec, *nxagentFontRecPtr; } nxagentFontRec, *nxagentFontRecPtr;
typedef struct _nxagentFontList typedef struct _nxagentFontList
{ {
nxagentFontRecPtr *list; nxagentFontRecPtr *list;
int length; int length;
int listSize; int listSize;
} nxagentFontList, *nxagentFontListPtr; } nxagentFontList, *nxagentFontListPtr;
nxagentFontList nxagentRemoteFontList = {NULL, (int)0, (int)0}; nxagentFontList nxagentRemoteFontList = {NULL, (int)0, (int)0};
...@@ -130,16 +130,16 @@ int nxagentFontPrivateIndex; ...@@ -130,16 +130,16 @@ int nxagentFontPrivateIndex;
typedef struct _nxCacheFontEntry typedef struct _nxCacheFontEntry
{ {
Atom atom; Atom atom;
XFontStruct *font_struct; XFontStruct *font_struct;
char *name; char *name;
} nxCacheFontEntryRec, *nxCacheFontEntryRecPtr; } nxCacheFontEntryRec, *nxCacheFontEntryRecPtr;
static struct _nxagentFontCache static struct _nxagentFontCache
{ {
nxCacheFontEntryRecPtr *entry; nxCacheFontEntryRecPtr *entry;
int index; int index;
int size; int size;
} nxagentFontCache = { NULL, (int) 0, (int) 0 }; } nxagentFontCache = { NULL, (int) 0, (int) 0 };
#define CACHE_ENTRY_PTR (nxagentFontCache.entry) #define CACHE_ENTRY_PTR (nxagentFontCache.entry)
...@@ -152,10 +152,10 @@ static struct _nxagentFontCache ...@@ -152,10 +152,10 @@ static struct _nxagentFontCache
static struct _nxagentFailedToReconnectFonts static struct _nxagentFailedToReconnectFonts
{ {
FontPtr *font; FontPtr *font;
XID *id; XID *id;
int size; int size;
int index; int index;
} nxagentFailedToReconnectFonts = {NULL, NULL, 0, 0}; } nxagentFailedToReconnectFonts = {NULL, NULL, 0, 0};
/* /*
...@@ -164,519 +164,521 @@ static struct _nxagentFailedToReconnectFonts ...@@ -164,519 +164,521 @@ static struct _nxagentFailedToReconnectFonts
void nxagentFreeFontCache(void) void nxagentFreeFontCache(void)
{ {
#ifdef NXAGENT_FONTCACHE_DEBUG #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: Freeing nxagent font cache\n"); fprintf(stderr, "Font: Freeing nxagent font cache\n");
#endif #endif
if (CACHE_INDEX == 0)
return;
#ifdef NXAGENT_FONTCACHE_DEBUG if (CACHE_INDEX == 0)
fprintf(stderr, "Font: Freeing nxagent font cache, there are [%d] entries.\n", CACHE_INDEX); return;
#endif
for (int i = 0; i < CACHE_INDEX; i++)
{
#ifdef NXAGENT_FONTCACHE_DEBUG #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: Freeing nxagent font cache entry [%d] entry pointer is [%p], name [%s]\n", fprintf(stderr, "Font: Freeing nxagent font cache, there are [%d] entries.\n", CACHE_INDEX);
i, CACHE_ENTRY(i), CACHE_NAME(i));
#endif #endif
if (CACHE_FSTRUCT(i)) for (int i = 0; i < CACHE_INDEX; i++)
{ {
nxagentFreeFont(CACHE_FSTRUCT(i)); #ifdef NXAGENT_FONTCACHE_DEBUG
} fprintf(stderr, "Font: Freeing nxagent font cache entry [%d] entry pointer is [%p], name [%s]\n",
i, CACHE_ENTRY(i), CACHE_NAME(i));
#endif
SAFE_free(CACHE_NAME(i)); if (CACHE_FSTRUCT(i))
SAFE_free(CACHE_ENTRY(i)); {
} nxagentFreeFont(CACHE_FSTRUCT(i));
}
SAFE_free(CACHE_ENTRY_PTR); SAFE_free(CACHE_NAME(i));
CACHE_ENTRY_PTR = NULL; SAFE_free(CACHE_ENTRY(i));
CACHE_INDEX = 0; }
CACHE_SIZE = 0;
#ifdef NXAGENT_FONTCACHE_DEBUG SAFE_free(CACHE_ENTRY_PTR);
fprintf(stderr, "Font: nxagent font cache fully freed\n"); CACHE_ENTRY_PTR = NULL;
#endif CACHE_INDEX = 0;
CACHE_SIZE = 0;
return; #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagent font cache fully freed\n");
#endif
return;
} }
void nxagentListRemoteFonts(const char *searchPattern, const int maxNames) void nxagentListRemoteFonts(const char *searchPattern, const int maxNames)
{ {
char **xList; if (NXDisplayError(nxagentDisplay) == 1)
int xLen = 0; {
return;
}
const char *patterns[] = {"*", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"}; /*
int patternsQt = 2; * Avoid querying again the remote fonts.
*/
if (NXDisplayError(nxagentDisplay) == 1) if (nxagentRemoteFontList.length > 0)
{ {
return; return;
} }
/* /*
* Avoid querying again the remote fonts. * We can't retrieve the full remote font list with a single query,
*/ * because the number of dashes in the pattern acts as a rule to
* select how to search for the font names, so the pattern '*' is
* useful to retrieve the font aliases, while the other one will
* select the 'real' fonts.
*/
if (nxagentRemoteFontList.length > 0) const char *patterns[] = {"*", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"};
{ const int numPatterns = 2;
return;
}
/* for (int p = 0; p < numPatterns; p++)
* We can't retrieve the full remote font list with a single query, {
* because the number of dashes in the pattern acts as a rule to int xLen = 0;
* select how to search for the font names, so the pattern '*' is char **xList = XListFonts(nxagentDisplay, patterns[p], maxNames, &xLen);
* useful to retrieve the font aliases, while the other one will
* select the 'real' fonts.
*/
for (int p = 0; p < patternsQt; p++) #ifdef NXAGENT_FONTMATCH_DEBUG
{ fprintf(stderr, "nxagentListRemoteFonts: NXagent remote list [%s] has %d elements.\n", patterns[p], xLen);
xList = XListFonts(nxagentDisplay, patterns[p], maxNames, &xLen); #endif
#ifdef NXAGENT_FONTMATCH_DEBUG /*
fprintf(stderr, "nxagentListRemoteFonts: NXagent remote list [%s] has %d elements.\n", patterns[p], xLen); * Add the ListFont request pattern to the list with the last
#endif * requested maxnames.
*/
/* nxagentListRemoteAddName(searchPattern, maxNames);
* Add the ListFont request pattern to the list with the last
* requested maxnames.
*/
nxagentListRemoteAddName(searchPattern, maxNames); for (int i = 0; i < xLen; i++)
{
nxagentListRemoteAddName(xList[i], 1);
}
for (int i = 0; i < xLen; i++) XFreeFontNames(xList);
{
nxagentListRemoteAddName(xList[i], 1);
} }
XFreeFontNames(xList); #ifdef NXAGENT_FONTMATCH_DEBUG
}
#ifdef NXAGENT_FONTMATCH_DEBUG
fprintf(stderr, "nxagentListRemoteFonts: Printing remote font list.\n"); fprintf(stderr, "nxagentListRemoteFonts: Printing remote font list.\n");
for (int i = 0; i < nxagentRemoteFontList.length; i++) for (int i = 0; i < nxagentRemoteFontList.length; i++)
{ {
fprintf(stderr, "Font# %d, \"%s\"\n", i, nxagentRemoteFontList.list[i]->name); fprintf(stderr, "Font# %d, \"%s\"\n", i, nxagentRemoteFontList.list[i]->name);
} }
fprintf(stderr, "nxagentListRemoteFonts: End of list\n"); fprintf(stderr, "nxagentListRemoteFonts: End of list\n");
#endif #endif
} }
void nxagentListRemoteAddName(const char *name, int status) void nxagentListRemoteAddName(const char *name, int status)
{ {
int pos; int pos;
if (nxagentFontFind(name, &pos)) if (nxagentFontFind(name, &pos))
{ {
if (nxagentRemoteFontList.list[pos]->status < status) if (nxagentRemoteFontList.list[pos]->status < status)
{ {
nxagentRemoteFontList.list[pos]->status = status; nxagentRemoteFontList.list[pos]->status = status;
#ifdef NXAGENT_FONTMATCH_DEBUG
fprintf(stderr, "Font: Font# %d, [%s] change status to %s\n",
pos, nxagentRemoteFontList.list[pos]->name,nxagentRemoteFontList.list[pos]->status?"OK":"deleted");
#endif
}
return;
}
if (nxagentRemoteFontList.length == nxagentRemoteFontList.listSize) #ifdef NXAGENT_FONTMATCH_DEBUG
{ fprintf(stderr, "Font: Font# %d, [%s] change status to %s\n",
nxagentRemoteFontList.list = realloc(nxagentRemoteFontList.list, sizeof(nxagentFontRecPtr) pos, nxagentRemoteFontList.list[pos]->name,
* (nxagentRemoteFontList.listSize + 1000)); nxagentRemoteFontList.list[pos]->status ? "OK" : "deleted");
#endif
}
return;
}
if (nxagentRemoteFontList.list == NULL) if (nxagentRemoteFontList.length == nxagentRemoteFontList.listSize)
{ {
FatalError("Font: remote list memory re-allocation failed!.\n"); /* FIXME: if realloc fails the pointer is lost! */
} nxagentRemoteFontList.list = realloc(nxagentRemoteFontList.list, sizeof(nxagentFontRecPtr)
* (nxagentRemoteFontList.listSize + 1000));
nxagentRemoteFontList.listSize += 1000; if (nxagentRemoteFontList.list == NULL)
} {
FatalError("Font: remote list memory re-allocation failed!.\n");
}
if (pos < nxagentRemoteFontList.length) nxagentRemoteFontList.listSize += 1000;
{ }
#ifdef NXAGENT_FONTMATCH_DEBUG
fprintf(stderr, "Font: Going to move list from %p to %p len = %d!.\n",
&nxagentRemoteFontList.list[pos], &nxagentRemoteFontList.list[pos+1],
(nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
#endif
memmove(&nxagentRemoteFontList.list[pos+1], if (pos < nxagentRemoteFontList.length)
&nxagentRemoteFontList.list[pos], {
(nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr)); #ifdef NXAGENT_FONTMATCH_DEBUG
} fprintf(stderr, "Font: Going to move list from %p to %p len = %d!.\n",
&nxagentRemoteFontList.list[pos], &nxagentRemoteFontList.list[pos+1],
(nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
#endif
if ((nxagentRemoteFontList.list[pos] = malloc(sizeof(nxagentFontRec)))) memmove(&nxagentRemoteFontList.list[pos+1],
{ &nxagentRemoteFontList.list[pos],
nxagentRemoteFontList.list[pos]->name = strdup(name); (nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
if (nxagentRemoteFontList.list[pos]->name == NULL) }
if ((nxagentRemoteFontList.list[pos] = malloc(sizeof(nxagentFontRec))))
{
nxagentRemoteFontList.list[pos]->name = strdup(name);
if (nxagentRemoteFontList.list[pos]->name == NULL)
{
fprintf(stderr, "Font: remote list name memory allocation failed!.\n");
SAFE_free(nxagentRemoteFontList.list[pos]);
return;
}
}
else
{ {
fprintf(stderr, "Font: remote list name memory allocation failed!.\n"); fprintf(stderr, "Font: remote list record memory allocation failed!.\n");
SAFE_free(nxagentRemoteFontList.list[pos]); return;
return;
} }
} nxagentRemoteFontList.list[pos]->status = status;
else nxagentRemoteFontList.length++;
{
fprintf(stderr, "Font: remote list record memory allocation failed!.\n"); #ifdef NXAGENT_FONTMATCH_DEBUG
return; fprintf(stderr, "Font: remote font list added [%s] in position [%d] as %s !.\n",
} name, pos, status ? "OK" : "deleted");
nxagentRemoteFontList.list[pos]->status = status; fprintf(stderr, "Font: remote font list total len is [%d] Size is [%d] !.\n",
nxagentRemoteFontList.length++; nxagentRemoteFontList.length, nxagentRemoteFontList.listSize);
#endif
#ifdef NXAGENT_FONTMATCH_DEBUG
fprintf(stderr, "Font: remote font list added [%s] in position [%d] as %s !.\n",
name, pos, status ? "OK" : "deleted");
fprintf(stderr, "Font: remote font list total len is [%d] Size is [%d] !.\n",
nxagentRemoteFontList.length, nxagentRemoteFontList.listSize);
#endif
} }
static void nxagentFreeRemoteFontList(nxagentFontList *listRec) static void nxagentFreeRemoteFontList(nxagentFontList *listRec)
{ {
for (int l = 0; l < listRec -> length; l++) for (int l = 0; l < listRec -> length; l++)
{
if (listRec -> list[l])
{ {
SAFE_free(listRec -> list[l] -> name); if (listRec -> list[l])
SAFE_free(listRec -> list[l]); {
SAFE_free(listRec -> list[l] -> name);
SAFE_free(listRec -> list[l]);
}
} }
}
listRec -> length = listRec -> listSize = 0; listRec -> length = listRec -> listSize = 0;
SAFE_free(listRec -> list); SAFE_free(listRec -> list);
return; return;
} }
Bool nxagentFontFind(const char *name, int *pos) Bool nxagentFontFind(const char *name, int *pos)
{ {
if (!nxagentRemoteFontList.length) if (!nxagentRemoteFontList.length)
{ {
*pos=0; *pos=0;
return False; return False;
} }
int low = 0;
int high = nxagentRemoteFontList.length - 1; int low = 0;
int iter = 0; int high = nxagentRemoteFontList.length - 1;
int res = 1; int iter = 0;
int lpos = nxagentRemoteFontList.length; int res = 1;
while (low <= high) int lpos = nxagentRemoteFontList.length;
{ while (low <= high)
*pos = (high + low)/2; {
iter ++; *pos = (high + low)/2;
res = strcasecmp(nxagentRemoteFontList.list[*pos]->name,name); iter ++;
if (res > 0) res = strcasecmp(nxagentRemoteFontList.list[*pos]->name,name);
{ if (res > 0)
high = *pos - 1; {
lpos = *pos; high = *pos - 1;
continue; lpos = *pos;
} continue;
else if (res < 0) }
{ else if (res < 0)
low = *pos + 1; {
lpos = low; low = *pos + 1;
continue; lpos = low;
} continue;
break; }
} break;
*pos = (res == 0)?*pos:lpos; }
*pos = (res == 0) ? *pos : lpos;
#ifdef NXAGENT_FONTMATCH_DEBUG
if (res == 0) #ifdef NXAGENT_FONTMATCH_DEBUG
fprintf(stderr, "Font: font found in %d iterations in pos = %d\n", iter, *pos); if (res == 0)
else fprintf(stderr, "Font: font found in %d iterations in pos = %d\n", iter, *pos);
fprintf(stderr, "Font: not font found in %d iterations insertion pos is = %d\n", iter, *pos); else
#endif fprintf(stderr, "Font: not font found in %d iterations insertion pos is = %d\n", iter, *pos);
#endif
return (res == 0);
return (res == 0);
} }
Bool nxagentFontLookUp(const char *name) Bool nxagentFontLookUp(const char *name)
{ {
int i; int i;
if (name != NULL && strlen(name) == 0) if (name && strlen(name) == 0)
{ {
return 0; return 0;
} }
int result = nxagentFontFind(name, &i); int result = nxagentFontFind(name, &i);
char *scalable = NULL; char *scalable = NULL;
/* /*
* Let's try with the scalable font description. * Let's try with the scalable font description.
*/ */
if (result == 0) if (result == 0)
{
if ((scalable = nxagentMakeScalableFontName(name, 0)) != NULL)
{ {
result = nxagentFontFind(scalable, &i); if ((scalable = nxagentMakeScalableFontName(name, 0)) != NULL)
{
result = nxagentFontFind(scalable, &i);
SAFE_free(scalable); SAFE_free(scalable);
}
} }
}
/* /*
* Let's try again after replacing zero to xdpi and ydpi in the pattern. * Let's try again after replacing zero to xdpi and ydpi in the pattern.
*/ */
if (result == 0) if (result == 0)
{
if ((scalable = nxagentMakeScalableFontName(name, 1)) != NULL)
{ {
result = nxagentFontFind(scalable, &i); if ((scalable = nxagentMakeScalableFontName(name, 1)) != NULL)
{
result = nxagentFontFind(scalable, &i);
SAFE_free(scalable); SAFE_free(scalable);
}
} }
}
if (result == 0) if (result == 0)
{ {
return 0; return 0;
} }
else else
{ {
return (nxagentRemoteFontList.list[i]->status > 0); return (nxagentRemoteFontList.list[i]->status > 0);
} }
} }
Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont) Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
{ {
void * priv;
Atom name_atom, value_atom;
int nprops;
FontPropPtr props;
int i;
const char *name;
char *origName = (char*) pScreen;
#ifdef HAS_XFONT2 #ifdef HAS_XFONT2
xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL); xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL);
#else #else
FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL); FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
#endif /* HAS_XFONT2 */ #endif /* HAS_XFONT2 */
name_atom = MakeAtom("FONT", 4, True); Atom name_atom = MakeAtom("FONT", 4, True);
value_atom = 0L; Atom value_atom = 0L;
nprops = pFont->info.nprops; int nprops = pFont->info.nprops;
props = pFont->info.props; FontPropPtr props = pFont->info.props;
for (i = 0; i < nprops; i++) for (int i = 0; i < nprops; i++)
if ((Atom)props[i].name == name_atom) { {
value_atom = props[i].value; if ((Atom)props[i].name == name_atom)
break; {
value_atom = props[i].value;
break;
}
} }
if (!value_atom) return False; if (!value_atom)
return False;
name = NameForAtom(value_atom); const char *name = NameForAtom(value_atom);
#ifdef NXAGENT_FONTCACHE_DEBUG #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentRealizeFont, realizing font: %s\n", validateString(name)); fprintf(stderr, "Font: nxagentRealizeFont, realizing font: %s\n", validateString(name));
fprintf(stderr, " atom: %ld\n", value_atom); fprintf(stderr, " atom: %ld\n", value_atom);
fprintf(stderr, "Font: Cache dump:\n"); fprintf(stderr, "Font: Cache dump:\n");
for (i = 0; i < CACHE_INDEX; i++) for (int i = 0; i < CACHE_INDEX; i++)
{ {
fprintf(stderr, "nxagentFontCache.entry[%d]->name: %s font_struct at %p\n", fprintf(stderr, "nxagentFontCache.entry[%d]->name: %s font_struct at %p\n",
i, CACHE_NAME(i), CACHE_FSTRUCT(i)); i, CACHE_NAME(i), CACHE_FSTRUCT(i));
} }
#endif #endif
if (!name) return False; if (!name)
return False;
if ((strcasecmp(origName, name) != 0) && !strchr(origName,'*')) char *origName = (char*) pScreen;
{ if ((strcasecmp(origName, name) != 0) && !strchr(origName,'*'))
#ifdef NXAGENT_FONTMATCH_DEBUG {
fprintf(stderr, "Font: Changing font name to realize from [%s] to [%s]\n", #ifdef NXAGENT_FONTMATCH_DEBUG
validateString(name), origName); fprintf(stderr, "Font: Changing font name to realize from [%s] to [%s]\n",
#endif validateString(name), origName);
#endif
name = origName; name = origName;
} }
priv = (void *)malloc(sizeof(nxagentPrivFont)); void *priv = (void *)malloc(sizeof(nxagentPrivFont));
#ifdef HAS_XFONT2 #ifdef HAS_XFONT2
xfont2_font_set_private(pFont, nxagentFontPrivateIndex, priv); xfont2_font_set_private(pFont, nxagentFontPrivateIndex, priv);
#else #else
FontSetPrivate(pFont, nxagentFontPrivateIndex, priv); FontSetPrivate(pFont, nxagentFontPrivateIndex, priv);
#endif /* HAS_XFONT2 */ #endif /* HAS_XFONT2 */
nxagentFontPriv(pFont) -> mirrorID = 0; nxagentFontPriv(pFont) -> mirrorID = 0;
for (i = 0; i < nxagentFontCache.index; i++) int fci;
{ for (fci = 0; fci < nxagentFontCache.index; fci++)
/* if (value_atom == CACHE_ATOM(i))*/ {
if (strcasecmp(CACHE_NAME(i), name) == 0) /* if (value_atom == CACHE_ATOM(i))*/
{ if (strcasecmp(CACHE_NAME(fci), name) == 0)
{
#ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentFontCache hit [%s] = [%s]!\n", CACHE_NAME(fci), validateString(name));
#endif
break;
}
}
if (fci < CACHE_INDEX)
{
nxagentFontPriv(pFont)->font_struct = CACHE_FSTRUCT(fci);
strcpy(nxagentFontPriv(pFont)->fontName, name);
}
else
{
#ifdef NXAGENT_FONTCACHE_DEBUG #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentFontCache hit [%s] = [%s]!\n", CACHE_NAME(i), validateString(name)); fprintf(stderr, "Font: nxagentFontCache fail.\n");
#endif #endif
break; if (CACHE_INDEX == CACHE_SIZE)
} {
} /* FIXME: if realloc fails the pointer is lost */
CACHE_ENTRY_PTR = realloc(CACHE_ENTRY_PTR, sizeof(nxCacheFontEntryRecPtr) * (CACHE_SIZE + 100));
if (i < CACHE_INDEX) if (CACHE_ENTRY_PTR == NULL)
{ {
nxagentFontPriv(pFont)->font_struct = CACHE_FSTRUCT(i); FatalError("Font: Cache list memory re-allocation failed.\n");
strcpy(nxagentFontPriv(pFont)->fontName, name); }
}
else
{
#ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentFontCache fail.\n");
#endif
if (CACHE_INDEX == CACHE_SIZE) CACHE_SIZE += 100;
{ }
CACHE_ENTRY_PTR = realloc(CACHE_ENTRY_PTR, sizeof(nxCacheFontEntryRecPtr) * (CACHE_SIZE + 100));
if (CACHE_ENTRY_PTR == NULL) CACHE_ENTRY(CACHE_INDEX) = malloc(sizeof(nxCacheFontEntryRec));
if (CACHE_ENTRY(CACHE_INDEX) == NULL)
{ {
FatalError("Font: Cache list memory re-allocation failed.\n"); return False;
} }
CACHE_SIZE += 100; CACHE_NAME(CACHE_INDEX) = malloc(strlen(name) + 1);
}
CACHE_ENTRY(CACHE_INDEX) = malloc(sizeof(nxCacheFontEntryRec)); if (CACHE_NAME(CACHE_INDEX) == NULL)
{
return False;
}
if (CACHE_ENTRY(CACHE_INDEX) == NULL) #ifdef NXAGENT_FONTMATCH_DEBUG
{ fprintf(stderr, "Font: Going to realize font [%s],[%s] on real X server.\n", validateString(name), origName);
return False; #endif
}
CACHE_NAME(CACHE_INDEX) = malloc(strlen(name) + 1); if (nxagentRemoteFontList.length == 0 && (NXDisplayError(nxagentDisplay) == 0))
{
nxagentListRemoteFonts("*", nxagentMaxFontNames);
}
if (CACHE_NAME(CACHE_INDEX) == NULL) nxagentFontPriv(pFont)->font_struct = nxagentLoadQueryFont(nxagentDisplay, (char *)name, pFont);
{ strcpy(nxagentFontPriv(pFont)->fontName, name);
return False; if (nxagentFontPriv(pFont)->font_struct != NULL)
} {
CACHE_ATOM(fci) = value_atom;
#ifdef NXAGENT_FONTMATCH_DEBUG strcpy(CACHE_NAME(fci), name);
fprintf(stderr, "Font: Going to realize font [%s],[%s] on real X server.\n", validateString(name), origName); CACHE_FSTRUCT(fci) = nxagentFontPriv(pFont)->font_struct;
#endif CACHE_INDEX++;
if (nxagentRemoteFontList.length == 0 && (NXDisplayError(nxagentDisplay) == 0)) nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
{ AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
nxagentListRemoteFonts("*", nxagentMaxFontNames);
} #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentFontCache adds font [%s] in pos. [%d].\n",
nxagentFontPriv(pFont)->font_struct = nxagentLoadQueryFont(nxagentDisplay, (char *)name, pFont); validateString(name), CACHE_INDEX - 1);
strcpy(nxagentFontPriv(pFont)->fontName, name); #endif
if (nxagentFontPriv(pFont)->font_struct != NULL) }
{ }
CACHE_ATOM(i) = value_atom;
strcpy(CACHE_NAME(i), name);
CACHE_FSTRUCT(i) = nxagentFontPriv(pFont)->font_struct;
CACHE_INDEX++;
nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
#ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "Font: nxagentFontCache adds font [%s] in pos. [%d].\n",
validateString(name), CACHE_INDEX - 1);
#endif
}
}
#ifdef NXAGENT_FONTMATCH_DEBUG #ifdef NXAGENT_FONTMATCH_DEBUG
if (nxagentFontPriv(pFont)->font_struct == NULL) if (nxagentFontPriv(pFont)->font_struct == NULL)
{
if (nxagentFontLookUp(name) == False)
{ {
fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s, not in our remote list\n", if (nxagentFontLookUp(name) == False)
validateString(name)); {
fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s, not in our remote list\n",
validateString(name));
}
else
{
fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s but the font is in our remote list\n",
validateString(name));
}
} }
else else
{ {
fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s but the font is in our remote list\n", fprintf(stderr, "Font: nxagentRealizeFont OK realizing font Font=%s\n",
validateString(name)); validateString(name));
} }
}
else
fprintf(stderr, "Font: nxagentRealizeFont OK realizing font Font=%s\n",
validateString(name));
#endif #endif
return (nxagentFontPriv(pFont)->font_struct != NULL); return (nxagentFontPriv(pFont)->font_struct != NULL);
} }
Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont) Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
{ {
if (nxagentFontPriv(pFont)) if (nxagentFontPriv(pFont))
{
if (NXDisplayError(nxagentDisplay) == 0)
{ {
if (nxagentFontStruct(pFont)) if (NXDisplayError(nxagentDisplay) == 0)
{ {
int i; if (nxagentFontStruct(pFont))
{
for (i = 0; i < CACHE_INDEX; i++) int fci;
{
if (CACHE_FSTRUCT(i) == nxagentFontStruct(pFont)) for (fci = 0; fci < CACHE_INDEX; fci++)
{ {
#ifdef NXAGENT_FONTCACHE_DEBUG if (CACHE_FSTRUCT(fci) == nxagentFontStruct(pFont))
fprintf(stderr, "nxagentUnrealizeFont: Not freeing the font in cache.\n"); {
#endif #ifdef NXAGENT_FONTCACHE_DEBUG
fprintf(stderr, "nxagentUnrealizeFont: Not freeing the font in cache.\n");
break; #endif
}
} break;
}
if (i == CACHE_INDEX) }
{
/* if (fci == CACHE_INDEX)
* This font is not in the cache. {
*/ /*
* This font is not in the cache.
#ifdef NXAGENT_FONTCACHE_DEBUG */
fprintf(stderr, "nxagentUnrealizeFont: Freeing font not found in cache '%d'\n",
CACHE_ATOM(i)); #ifdef NXAGENT_FONTCACHE_DEBUG
#endif fprintf(stderr, "nxagentUnrealizeFont: Freeing font not found in cache '%d'\n",
CACHE_ATOM(fci));
XFreeFont(nxagentDisplay, nxagentFontStruct(pFont)); #endif
}
} XFreeFont(nxagentDisplay, nxagentFontStruct(pFont));
} }
}
}
if (nxagentFontPriv(pFont) -> mirrorID) if (nxagentFontPriv(pFont) -> mirrorID)
FreeResource(nxagentFontPriv(pFont) -> mirrorID, RT_NONE); FreeResource(nxagentFontPriv(pFont) -> mirrorID, RT_NONE);
free(nxagentFontPriv(pFont)); free(nxagentFontPriv(pFont));
#ifdef HAS_XFONT2 #ifdef HAS_XFONT2
xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL); xfont2_font_set_private(pFont, nxagentFontPrivateIndex, NULL);
#else #else
FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL); FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
#endif /* HAS_XFONT2 */ #endif /* HAS_XFONT2 */
} }
return True; return True;
} }
int nxagentDestroyNewFontResourceType(void * p, XID id) int nxagentDestroyNewFontResourceType(void * p, XID id)
{ {
#ifdef TEST #ifdef TEST
fprintf(stderr, "%s: Destroying mirror id [%ld] for font at [%p].\n", __func__, fprintf(stderr, "%s: Destroying mirror id [%ld] for font at [%p].\n", __func__,
nxagentFontPriv((FontPtr) p) -> mirrorID, (void *) p); nxagentFontPriv((FontPtr) p) -> mirrorID, (void *) p);
#endif #endif
/* /*
FIXME: It happens that this resource had been already destroyed. We FIXME: It happens that this resource had been already destroyed. We
...@@ -684,12 +686,12 @@ FIXME: It happens that this resource had been already destroyed. We ...@@ -684,12 +686,12 @@ FIXME: It happens that this resource had been already destroyed. We
client and another client. We had a crash when freeing server client and another client. We had a crash when freeing server
client resources. client resources.
*/ */
if (nxagentFontPriv((FontPtr) p) != NULL) if (nxagentFontPriv((FontPtr) p) != NULL)
{ {
nxagentFontPriv((FontPtr) p) -> mirrorID = None; nxagentFontPriv((FontPtr) p) -> mirrorID = None;
} }
return 1; return 1;
} }
static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont) static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont)
...@@ -722,7 +724,7 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP ...@@ -722,7 +724,7 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
5, /* Set-width */ 5, /* Set-width */
8, /* Point size */ 8, /* Point size */
10 /* DPI_y */ 10 /* DPI_y */
}; };
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentLoadBestQueryFont: Searching font '%s' .\n", fontName); fprintf(stderr, "nxagentLoadBestQueryFont: Searching font '%s' .\n", fontName);
...@@ -734,71 +736,69 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP ...@@ -734,71 +736,69 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
if (numFontFields <= FIELDS) if (numFontFields <= FIELDS)
{ {
#ifdef WARNING #ifdef WARNING
if (nxagentVerbose == 1) if (nxagentVerbose == 1)
{ {
fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Font name in non standard format. \n"); fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Font name in non standard format.\n");
} }
#endif #endif
} }
else else
{ {
for (int i = 1 ; i < nxagentRemoteFontList.length ; i++) for (int i = 1 ; i < nxagentRemoteFontList.length ; i++)
{
numSearchFields = nxagentSplitString(nxagentRemoteFontList.list[i]->name, searchFields, FIELDS+1, "-");
/* The following code attempts to find an accurate approximation
* of the missing font. The current candidate and the missing font are
* compared on the 14 fields of the X Logical Font Description Convention.
* The selection is performed by the analysis of the matching fields,
* shifting left the value of the Weight variable on the right matches
* and shifting right the value of the Weight on the wrong ones;
* due a probability of overmuch right shifting, the starting weight is set
* to a high value. At the end of matching the selected font is the one
* with the bigger final Weight. The shift operation has been used instead
* of other operation for a performance issue.
* In some check the shift is performed by more than one position, because
* of the relevance of the field; for example a correct slant or a matching
* charset is more relevant than the size.
*/
if (numSearchFields > FIELDS)
{ {
numSearchFields = nxagentSplitString(nxagentRemoteFontList.list[i]->name, searchFields, FIELDS+1, "-");
tempWeight = 0;
for (int j = 0; j < FIELDS; j++) /* The following code attempts to find an accurate approximation
{ * of the missing font. The current candidate and the missing font are
if (strcasecmp(searchFields[fieldOrder[j]], fontNameFields[fieldOrder[j]]) == 0 || * compared on the 14 fields of the X Logical Font Description Convention.
strcmp(searchFields[fieldOrder[j]], "") == 0 || * The selection is performed by the analysis of the matching fields,
strcmp(fontNameFields[fieldOrder[j]], "") != 0 || * shifting left the value of the Weight variable on the right matches
strcmp(searchFields[fieldOrder[j]], "*") == 0 || * and shifting right the value of the Weight on the wrong ones;
strcmp(fontNameFields[fieldOrder[j]], "*") == 0) * due a probability of overmuch right shifting, the starting weight is set
* to a high value. At the end of matching the selected font is the one
* with the bigger final Weight. The shift operation has been used instead
* of other operation for a performance issue.
* In some check the shift is performed by more than one position, because
* of the relevance of the field; for example a correct slant or a matching
* charset is more relevant than the size.
*/
if (numSearchFields > FIELDS)
{ {
tempWeight ++; tempWeight = 0;
}
for (int j = 0; j < FIELDS; j++)
tempWeight <<= 1; {
} if (strcasecmp(searchFields[fieldOrder[j]], fontNameFields[fieldOrder[j]]) == 0 ||
strcmp(searchFields[fieldOrder[j]], "") == 0 ||
strcmp(fontNameFields[fieldOrder[j]], "") != 0 ||
strcmp(searchFields[fieldOrder[j]], "*") == 0 ||
strcmp(fontNameFields[fieldOrder[j]], "*") == 0)
{
tempWeight ++;
}
tempWeight <<= 1;
}
} }
if (tempWeight > weight) if (tempWeight > weight)
{ {
/* Found more accurate font */ /* Found more accurate font */
weight = tempWeight; weight = tempWeight;
snprintf(substFontBuf, sizeof(substFontBuf), "%s", nxagentRemoteFontList.list[i]->name); snprintf(substFontBuf, sizeof(substFontBuf), "%s", nxagentRemoteFontList.list[i]->name);
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentLoadBestQueryFont: Weight '%d' of more accurate font '%s' .\n", weight, substFontBuf); fprintf(stderr, "nxagentLoadBestQueryFont: Weight '%d' of more accurate font '%s' .\n", weight, substFontBuf);
#endif #endif
} }
for (int j = 0; j < numSearchFields; j++) for (int j = 0; j < numSearchFields; j++)
{ {
SAFE_free(searchFields[j]); SAFE_free(searchFields[j]);
} }
} }
} }
...@@ -806,8 +806,8 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP ...@@ -806,8 +806,8 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
#ifdef WARNING #ifdef WARNING
if (nxagentVerbose == 1) if (nxagentVerbose == 1)
{ {
fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Failed to load font '%s'. Replacing with '%s'.\n", fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Failed to load font '%s'. Replacing with '%s'.\n",
fontName, substFontBuf); fontName, substFontBuf);
} }
#endif #endif
...@@ -815,7 +815,7 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP ...@@ -815,7 +815,7 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
for (int j = 0; j < numFontFields; j++) for (int j = 0; j < numFontFields; j++)
{ {
SAFE_free(fontNameFields[j]); SAFE_free(fontNameFields[j]);
} }
return fontStruct; return fontStruct;
...@@ -837,16 +837,16 @@ static void nxagentFontDisconnect(FontPtr pFont, XID param1, void * param2) ...@@ -837,16 +837,16 @@ static void nxagentFontDisconnect(FontPtr pFont, XID param1, void * param2)
for (int i = 0; i < CACHE_INDEX; i++) for (int i = 0; i < CACHE_INDEX; i++)
{ {
if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0) if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFontDisconnect: font %s found in cache at position %d\n", fprintf(stderr, "nxagentFontDisconnect: font %s found in cache at position %d\n",
privFont -> fontName, i); privFont -> fontName, i);
#endif #endif
privFont -> font_struct = NULL; privFont -> font_struct = NULL;
return; return;
} }
} }
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
...@@ -856,888 +856,883 @@ static void nxagentFontDisconnect(FontPtr pFont, XID param1, void * param2) ...@@ -856,888 +856,883 @@ static void nxagentFontDisconnect(FontPtr pFont, XID param1, void * param2)
if (privFont -> font_struct) if (privFont -> font_struct)
{ {
XFreeFont(nxagentDisplay, privFont -> font_struct); XFreeFont(nxagentDisplay, privFont -> font_struct);
privFont -> font_struct = NULL; privFont -> font_struct = NULL;
} }
} }
static void nxagentCollectFailedFont(FontPtr fpt, XID id) static void nxagentCollectFailedFont(FontPtr fpt, XID id)
{ {
if (nxagentFailedToReconnectFonts.font == NULL) if (nxagentFailedToReconnectFonts.font == NULL)
{ {
nxagentFailedToReconnectFonts.size = 8; nxagentFailedToReconnectFonts.size = 8;
nxagentFailedToReconnectFonts.font = malloc(nxagentFailedToReconnectFonts.size * nxagentFailedToReconnectFonts.font = malloc(nxagentFailedToReconnectFonts.size *
sizeof(FontPtr)); sizeof(FontPtr));
nxagentFailedToReconnectFonts.id = malloc(nxagentFailedToReconnectFonts.size * sizeof(XID)); nxagentFailedToReconnectFonts.id = malloc(nxagentFailedToReconnectFonts.size *
sizeof(XID));
if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL) if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
{ {
SAFE_free(nxagentFailedToReconnectFonts.font); SAFE_free(nxagentFailedToReconnectFonts.font);
SAFE_free(nxagentFailedToReconnectFonts.id); SAFE_free(nxagentFailedToReconnectFonts.id);
FatalError("Font: font not reconnected memory allocation failed!.\n");
}
FatalError("Font: font not reconnected memory allocation failed!.\n"); #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentCollectFailedFont: allocated [%d] bytes.\n",
8 * (sizeof(FontPtr)+ sizeof(XID)));
#endif
} }
else if (nxagentFailedToReconnectFonts.index == nxagentFailedToReconnectFonts.size - 1)
{
nxagentFailedToReconnectFonts.size *= 2;
#ifdef NXAGENT_RECONNECT_FONT_DEBUG /* FIXME: if realloc fails the pointer is lost */
fprintf(stderr, "nxagentCollectFailedFont: allocated [%d] bytes.\n", nxagentFailedToReconnectFonts.font = realloc(nxagentFailedToReconnectFonts.font,
8 * (sizeof(FontPtr)+ sizeof(XID))); nxagentFailedToReconnectFonts.size *
#endif sizeof(FontPtr));
}
else if (nxagentFailedToReconnectFonts.index == nxagentFailedToReconnectFonts.size - 1)
{
nxagentFailedToReconnectFonts.size *= 2;
nxagentFailedToReconnectFonts.font = realloc(nxagentFailedToReconnectFonts.font, nxagentFailedToReconnectFonts.id = realloc(nxagentFailedToReconnectFonts.id,
nxagentFailedToReconnectFonts.size * nxagentFailedToReconnectFonts.size *
sizeof(FontPtr)); sizeof(XID));
nxagentFailedToReconnectFonts.id = realloc(nxagentFailedToReconnectFonts.id, if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
nxagentFailedToReconnectFonts.size * {
sizeof(XID)); FatalError("Font: font not reconnected memory re-allocation failed!.\n");
}
if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL) #ifdef NXAGENT_RECONNECT_FONT_DEBUG
{ fprintf(stderr,"nxagentCollectFailedFont: reallocated memory.\n ");
FatalError("Font: font not reconnected memory re-allocation failed!.\n"); #endif
} }
#ifdef NXAGENT_RECONNECT_FONT_DEBUG nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index] = fpt;
fprintf(stderr,"nxagentCollectFailedFont: reallocated memory.\n ");
#endif
}
nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index] = fpt;
nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index] = id; nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index] = id;
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentCollectFailedFont: font not reconnected at [%p], " fprintf(stderr, "nxagentCollectFailedFont: font not reconnected at [%p], "
"put in nxagentFailedToReconnectFonts.font[%d] = [%p], with XID = [%lu].\n", "put in nxagentFailedToReconnectFonts.font[%d] = [%p], with XID = [%lu].\n",
(void*) fpt, nxagentFailedToReconnectFonts.index, (void*) fpt, nxagentFailedToReconnectFonts.index,
(void *)nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index], (void *)nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index],
nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index]); nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index]);
#endif #endif
nxagentFailedToReconnectFonts.index++; nxagentFailedToReconnectFonts.index++;
} }
static void nxagentFontReconnect(FontPtr pFont, XID param1, void * param2) static void nxagentFontReconnect(FontPtr pFont, XID param1, void * param2)
{ {
int i; int i;
Bool *pBool = (Bool*)param2; Bool *pBool = (Bool*)param2;
if (pFont == NULL) if (pFont == NULL)
return; return;
nxagentPrivFont *privFont = nxagentFontPriv(pFont); nxagentPrivFont *privFont = nxagentFontPriv(pFont);
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFontReconnect: pFont %p - XID %lx - name %s\n", fprintf(stderr, "nxagentFontReconnect: pFont %p - XID %lx - name %s\n",
(void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0, (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
privFont -> fontName); privFont -> fontName);
#endif #endif
for (i = 0; i < CACHE_INDEX; i++) for (i = 0; i < CACHE_INDEX; i++)
{
if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
fprintf(stderr, "\tfound in cache"); {
#endif #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "\tfound in cache");
#endif
if (!CACHE_FSTRUCT(i)) if (!CACHE_FSTRUCT(i))
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, " --- font struct not valid\n"); fprintf(stderr, " --- font struct not valid\n");
#endif #endif
break; break;
} }
nxagentFontStruct(pFont) = CACHE_FSTRUCT(i); nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
return; return;
}
} }
}
if (i == CACHE_INDEX) if (i == CACHE_INDEX)
{ {
FatalError("nxagentFontReconnect: font not found in cache."); FatalError("nxagentFontReconnect: font not found in cache.");
} }
privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont); privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
if ((privFont -> font_struct == NULL) && reconnectFlexibility) if ((privFont -> font_struct == NULL) && reconnectFlexibility)
{ {
privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont); privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
} }
if (privFont->font_struct != NULL) if (privFont->font_struct != NULL)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid); fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
#endif #endif
CACHE_FSTRUCT(i) = privFont -> font_struct; CACHE_FSTRUCT(i) = privFont -> font_struct;
} }
else else
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFontReconnect: failed\n"); fprintf(stderr, "nxagentFontReconnect: failed\n");
#endif #endif
nxagentCollectFailedFont(pFont, param1); nxagentCollectFailedFont(pFont, param1);
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFontReconnect: reconnection of font [%s] failed.\n", fprintf(stderr, "nxagentFontReconnect: reconnection of font [%s] failed.\n",
privFont -> fontName); privFont -> fontName);
#endif #endif
nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT, nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
"Couldn't restore the font '%s'", privFont -> fontName); "Couldn't restore the font '%s'", privFont -> fontName);
*pBool = False; *pBool = False;
} }
return; return;
} }
static void nxagentFreeCacheBeforeReconnect(void) static void nxagentFreeCacheBeforeReconnect(void)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
printFontCacheDump("nxagentFreeCacheBeforeReconnect"); printFontCacheDump("nxagentFreeCacheBeforeReconnect");
#endif #endif
for (int i = 0; i < CACHE_INDEX; i++) for (int i = 0; i < CACHE_INDEX; i++)
{
if (CACHE_FSTRUCT(i))
{ {
nxagentFreeFont(CACHE_FSTRUCT(i)); if (CACHE_FSTRUCT(i))
CACHE_FSTRUCT(i) = NULL; {
nxagentFreeFont(CACHE_FSTRUCT(i));
CACHE_FSTRUCT(i) = NULL;
}
} }
}
} }
static void nxagentCleanCacheAfterReconnect(void) static void nxagentCleanCacheAfterReconnect(void)
{ {
int real_size = CACHE_INDEX; int real_size = CACHE_INDEX;
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
printFontCacheDump("nxagentCleanCacheAfterReconnect"); printFontCacheDump("nxagentCleanCacheAfterReconnect");
#endif #endif
for (int i = 0; i < CACHE_INDEX; i++) for (int i = 0; i < CACHE_INDEX; i++)
{
if(CACHE_FSTRUCT(i) == NULL)
{ {
SAFE_XFree(CACHE_NAME(i)); if (CACHE_FSTRUCT(i) == NULL)
real_size--; {
SAFE_XFree(CACHE_NAME(i));
real_size--;
}
} }
}
for (int i = 0; i < real_size; i++) for (int i = 0; i < real_size; i++)
{ {
int j; int j;
nxCacheFontEntryRecPtr swapEntryPtr; nxCacheFontEntryRecPtr swapEntryPtr;
/* Find - first bad occurrence if exist. */ /* Find - first bad occurrence if exist. */
while ((i < real_size) && CACHE_FSTRUCT(i)) i++; while ((i < real_size) && CACHE_FSTRUCT(i))
i++;
/* Really nothing more to do. */ /* Really nothing more to do. */
if (i == real_size) if (i == real_size)
break; break;
/* /*
* Find - first good occurrence (moving backward from right end) entry in * Find - first good occurrence (moving backward from right end) entry in
* order to replace the bad one. * order to replace the bad one.
*/ */
for (j = CACHE_INDEX - 1; CACHE_FSTRUCT(j) == NULL; j--); for (j = CACHE_INDEX - 1; CACHE_FSTRUCT(j) == NULL; j--);
/* /*
* Now we can swap the two entry and reduce the Cache index * Now we can swap the two entry and reduce the Cache index
*/ */
swapEntryPtr = CACHE_ENTRY(i); swapEntryPtr = CACHE_ENTRY(i);
CACHE_ENTRY(i) = CACHE_ENTRY(j); CACHE_ENTRY(i) = CACHE_ENTRY(j);
CACHE_ENTRY(j) = swapEntryPtr; CACHE_ENTRY(j) = swapEntryPtr;
} }
CACHE_INDEX = real_size; CACHE_INDEX = real_size;
} }
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
static void printFontCacheDump(char* msg) static void printFontCacheDump(char* msg)
{ {
fprintf(stderr, "%s - begin -\n", msg); fprintf(stderr, "%s - begin -\n", msg);
for (int i = 0; i < CACHE_INDEX; i++) for (int i = 0; i < CACHE_INDEX; i++)
{
if (CACHE_FSTRUCT(i))
{
fprintf(stderr, "\tXID %lx - %s\n", CACHE_FSTRUCT(i) -> fid, CACHE_NAME(i));
}
else
{ {
fprintf(stderr, "\tdestroyed - %s\n", CACHE_NAME(i)); if (CACHE_FSTRUCT(i))
{
fprintf(stderr, "\tXID %lx - %s\n", CACHE_FSTRUCT(i) -> fid, CACHE_NAME(i));
}
else
{
fprintf(stderr, "\tdestroyed - %s\n", CACHE_NAME(i));
}
} }
} fprintf(stderr, "%s - end -\n", msg);
fprintf(stderr, "%s - end -\n", msg);
} }
#endif #endif
Bool nxagentReconnectAllFonts(void *p0) Bool nxagentReconnectAllFonts(void *p0)
{ {
Bool fontSuccess = True; Bool fontSuccess = True;
reconnectFlexibility = *((int *) p0); reconnectFlexibility = *((int *) p0);
#if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG) #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
fprintf(stderr, "nxagentReconnectAllFonts\n"); fprintf(stderr, "nxagentReconnectAllFonts\n");
#endif #endif
/* /*
* The resource type RT_NX_FONT is created on the server client * The resource type RT_NX_FONT is created on the server client
* only, so we can avoid to loop through all the clients. * only, so we can avoid to loop through all the clients.
*/ */
FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT, FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
(FindResType) nxagentFontReconnect, &fontSuccess); (FindResType) nxagentFontReconnect, &fontSuccess);
for (int cid = 0; cid < MAXCLIENTS; cid++) for (int cid = 0; cid < MAXCLIENTS; cid++)
{
if (clients[cid])
{ {
FindClientResourcesByType(clients[cid], RT_FONT, if (clients[cid])
(FindResType) nxagentFontReconnect, &fontSuccess); {
FindClientResourcesByType(clients[cid], RT_FONT,
(FindResType) nxagentFontReconnect, &fontSuccess);
}
} }
}
if (fontSuccess) if (fontSuccess)
{ {
nxagentCleanCacheAfterReconnect(); nxagentCleanCacheAfterReconnect();
} }
return fontSuccess; return fontSuccess;
} }
static void nxagentFailedFontReconnect(FontPtr pFont, XID param1, void * param2) static void nxagentFailedFontReconnect(FontPtr pFont, XID param1, void * param2)
{ {
int i; int i;
nxagentPrivFont *privFont; Bool *pBool = (Bool*)param2;
Bool *pBool = (Bool*)param2;
if (pFont == NULL) if (pFont == NULL)
return; return;
privFont = nxagentFontPriv(pFont); nxagentPrivFont *privFont = nxagentFontPriv(pFont);
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFailedFontReconnect: pFont %p - XID %lx - name %s\n", fprintf(stderr, "nxagentFailedFontReconnect: pFont %p - XID %lx - name %s\n",
(void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0, (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
privFont -> fontName); privFont -> fontName);
#endif #endif
for (i = 0; i < CACHE_INDEX; i++) for (i = 0; i < CACHE_INDEX; i++)
{
if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
fprintf(stderr, "\tfound in cache"); {
#endif #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "\tfound in cache");
#endif
if (!CACHE_FSTRUCT(i)) if (!CACHE_FSTRUCT(i))
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, " --- font struct not valid\n"); fprintf(stderr, " --- font struct not valid\n");
#endif #endif
break; break;
} }
nxagentFontStruct(pFont) = CACHE_FSTRUCT(i); nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
return; return;
}
} }
}
if (i == CACHE_INDEX) if (i == CACHE_INDEX)
{ {
FatalError("nxagentFailedFontReconnect: font not found in cache."); FatalError("nxagentFailedFontReconnect: font not found in cache.");
} }
privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont); privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
if (privFont -> font_struct == NULL) if (privFont -> font_struct == NULL)
{ {
privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont); privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
} }
if (privFont->font_struct != NULL) if (privFont->font_struct != NULL)
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid); fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
#endif #endif
CACHE_FSTRUCT(i) = privFont -> font_struct; CACHE_FSTRUCT(i) = privFont -> font_struct;
} }
else else
{ {
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFailedFontReconnect: failed\n"); fprintf(stderr, "nxagentFailedFontReconnect: failed\n");
#endif #endif
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentFailedFontReconnect: reconnection of font [%s] failed.\n", fprintf(stderr, "nxagentFailedFontReconnect: reconnection of font [%s] failed.\n",
privFont -> fontName); privFont -> fontName);
#endif #endif
nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT, nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
"Couldn't restore the font '%s'", privFont -> fontName); "Couldn't restore the font '%s'", privFont -> fontName);
*pBool = False; *pBool = False;
} }
return; return;
} }
static void nxagentFreeFailedToReconnectFonts(void) static void nxagentFreeFailedToReconnectFonts(void)
{ {
SAFE_free(nxagentFailedToReconnectFonts.font); SAFE_free(nxagentFailedToReconnectFonts.font);
SAFE_free(nxagentFailedToReconnectFonts.id); SAFE_free(nxagentFailedToReconnectFonts.id);
nxagentFailedToReconnectFonts.size = 0; nxagentFailedToReconnectFonts.size = 0;
nxagentFailedToReconnectFonts.index = 0; nxagentFailedToReconnectFonts.index = 0;
} }
Bool nxagentReconnectFailedFonts(void *p0) Bool nxagentReconnectFailedFonts(void *p0)
{ {
int attempt = 1; char fontServerPath[256] = "";
const int maxAttempt = 5;
char **fontPaths, **localFontPaths, **newFontPaths;
char fontServerPath[256] = "";
int nPaths = 0;
Bool repeat = True;
Bool fontSuccess = True;
reconnectFlexibility = *((int *) p0);
#ifdef NXAGENT_RECONNECT_FONT_DEBUG reconnectFlexibility = *((int *) p0);
fprintf(stderr, "nxagentReconnectFailedFonts: \n");
#endif
if (nxagentGetFontServerPath(fontServerPath, sizeof(fontServerPath)) == False) #ifdef NXAGENT_RECONNECT_FONT_DEBUG
{ fprintf(stderr, "nxagentReconnectFailedFonts: \n");
#ifdef WARNING
fprintf(stderr, "nxagentReconnectFailedFonts: WARNING! "
"Font server tunneling not retrieved.\n");
#endif #endif
}
#ifdef NXAGENT_RECONNECT_FONT_DEBUG if (nxagentGetFontServerPath(fontServerPath, sizeof(fontServerPath)) == False)
fprintf(stderr, "nxagentReconnectFailedFonts: font server path [%s]\n", fontServerPath); {
#endif #ifdef WARNING
fprintf(stderr, "nxagentReconnectFailedFonts: WARNING! "
fontPaths = XGetFontPath(nxagentDisplay, &nPaths); "Font server tunneling not retrieved.\n");
#endif
if ((newFontPaths = malloc((nPaths + 1) * sizeof(char *))) == NULL) }
{
FatalError("nxagentReconnectFailedFonts: malloc failed.");
}
memcpy(newFontPaths, fontPaths, nPaths * sizeof(char*));
localFontPaths = newFontPaths;
localFontPaths += nPaths;
*localFontPaths = fontServerPath;
while(repeat)
{
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentReconnectFailedFonts: attempt [%d].\n", attempt); fprintf(stderr, "nxagentReconnectFailedFonts: font server path [%s]\n", fontServerPath);
#endif #endif
repeat = False; int nPaths = 0;
char **fontPaths = XGetFontPath(nxagentDisplay, &nPaths);
char **newFontPaths = malloc((nPaths + 1) * sizeof(char *));
XSetFontPath(nxagentDisplay, newFontPaths, nPaths + 1); if (newFontPaths == NULL)
nxagentFreeRemoteFontList(&nxagentRemoteFontList); {
nxagentListRemoteFonts("*", nxagentMaxFontNames); FatalError("nxagentReconnectFailedFonts: malloc failed.");
}
for(int i = 0; i < nxagentFailedToReconnectFonts.index; i++) memcpy(newFontPaths, fontPaths, nPaths * sizeof(char*));
char **localFontPaths = newFontPaths;
localFontPaths += nPaths;
*localFontPaths = fontServerPath;
int attempt = 1;
const int maxAttempt = 5;
Bool repeat = True;
while (repeat)
{ {
fontSuccess = True; #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentReconnectFailedFonts: attempt [%d].\n", attempt);
#endif
if(nxagentFailedToReconnectFonts.font[i]) repeat = False;
{
nxagentFailedFontReconnect(nxagentFailedToReconnectFonts.font[i],
nxagentFailedToReconnectFonts.id[i],
&fontSuccess);
if (fontSuccess) XSetFontPath(nxagentDisplay, newFontPaths, nPaths + 1);
{ nxagentFreeRemoteFontList(&nxagentRemoteFontList);
nxagentFailedToReconnectFonts.font[i] = NULL; nxagentListRemoteFonts("*", nxagentMaxFontNames);
}
else for (int i = 0; i < nxagentFailedToReconnectFonts.index; i++)
{ {
repeat = True; Bool fontSuccess = True;
if (nxagentFailedToReconnectFonts.font[i])
{
nxagentFailedFontReconnect(nxagentFailedToReconnectFonts.font[i],
nxagentFailedToReconnectFonts.id[i],
&fontSuccess);
if (fontSuccess)
{
nxagentFailedToReconnectFonts.font[i] = NULL;
}
else
{
repeat = True;
}
}
} }
} attempt++;
}
attempt++; if (attempt > maxAttempt)
{
if (attempt > maxAttempt) nxagentFreeFailedToReconnectFonts();
{
nxagentFreeFailedToReconnectFonts();
XSetFontPath(nxagentDisplay, fontPaths, nPaths); XSetFontPath(nxagentDisplay, fontPaths, nPaths);
nxagentFreeRemoteFontList(&nxagentRemoteFontList); nxagentFreeRemoteFontList(&nxagentRemoteFontList);
nxagentListRemoteFonts("*", nxagentMaxFontNames); nxagentListRemoteFonts("*", nxagentMaxFontNames);
XFreeFontPath(fontPaths); XFreeFontPath(fontPaths);
SAFE_free(newFontPaths); SAFE_free(newFontPaths);
return False; return False;
}
} }
}
nxagentFreeFailedToReconnectFonts(); nxagentFreeFailedToReconnectFonts();
XSetFontPath(nxagentDisplay, fontPaths, nPaths); XSetFontPath(nxagentDisplay, fontPaths, nPaths);
XFreeFontPath(fontPaths); XFreeFontPath(fontPaths);
SAFE_free(newFontPaths); SAFE_free(newFontPaths);
nxagentCleanCacheAfterReconnect(); nxagentCleanCacheAfterReconnect();
return True; return True;
} }
Bool nxagentDisconnectAllFonts(void) Bool nxagentDisconnectAllFonts(void)
{ {
Bool fontSuccess = True; Bool fontSuccess = True;
#if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG) #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
fprintf(stderr, "nxagentDisconnectAllFonts\n"); fprintf(stderr, "nxagentDisconnectAllFonts\n");
#endif #endif
nxagentFreeRemoteFontList(&nxagentRemoteFontList); nxagentFreeRemoteFontList(&nxagentRemoteFontList);
nxagentFreeCacheBeforeReconnect(); nxagentFreeCacheBeforeReconnect();
/* /*
* The resource type RT_NX_FONT is created on the server client * The resource type RT_NX_FONT is created on the server client
* only, so we can avoid to loop through all the clients. * only, so we can avoid to loop through all the clients.
*/ */
FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT, FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
(FindResType) nxagentFontDisconnect, &fontSuccess); (FindResType) nxagentFontDisconnect, &fontSuccess);
for(int cid = 0; cid < MAXCLIENTS; cid++) for (int cid = 0; cid < MAXCLIENTS; cid++)
{
if( clients[cid] && fontSuccess )
{ {
FindClientResourcesByType(clients[cid], RT_FONT, if (clients[cid] && fontSuccess)
(FindResType) nxagentFontDisconnect, &fontSuccess); {
FindClientResourcesByType(clients[cid], RT_FONT,
(FindResType) nxagentFontDisconnect, &fontSuccess);
}
} }
}
return True; return True;
} }
static Bool nxagentGetFontServerPath(char * fontServerPath, int size) static Bool nxagentGetFontServerPath(char * fontServerPath, int size)
{ {
char path[256] = {0}; char path[256] = {0};
if (NXGetFontParameters(nxagentDisplay, sizeof(path), path) == True)
{
/* the length is stored in the first byte and is therefore limited to 255 */
unsigned int len = *path;
if (len) if (NXGetFontParameters(nxagentDisplay, sizeof(path), path) == True)
{ {
snprintf(fontServerPath, min(size, len + 1), "%s", path + 1); /* the length is stored in the first byte and is therefore limited to 255 */
unsigned int len = *path;
#ifdef TEST if (len)
fprintf(stderr, "%s: Got path [%s].\n", __func__, {
fontServerPath); snprintf(fontServerPath, min(size, len + 1), "%s", path + 1);
#endif
#ifdef TEST
fprintf(stderr, "%s: Got path [%s].\n", __func__,
fontServerPath);
#endif
}
else
{
#ifdef TEST
fprintf(stderr, "%s: WARNING! Font server tunneling not enabled.\n", __func__);
#endif
return False;
}
} }
else else
{ {
#ifdef TEST #ifdef TEST
fprintf(stderr, "%s: WARNING! Font server tunneling not enabled.\n", __func__); fprintf(stderr, "%s: WARNING! Failed to get path for font server tunneling.\n", __func__);
#endif #endif
return False; return False;
} }
}
else
{
#ifdef TEST
fprintf(stderr, "%s: WARNING! Failed to get path for font server tunneling.\n", __func__);
#endif
return False;
}
return True; return True;
} }
void nxagentVerifySingleFontPath(char **dest, const char *fontDir) void nxagentVerifySingleFontPath(char **dest, const char *fontDir)
{ {
if (!dest || !*dest) if (!dest || !*dest)
return; return;
#ifdef TEST #ifdef TEST
fprintf(stderr, "%s: Assuming fonts in directory [%s].\n", __func__, fprintf(stderr, "%s: Assuming fonts in directory [%s].\n", __func__,
validateString(fontDir)); validateString(fontDir));
#endif #endif
for (int i = 0; ; i++) for (int i = 0; ; i++)
{ {
char *tmppath = NULL; char *tmppath = NULL;
int rc; int rc;
const char *subdir = nxagentFontSubdirs[i]; const char *subdir = nxagentFontSubdirs[i];
if (subdir == NULL) if (subdir == NULL)
return; return;
if (**dest != '\0') if (**dest != '\0')
{ {
rc = asprintf(&tmppath, "%s,%s/%s", *dest, fontDir, subdir); rc = asprintf(&tmppath, "%s,%s/%s", *dest, fontDir, subdir);
} }
else else
{ {
rc = asprintf(&tmppath, "%s/%s", fontDir, subdir); rc = asprintf(&tmppath, "%s/%s", fontDir, subdir);
} }
if (rc == -1) if (rc == -1)
return; return;
SAFE_free(*dest); SAFE_free(*dest);
*dest = tmppath; *dest = tmppath;
tmppath = NULL; tmppath = NULL;
} }
} }
void nxagentVerifyDefaultFontPath(void) void nxagentVerifyDefaultFontPath(void)
{ {
static char *fontPath; static char *fontPath;
#ifdef TEST #ifdef TEST
fprintf(stderr, "%s: Going to search for one or more valid font paths.\n", __func__); fprintf(stderr, "%s: Going to search for one or more valid font paths.\n", __func__);
#endif
/*
* Set the default font path as the first choice.
*/
if ((fontPath = strdup(defaultFontPath)) == NULL)
{
#ifdef WARNING
fprintf(stderr, "%s: WARNING! Unable to allocate memory for a new font path. "
"Using the default font path [%s].\n", __func__,
validateString(defaultFontPath));
#endif #endif
return; /*
} * Set the default font path as the first choice.
*/
for (int i = 0; ; i++)
{
int j;
const char *dir = nxagentFontDirs[i];
if (dir == NULL) if ((fontPath = strdup(defaultFontPath)) == NULL)
{ {
break; #ifdef WARNING
fprintf(stderr, "%s: WARNING! Unable to allocate memory for a new font path. "
"Using the default font path [%s].\n", __func__,
validateString(defaultFontPath));
#endif
return;
} }
else
for (int i = 0; ; i++)
{ {
for (j = 0; j <= i; j++) int j;
{ const char *dir = nxagentFontDirs[i];
//if (strcmp(nxagentFontDirs[j], dir) == 0)
if (nxagentFontDirs[j] == dir) if (dir == NULL)
{ {
break; break;
} }
} else
{
if (j == i) for (j = 0; j <= i; j++)
{ {
nxagentVerifySingleFontPath(&fontPath, dir); //if (strcmp(nxagentFontDirs[j], dir) == 0)
} if (nxagentFontDirs[j] == dir)
{
break;
}
}
if (j == i)
{
nxagentVerifySingleFontPath(&fontPath, dir);
}
#ifdef TEST #ifdef TEST
else else
{ {
fprintf(stderr, "%s: Skipping duplicate font dir [%s].\n", __func__, fprintf(stderr, "%s: Skipping duplicate font dir [%s].\n", __func__,
validateString(dir)); validateString(dir));
} }
#endif #endif
}
} }
}
if (*fontPath == '\0') if (*fontPath == '\0')
{ {
#ifdef WARNING #ifdef WARNING
fprintf(stderr, "%s: WARNING! Can't find a valid font directory.\n", __func__); fprintf(stderr, "%s: WARNING! Can't find a valid font directory.\n", __func__);
fprintf(stderr, "%s: WARNING! Using font path [%s].\n", __func__, fprintf(stderr, "%s: WARNING! Using font path [%s].\n", __func__,
validateString(defaultFontPath)); validateString(defaultFontPath));
#endif #endif
} }
else else
{ {
/* do _not_ free defaultFontPath here - it's either set at compile time or /* do _not_ free defaultFontPath here - it's either set at compile time or
part of argv */ part of argv */
defaultFontPath = fontPath; defaultFontPath = fontPath;
#ifdef TEST #ifdef TEST
fprintf(stderr, "%s: Using font path [%s].\n", __func__, fprintf(stderr, "%s: Using font path [%s].\n", __func__,
validateString(defaultFontPath)); validateString(defaultFontPath));
#endif #endif
} }
return; return;
} }
XFontStruct* nxagentLoadQueryFont(register Display *dpy, char *name, FontPtr pFont) XFontStruct* nxagentLoadQueryFont(register Display *dpy, char *name, FontPtr pFont)
{ {
XFontStruct* fs; XFontStruct* fs = (XFontStruct *) malloc (sizeof (XFontStruct));
xCharInfo *xcip;
fs = (XFontStruct *) malloc (sizeof (XFontStruct)); if (fs == NULL)
{
if (fs == NULL) #ifdef WARNING
{ fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontStruct.\n");
#ifdef WARNING #endif
fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontStruct.\n");
#endif
return (XFontStruct *)NULL; return (XFontStruct *)NULL;
} }
#ifdef NXAGENT_RECONNECT_FONT_DEBUG #ifdef NXAGENT_RECONNECT_FONT_DEBUG
fprintf(stderr, "nxagentLoadQueryFont: Looking for font '%s'.\n", name); fprintf(stderr, "nxagentLoadQueryFont: Looking for font '%s'.\n", name);
#endif #endif
if (nxagentFontLookUp(name) == 0) if (nxagentFontLookUp(name) == 0)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "nxagentLoadQueryFont: WARNING! Font not found '%s'.\n", name); fprintf(stderr, "nxagentLoadQueryFont: WARNING! Font not found '%s'.\n", name);
#endif #endif
SAFE_free(fs); SAFE_free(fs);
return (XFontStruct *) NULL; return (XFontStruct *) NULL;
} }
fs -> ext_data = NULL; /* Hook for extension to hang data.*/
fs -> fid = XLoadFont(dpy, name); /* Font id for this font. */
fs -> direction = pFont->info.drawDirection; /* Hint about the direction font is painted. */
fs -> min_char_or_byte2 = pFont->info.firstCol; /* First character. */
fs -> max_char_or_byte2 = pFont->info.lastCol; /* Last character. */
fs -> min_byte1 = pFont->info.firstRow; /* First row that exists. */
fs -> max_byte1 = pFont->info.lastRow; /* Last row that exists. */
fs -> all_chars_exist = pFont->info.allExist; /* Flag if all characters have nonzero size. */
fs -> default_char = pFont->info.defaultCh; /* Char to print for undefined character. */
fs -> n_properties = pFont->info.nprops; /* How many properties there are. */
/*
* If no properties defined for the font, then it is bad
* font, but shouldn't try to read nothing.
*/
if (fs -> n_properties > 0) fs -> ext_data = NULL; /* Hook for extension to hang data.*/
{ fs -> fid = XLoadFont(dpy, name); /* Font id for this font. */
register long nbytes; fs -> direction = pFont->info.drawDirection; /* Hint about the direction font is painted. */
fs -> min_char_or_byte2 = pFont->info.firstCol; /* First character. */
fs -> max_char_or_byte2 = pFont->info.lastCol; /* Last character. */
fs -> min_byte1 = pFont->info.firstRow; /* First row that exists. */
fs -> max_byte1 = pFont->info.lastRow; /* Last row that exists. */
fs -> all_chars_exist = pFont->info.allExist; /* Flag if all characters have nonzero size. */
fs -> default_char = pFont->info.defaultCh; /* Char to print for undefined character. */
fs -> n_properties = pFont->info.nprops; /* How many properties there are. */
nbytes = pFont -> info.nprops * sizeof(XFontProp); /*
fs -> properties = (XFontProp *) malloc((unsigned) nbytes); * If no properties defined for the font, then it is bad
* font, but shouldn't try to read nothing.
*/
if (fs -> properties == NULL) if (fs -> n_properties > 0)
{ {
#ifdef WARNING long nbytes;
fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontProp.");
#endif
SAFE_free(fs); nbytes = pFont -> info.nprops * sizeof(XFontProp);
return (XFontStruct *) NULL; fs -> properties = (XFontProp *) malloc((unsigned) nbytes);
}
memmove(fs -> properties, pFont -> info.props, nbytes); if (fs -> properties == NULL)
} {
#ifdef WARNING
fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontProp.");
#endif
xcip = (xCharInfo *) &pFont -> info.ink_minbounds; SAFE_free(fs);
return (XFontStruct *) NULL;
}
fs -> min_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing); memmove(fs -> properties, pFont -> info.props, nbytes);
fs -> min_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing); }
fs -> min_bounds.width = cvtINT16toShort(xcip -> characterWidth);
fs -> min_bounds.ascent = cvtINT16toShort(xcip -> ascent); xCharInfo *xcip = (xCharInfo *) &pFont -> info.ink_minbounds;
fs -> min_bounds.descent = cvtINT16toShort(xcip -> descent);
fs -> min_bounds.attributes = xcip -> attributes; fs -> min_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing);
fs -> min_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing);
fs -> min_bounds.width = cvtINT16toShort(xcip -> characterWidth);
fs -> min_bounds.ascent = cvtINT16toShort(xcip -> ascent);
fs -> min_bounds.descent = cvtINT16toShort(xcip -> descent);
fs -> min_bounds.attributes = xcip -> attributes;
xcip = (xCharInfo *) &pFont -> info.ink_maxbounds; xcip = (xCharInfo *) &pFont -> info.ink_maxbounds;
fs -> max_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing); fs -> max_bounds.lbearing = cvtINT16toShort(xcip -> leftSideBearing);
fs -> max_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing); fs -> max_bounds.rbearing = cvtINT16toShort(xcip -> rightSideBearing);
fs -> max_bounds.width = cvtINT16toShort(xcip -> characterWidth); fs -> max_bounds.width = cvtINT16toShort(xcip -> characterWidth);
fs -> max_bounds.ascent = cvtINT16toShort(xcip -> ascent); fs -> max_bounds.ascent = cvtINT16toShort(xcip -> ascent);
fs -> max_bounds.descent = cvtINT16toShort(xcip -> descent); fs -> max_bounds.descent = cvtINT16toShort(xcip -> descent);
fs -> max_bounds.attributes = xcip -> attributes; fs -> max_bounds.attributes = xcip -> attributes;
fs -> per_char = NULL; /* First_char to last_char information. */ fs -> per_char = NULL; /* First_char to last_char information. */
fs -> ascent = pFont->info.fontAscent; /* Logical extent above baseline for spacing. */ fs -> ascent = pFont->info.fontAscent; /* Logical extent above baseline for spacing. */
fs -> descent = pFont->info.fontDescent; /* Logical decent below baseline for spacing. */ fs -> descent = pFont->info.fontDescent; /* Logical decent below baseline for spacing. */
return fs; return fs;
} }
int nxagentFreeFont(XFontStruct *fs) int nxagentFreeFont(XFontStruct *fs)
{ {
if (fs->per_char) if (fs->per_char)
{ {
#ifdef USE_XF86BIGFONT #ifdef USE_XF86BIGFONT
_XF86BigfontFreeFontMetrics(fs); _XF86BigfontFreeFontMetrics(fs);
#else #else
SAFE_free(fs->per_char); SAFE_free(fs->per_char);
#endif #endif
} }
SAFE_free(fs->properties); SAFE_free(fs->properties);
SAFE_XFree(fs); SAFE_XFree(fs);
return 1; return 1;
} }
int nxagentSplitString(char *string, char *fields[], int nfields, char *sep) int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
{ {
int seplen = strlen(sep); int seplen = strlen(sep);
int len = strlen(string); int len = strlen(string);
char *current = string; char *current = string;
int i = 0; int i = 0;
int last = 0; int last = 0;
for (;;) for (;;)
{
char *next = NULL;
if (current < string + len)
{ {
next = strstr(current, sep); char *next = NULL;
}
if (next == NULL) if (current < string + len)
{ {
next = string + len; next = strstr(current, sep);
last = 1; }
}
if (next == NULL)
{
next = string + len;
last = 1;
}
int fieldlen = next - current; int fieldlen = next - current;
if (i < nfields) if (i < nfields)
{ {
fields[i] = strndup(current, fieldlen); fields[i] = strndup(current, fieldlen);
} }
else else
{ {
fields[i] = NULL; fields[i] = NULL;
} }
current = next + seplen; current = next + seplen;
i++; i++;
if (last == 1) if (last == 1)
{ {
break; break;
}
} }
}
return i; return i;
} }
char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution) char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution)
{ {
char *scalableFontName; char *scalableFontName;
/* FIXME: use str(n)dup()? */
if ((scalableFontName = malloc(strlen(fontName) + 1)) == NULL)
{
#ifdef PANIC
fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
#endif
return NULL; /* FIXME: use str(n)dup()? */
} if ((scalableFontName = malloc(strlen(fontName) + 1)) == NULL)
{
#ifdef PANIC
fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
#endif
scalableFontName[0] = '\0'; return NULL;
}
if (*fontName != '-') scalableFontName[0] = '\0';
{
goto MakeScalableFontNameError;
}
const char *s = fontName; if (*fontName != '-')
{
goto MakeScalableFontNameError;
}
int field = 0; const char *s = fontName;
while (s != NULL) int field = 0;
{
s = strchr(s + 1, '-');
if (s != NULL) while (s != NULL)
{ {
if (field == 6 || field == 7 || field == 11) s = strchr(s + 1, '-');
{
/*
* PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
*/
strcat(scalableFontName, "-0"); if (s != NULL)
} {
else if (scalableResolution == 1 && (field == 8 || field == 9)) if (field == 6 || field == 7 || field == 11)
{ {
/* /*
* RESOLUTION_X || RESOLUTION_Y * PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
*/ */
strcat(scalableFontName, "-0"); strcat(scalableFontName, "-0");
} }
else else if (scalableResolution == 1 && (field == 8 || field == 9))
{ {
strncat(scalableFontName, fontName, s - fontName); /*
} * RESOLUTION_X || RESOLUTION_Y
*/
strcat(scalableFontName, "-0");
}
else
{
strncat(scalableFontName, fontName, s - fontName);
}
fontName = s;
}
else
{
strcat(scalableFontName, fontName);
}
fontName = s; field++;
} }
else
if (field != 14)
{ {
strcat(scalableFontName, fontName); goto MakeScalableFontNameError;
} }
field++; return scalableFontName;
}
if (field != 14)
{
goto MakeScalableFontNameError;
}
return scalableFontName;
MakeScalableFontNameError: MakeScalableFontNameError:
SAFE_free(scalableFontName); SAFE_free(scalableFontName);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n"); fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n");
#endif #endif
return NULL; return NULL;
} }
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