summaryrefslogtreecommitdiff
path: root/src/fc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fc')
-rw-r--r--src/fc/fsconvert.c257
-rw-r--r--src/fc/fserve.c3581
-rw-r--r--src/fc/fserve.h30
-rw-r--r--src/fc/fservestr.h63
-rw-r--r--src/fc/fsio.c742
-rw-r--r--src/fc/fsio.h137
-rw-r--r--src/fc/fslibos.h7
7 files changed, 2677 insertions, 2140 deletions
diff --git a/src/fc/fsconvert.c b/src/fc/fsconvert.c
index 1c8c6d1..47239cf 100644
--- a/src/fc/fsconvert.c
+++ b/src/fc/fsconvert.c
@@ -22,31 +22,32 @@
*
* Author: Dave Lemke, Network Computing Devices, Inc
*/
+/* $XFree86: xc/lib/font/fc/fsconvert.c,v 1.11 2002/09/10 16:14:35 tsi Exp $ */
/*
* FS data conversion
*/
#include <X11/X.h>
+#include <X11/Xtrans.h>
+#include <X11/Xpoll.h>
#include "FS.h"
#include "FSproto.h"
#include "fontmisc.h"
#include "fontstruct.h"
#include "fservestr.h"
+#include "fontutil.h"
extern char _fs_glyph_undefined;
extern char _fs_glyph_requested;
extern char _fs_glyph_zero_length;
-extern int _fs_load_glyphs();
/*
* converts data from font server form to X server form
*/
void
-_fs_convert_char_info(src, dst)
- fsXCharInfo *src;
- xCharInfo *dst;
+_fs_convert_char_info(fsXCharInfo *src, xCharInfo *dst)
{
dst->ascent = src->ascent;
dst->descent = src->descent;
@@ -57,9 +58,7 @@ _fs_convert_char_info(src, dst)
}
void
-_fs_init_fontinfo(conn, pfi)
- FSFpePtr conn;
- FontInfoPtr pfi;
+_fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi)
{
if (conn->fsMajorVersion == 1) {
unsigned short n;
@@ -69,7 +68,7 @@ _fs_init_fontinfo(conn, pfi)
n = pfi->lastCol;
pfi->lastCol = pfi->lastRow;
pfi->lastRow = n;
- pfi->defaultCh = (pfi->defaultCh >> 8) & 0xff
+ pfi->defaultCh = ((pfi->defaultCh >> 8) & 0xff)
+ ((pfi->defaultCh & 0xff) << 8);
}
@@ -87,11 +86,8 @@ _fs_init_fontinfo(conn, pfi)
}
int
-_fs_convert_props(pi, po, pd, pfi)
- fsPropInfo *pi;
- fsPropOffset *po;
- pointer pd;
- FontInfoPtr pfi;
+_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd,
+ FontInfoPtr pfi)
{
FontPropPtr dprop;
int i,
@@ -99,38 +95,39 @@ _fs_convert_props(pi, po, pd, pfi)
char *is_str;
fsPropOffset local_off;
char *off_adr;
+ char *pdc = pd;
/* stolen from server/include/resource.h */
#define BAD_RESOURCE 0xe0000000
nprops = pfi->nprops = pi->num_offsets;
- dprop = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops);
- is_str = (char *) xalloc(sizeof(char) * nprops);
- if (!dprop || !is_str) {
- xfree(is_str);
- xfree(dprop);
+ dprop = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops +
+ sizeof (char) * nprops);
+ if (!dprop)
return -1;
- }
+
+ is_str = (char *) (dprop + nprops);
pfi->props = dprop;
pfi->isStringProp = is_str;
off_adr = (char *)po;
- for (i = 0; i < nprops; i++, dprop++, is_str++) {
+ for (i = 0; i < nprops; i++, dprop++, is_str++)
+ {
memcpy(&local_off, off_adr, SIZEOF(fsPropOffset));
- dprop->name = MakeAtom(&pd[local_off.name.position],
+ dprop->name = MakeAtom(&pdc[local_off.name.position],
local_off.name.length, 1);
if (local_off.type != PropTypeString) {
*is_str = FALSE;
dprop->value = local_off.value.position;
} else {
*is_str = TRUE;
- dprop->value = (INT32) MakeAtom(&pd[local_off.value.position],
+ dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position],
local_off.value.length, 1);
if (dprop->value == BAD_RESOURCE)
{
xfree (pfi->props);
- xfree (pfi->isStringProp);
+ pfi->nprops = 0;
pfi->props = 0;
pfi->isStringProp = 0;
return -1;
@@ -142,14 +139,21 @@ _fs_convert_props(pi, po, pd, pfi)
return nprops;
}
+void
+_fs_free_props (FontInfoPtr pfi)
+{
+ if (pfi->props)
+ {
+ xfree (pfi->props);
+ pfi->nprops = 0;
+ pfi->props = 0;
+ }
+}
+
int
-_fs_convert_lfwi_reply(conn, pfi, fsrep, pi, po, pd)
- FSFpePtr conn;
- FontInfoPtr pfi;
- fsListFontsWithXInfoReply *fsrep;
- fsPropInfo *pi;
- fsPropOffset *po;
- pointer pd;
+_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi,
+ fsListFontsWithXInfoReply *fsrep,
+ fsPropInfo *pi, fsPropOffset *po, pointer pd)
{
fsUnpack_XFontInfoHeader(fsrep, pfi);
_fs_init_fontinfo(conn, pfi);
@@ -181,14 +185,9 @@ _fs_convert_lfwi_reply(conn, pfi, fsrep, pi, po, pd)
*/
/* ARGSUSED */
int
-fs_build_range(pfont, range_flag, count, item_size, data, nranges, ranges)
- FontPtr pfont;
- Bool range_flag;
- register unsigned int count;
- int item_size;
- register unsigned char *data;
- int *nranges;
- fsRange **ranges;
+fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count,
+ int item_size, unsigned char *data, int *nranges,
+ fsRange **ranges)
{
FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
FSFontPtr fsfont = (FSFontPtr) (pfont->fontPrivate);
@@ -309,7 +308,7 @@ fs_build_range(pfont, range_flag, count, item_size, data, nranges, ranges)
if (GLYPH_UNDEFINED(loc))
{
if (row1 == row2 &&
- ((col1 & 0xf) && col1 > firstcol ||
+ (((col1 & 0xf) && col1 > firstcol) ||
(col2 & 0xf) != 0xf) && (col2 < lastcol))
{
/* If we're loading from a single row, expand
@@ -348,10 +347,8 @@ fs_build_range(pfont, range_flag, count, item_size, data, nranges, ranges)
requests needs to be cancelled. */
void
-_fs_clean_aborted_loadglyphs(pfont, num_expected_ranges, expected_ranges)
- FontPtr pfont;
- int num_expected_ranges;
- fsRange *expected_ranges;
+_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges,
+ fsRange *expected_ranges)
{
register FSFontPtr fsfont;
register FSFontDataRec *fsd;
@@ -405,12 +402,8 @@ _fs_clean_aborted_loadglyphs(pfont, num_expected_ranges, expected_ranges)
*/
/* ARGSUSED */
int
-_fs_check_extents(pfont, flags, nranges, range, blockrec)
- FontPtr pfont;
- Mask flags;
- int nranges;
- fsRange *range;
- FSBlockDataPtr blockrec;
+_fs_check_extents(FontPtr pfont, Mask flags, int nranges, fsRange *range,
+ FSBlockDataPtr blockrec)
{
/* XXX -- either fill in the requested info if we have it somewhere
* and return AccessDone, or else return Successful
@@ -425,13 +418,9 @@ _fs_check_extents(pfont, flags, nranges, range, blockrec)
*/
/* ARGSUSED */
int
-_fs_check_bitmaps(pfont, format, flags, nranges, range, blockrec)
- FontPtr pfont;
- fsBitmapFormat format;
- Mask flags;
- int nranges;
- fsRange *range;
- FSBlockDataPtr blockrec;
+_fs_check_bitmaps(FontPtr pfont, fsBitmapFormat format,
+ Mask flags, int nranges, fsRange *range,
+ FSBlockDataPtr blockrec)
{
/* XXX -- either fill in the requested info if we have it somewhere
* and return AccessDone, or else return Successful
@@ -440,13 +429,10 @@ _fs_check_bitmaps(pfont, format, flags, nranges, range, blockrec)
}
int
-_fs_get_glyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
- FontPtr pFont;
- unsigned long count;
- register unsigned char *chars;
- FontEncoding charEncoding;
- unsigned long *glyphCount; /* RETURN */
- CharInfoPtr *glyphs; /* RETURN */
+_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ CharInfoPtr *glyphs) /* RETURN */
{
FSFontPtr fsdata;
unsigned int firstCol;
@@ -562,13 +548,10 @@ _fs_get_glyphs(pFont, count, chars, charEncoding, glyphCount, glyphs)
static int
-_fs_get_metrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
- FontPtr pFont;
- unsigned long count;
- register unsigned char *chars;
- FontEncoding charEncoding;
- unsigned long *glyphCount; /* RETURN */
- xCharInfo **glyphs; /* RETURN */
+_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars,
+ FontEncoding charEncoding,
+ unsigned long *glyphCount, /* RETURN */
+ xCharInfo **glyphs) /* RETURN */
{
FSFontPtr fsdata;
unsigned int firstCol;
@@ -585,6 +568,9 @@ _fs_get_metrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
fsdata = (FSFontPtr) pFont->fontPrivate;
encoding = fsdata->inkMetrics;
pDefault = fsdata->pDefault;
+ /* convert default bitmap metric to default ink metric */
+ if (pDefault)
+ pDefault = encoding + (pDefault - fsdata->encoding);
firstCol = pFont->info.firstCol;
numCols = pFont->info.lastCol - firstCol + 1;
glyphsBase = glyphs;
@@ -662,41 +648,120 @@ _fs_get_metrics(pFont, count, chars, charEncoding, glyphCount, glyphs)
void
-_fs_unload_font(pfont)
- FontPtr pfont;
+_fs_unload_font(FontPtr pfont)
{
- FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
-
- if (fsdata->encoding)
+ FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
+ FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate;
+ CharInfoPtr encoding = fsdata->encoding;
+ FSGlyphPtr glyphs;
+
+ /*
+ * fsdata points at FSFontRec, FSFontDataRec and name
+ */
+ if (encoding)
+ xfree(encoding);
+
+ while ((glyphs = fsdata->glyphs))
{
- register int i;
- register CharInfoPtr encoding = fsdata->encoding;
- FontInfoPtr pfi = &pfont->info;
- for (i = (pfi->lastCol - pfi->firstCol + 1) *
- (pfi->lastRow - pfi->firstRow + 1);
- i > 0;
- encoding++, i--)
- {
- if (encoding->bits &&
- encoding->bits != &_fs_glyph_undefined &&
- encoding->bits != &_fs_glyph_requested &&
- encoding->bits != &_fs_glyph_zero_length)
- xfree(encoding->bits);
- }
+ fsdata->glyphs = glyphs->next;
+ xfree (glyphs);
}
- xfree(fsdata->encoding);
+
+ /* XXX we may get called after the resource DB has been cleaned out */
+ if (find_old_font(fsd->fontid))
+ DeleteFontClientID (fsd->fontid);
+
+ _fs_free_props (&pfont->info);
+
xfree(fsdata);
-
- pfont->fontPrivate = 0;
+
+ DestroyFontRec(pfont);
}
-void
-_fs_init_font(pfont)
- FontPtr pfont;
+FontPtr
+fs_create_font (FontPathElementPtr fpe,
+ char *name,
+ int namelen,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask)
{
+ FontPtr pfont;
+ FSFontPtr fsfont;
+ FSFontDataPtr fsd;
+ int bit, byte, scan, glyph;
+
+ pfont = CreateFontRec ();
+ if (!pfont)
+ return 0;
+ fsfont = (FSFontPtr) xalloc (sizeof (FSFontRec) +
+ sizeof (FSFontDataRec) +
+ namelen + 1);
+ if (!fsfont)
+ {
+ DestroyFontRec (pfont);
+ return 0;
+ }
+ fsd = (FSFontDataPtr) (fsfont + 1);
+ bzero((char *) fsfont, sizeof(FSFontRec));
+ bzero((char *) fsd, sizeof(FSFontDataRec));
+
+ pfont->fpe = fpe;
+ pfont->fontPrivate = (pointer) fsfont;
+ pfont->fpePrivate = (pointer) fsd;
+
+ /* These font components will be needed in packGlyphs */
+ CheckFSFormat(format, BitmapFormatMaskBit |
+ BitmapFormatMaskByte |
+ BitmapFormatMaskScanLineUnit |
+ BitmapFormatMaskScanLinePad,
+ &bit,
+ &byte,
+ &scan,
+ &glyph,
+ NULL);
+ pfont->format = format;
+ pfont->bit = bit;
+ pfont->byte = byte;
+ pfont->scan = scan;
+ pfont->glyph = glyph;
+
+ pfont->info.nprops = 0;
+ pfont->info.props = 0;
+ pfont->info.isStringProp = 0;
+
/* set font function pointers */
pfont->get_glyphs = _fs_get_glyphs;
pfont->get_metrics = _fs_get_metrics;
pfont->unload_font = _fs_unload_font;
- pfont->unload_glyphs = (void (*)())0;
+ pfont->unload_glyphs = NULL;
+
+ /* set the FPE private information */
+ fsd->format = format;
+ fsd->fmask = fmask;
+ fsd->name = (char *) (fsd + 1);
+ memcpy (fsd->name, name, namelen);
+ fsd->name[namelen] = '\0';
+ fsd->fontid = GetNewFontClientID ();
+
+ /* save the ID */
+ if (!StoreFontClientFont(pfont, fsd->fontid))
+ {
+ xfree (fsfont);
+ DestroyFontRec (pfont);
+ return 0;
+ }
+
+ return pfont;
+}
+
+pointer
+fs_alloc_glyphs (FontPtr pFont, int size)
+{
+ FSGlyphPtr glyphs;
+ FSFontPtr fsfont = (FSFontPtr) pFont->fontPrivate;
+
+ glyphs = xalloc (sizeof (FSGlyphRec) + size);
+ glyphs->next = fsfont->glyphs;
+ fsfont->glyphs = glyphs;
+ return (pointer) (glyphs + 1);
}
diff --git a/src/fc/fserve.c b/src/fc/fserve.c
index 95ce811..f21233c 100644
--- a/src/fc/fserve.c
+++ b/src/fc/fserve.c
@@ -24,6 +24,7 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
+/* $XFree86: xc/lib/font/fc/fserve.c,v 3.22 2002/05/31 18:45:49 dawes Exp $ */
/*
* Copyright 1990 Network Computing Devices
@@ -54,36 +55,32 @@ in this Software without prior written authorization from The Open Group.
#ifdef WIN32
#define _WILLWINSOCK_
#endif
-#include <X11/X.h>
-#include <X11/Xos.h>
+#include "X11/Xtrans.h"
#include "X11/Xpoll.h"
#include "FS.h"
#include "FSproto.h"
+#include <X11/X.h>
+#include <X11/Xos.h>
#include "fontmisc.h"
#include "fontstruct.h"
#include "fservestr.h"
+#include "fontutil.h"
#include <errno.h>
-#ifdef X_NOT_STDC_ENV
-extern int errno;
-#define Time_t long
-extern Time_t time ();
-#else
+
#include <time.h>
#define Time_t time_t
-#endif
#ifdef NCD
#include <ncd/nvram.h>
#endif
-#ifndef NULL
-#define NULL 0
-#endif
+#include <stddef.h>
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
-
+#define TimeCmp(a,c,b) ((int) ((a) - (b)) c 0)
+
#define NONZEROMETRICS(pci) ((pci)->leftSideBearing || \
(pci)->rightSideBearing || \
(pci)->ascent || \
@@ -91,37 +88,71 @@ extern Time_t time ();
(pci)->characterWidth)
-extern FontPtr find_old_font();
-
-extern int _fs_build_range();
-
-static int fs_read_glyphs();
-static int fs_read_list();
-static int fs_read_list_info();
+static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list ( FontPathElementPtr fpe, FSBlockDataPtr blockrec );
+static int fs_read_list_info ( FontPathElementPtr fpe,
+ FSBlockDataPtr blockrec );
static int fs_font_type;
extern fd_set _fs_fd_mask;
-static void fs_block_handler();
-static int fs_wakeup();
-
-static FSFpePtr awaiting_reconnect;
+static void fs_block_handler ( pointer data, OSTimePtr wt,
+ pointer LastSelectMask );
+static int fs_wakeup ( FontPathElementPtr fpe, unsigned long *mask );
-void _fs_connection_died();
-static int _fs_restart_connection();
-static void _fs_try_reconnect();
-static int fs_send_query_info();
-static int fs_send_query_extents();
-static int fs_send_query_bitmaps();
-static int fs_send_close_font();
-static void fs_client_died();
-static void _fs_client_access();
-static void _fs_client_resolution();
+/*
+ * List of all FPEs
+ */
+static FSFpePtr fs_fpes;
+/*
+ * Union of all FPE blockStates
+ */
+static CARD32 fs_blockState;
+
+static int _fs_restart_connection ( FSFpePtr conn );
+static void fs_send_query_bitmaps ( FontPathElementPtr fpe,
+ FSBlockDataPtr blockrec );
+static int fs_send_close_font ( FontPathElementPtr fpe, Font id );
+static void fs_client_died ( pointer client, FontPathElementPtr fpe );
+static void _fs_client_access ( FSFpePtr conn, pointer client, Bool sync );
+static void _fs_client_resolution ( FSFpePtr conn );
+static fsGenericReply *fs_get_reply (FSFpePtr conn, int *error);
+static int fs_await_reply (FSFpePtr conn);
+static void _fs_do_blocked (FSFpePtr conn);
+static void fs_cleanup_bfont (FSBlockedFontPtr bfont);
char _fs_glyph_undefined;
char _fs_glyph_requested;
char _fs_glyph_zero_length;
+static int generationCount;
+
+int FontServerRequestTimeout = 30 * 1000;
+
+static void
+_fs_close_server (FSFpePtr conn);
+
+static FSFpePtr
+_fs_init_conn (char *servername);
+
+static int
+_fs_wait_connect (FSFpePtr conn);
+
+static int
+_fs_send_init_packets (FSFpePtr conn);
+
+static void
+_fs_check_reconnect (FSFpePtr conn);
+
+static void
+_fs_start_reconnect (FSFpePtr conn);
+
+static void
+_fs_free_conn (FSFpePtr conn);
+
+static int
+fs_free_fpe(FontPathElementPtr fpe);
+
/*
* Font server access
*
@@ -141,35 +172,58 @@ char _fs_glyph_zero_length;
*/
-/* XXX this should probably be a macro once its fully debugged */
-/* ARGSUSED */
+#ifdef DEBUG
static void
-_fs_add_req_log(conn, opcode)
- FSFpePtr conn;
- int opcode;
+_fs_add_req_log(FSFpePtr conn, int opcode)
{
-
-#ifdef DEBUG
- conn->reqbuffer[conn->reqindex++] = opcode;
+ conn->current_seq++;
+ fprintf (stderr, "\t\tRequest: %5d Opcode: %2d\n",
+ conn->current_seq, opcode);
+ conn->reqbuffer[conn->reqindex].opcode = opcode;
+ conn->reqbuffer[conn->reqindex].sequence = conn->current_seq;
+ conn->reqindex++;
if (conn->reqindex == REQUEST_LOG_SIZE)
conn->reqindex = 0;
-#endif
+}
- conn->current_seq++;
+static void
+_fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep)
+{
+ int i;
+
+ for (i = 0; i < REQUEST_LOG_SIZE; i++)
+ if (conn->reqbuffer[i].sequence == rep->sequenceNumber)
+ break;
+ if (i == REQUEST_LOG_SIZE)
+ fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: unknown\n",
+ rep->sequenceNumber);
+ else
+ fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: %d\n",
+ rep->sequenceNumber,
+ conn->reqbuffer[i].opcode);
}
+#else
+#define _fs_add_req_log(conn,op) ((conn)->current_seq++)
+#define _fs_add_rep_log(conn,rep)
+#endif
static Bool
-fs_name_check(name)
- char *name;
+fs_name_check(char *name)
{
+#ifdef __UNIXOS2__
+ /* OS/2 uses D:/usr/X11R6/.... as fontfile pathnames, so check that
+ * there is not only a protocol/ prefix, but also that the first chars
+ * are not a drive letter
+ */
+ if (name && isalpha(*name) && name[1] == ':')
+ return FALSE;
+#endif
/* Just make sure there is a protocol/ prefix */
-
return (name && *name != '/' && strchr(name, '/'));
}
static void
-_fs_client_resolution(conn)
- FSFpePtr conn;
+_fs_client_resolution(FSFpePtr conn)
{
fsSetResolutionReq srreq;
int num_res;
@@ -190,158 +244,18 @@ _fs_client_resolution(conn)
}
}
-/*
- * sends the stuff that's meaningful to a newly opened or reset FS
- */
-static int
-fs_send_init_packets(conn)
- FSFpePtr conn;
-{
- fsSetResolutionReq srreq;
- fsSetCataloguesReq screq;
- fsListCataloguesReq lcreq;
- fsListCataloguesReply lcreply;
- int num_cats,
- clen,
- len;
- char *client_cat = (char *) 0,
- *cp,
- *sp,
- *end;
- int num_res;
- FontResolutionPtr res;
- int err = Successful;
-
-#define CATALOGUE_SEP '+'
-
- res = GetClientResolutions(&num_res);
- if (num_res) {
- srreq.reqType = FS_SetResolution;
- srreq.num_resolutions = num_res;
- srreq.length = (SIZEOF(fsSetResolutionReq) +
- (num_res * SIZEOF(fsResolution)) + 3) >> 2;
-
- _fs_add_req_log(conn, FS_SetResolution);
- if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) == -1)
- {
- err = BadFontPath;
- goto fail;
- }
- if (_fs_write_pad(conn, (char *) res, (num_res * SIZEOF(fsResolution))) == -1)
- {
- err = BadFontPath;
- goto fail;
- }
- }
- sp = strrchr(conn->servername, '/');
-
- /* don't get tricked by a non-existant catalogue list */
- if (sp == strchr(conn->servername, '/')) {
- /*
- * try original name -- this might be an alternate with no catalogues
- */
- sp = strrchr(conn->requestedname, '/');
- if (sp == strchr(conn->requestedname, '/'))
- sp = (char *) 0;
- }
- if (sp) { /* turn cats into counted list */
- sp++;
- /* allocate more than enough room */
- cp = client_cat = (char *) xalloc(strlen(conn->servername));
- if (!cp) {
- err = BadAlloc;
- goto fail;
- }
- num_cats = 0;
- while (*sp) {
- end = strchr(sp, CATALOGUE_SEP);
- if (!end)
- end = sp + strlen(sp);
- *cp++ = len = end - sp;
- num_cats++;
- memmove(cp, sp, len);
- sp += len;
- if (*sp == CATALOGUE_SEP)
- sp++;
- cp += len;
- }
- clen = cp - client_cat;
- /* our list checked out, so send it */
- screq.reqType = FS_SetCatalogues;
- screq.num_catalogues = num_cats;
- screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2;
-
- _fs_add_req_log(conn, FS_SetCatalogues);
- if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) == -1)
- {
- err = BadFontPath;
- goto fail;
- }
- if (_fs_write_pad(conn, (char *) client_cat, clen) == -1)
- {
- err = BadFontPath;
- goto fail;
- }
-
- /*
- * now sync up with the font server, to see if an error was generated
- * by a bogus catalogue
- */
- lcreq.reqType = FS_ListCatalogues;
- lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2;
- lcreq.maxNames = 0;
- lcreq.nbytes = 0;
- _fs_add_req_log(conn, FS_SetCatalogues);
- if (_fs_write(conn, (char *) &lcreq, SIZEOF(fsListCataloguesReq)) == -1)
- {
- err = BadFontPath;
- goto fail;
- }
-
- /*
- * next bit will either by the ListCats reply, or an error followed by
- * the reply
- */
- if (_fs_read(conn, (char *) &lcreply, SIZEOF(fsGenericReply)) == -1) {
- err = BadFontPath;
- goto fail;
- }
- if (lcreply.type == FS_Error &&
- ((fsError *) & lcreply)->major_opcode == FS_SetCatalogues) {
- _fs_eat_rest_of_error(conn, (fsError *) & lcreply);
- /* get ListCats response */
- (void) _fs_read(conn, (char *) &lcreply,
- SIZEOF(fsListCataloguesReply));
- err = BadFontPath;
- goto fail;
- }
- /* must be reply, swallow the rest of it */
- _fs_eat_rest_of_error(conn, (fsError *) & lcreply);
- }
-fail:
- xfree(client_cat);
- return err;
-}
-
/*
* close font server and remove any state associated with
* this connection - this includes any client records.
*/
static void
-fs_close_conn(conn)
- FSFpePtr conn;
+fs_close_conn(FSFpePtr conn)
{
FSClientPtr client, nclient;
- /* XXX - hack. The right fix is to remember that the font server
- has gone away when we first discovered it. */
- if (conn->trans_conn)
- (void) _FontTransClose (conn->trans_conn);
-
- if (conn->fs_fd != -1)
- FD_CLR(conn->fs_fd, &_fs_fd_mask);
-
+ _fs_close_server (conn);
+
for (client = conn->clients; client; client = nclient)
{
nclient = client->next;
@@ -357,65 +271,76 @@ fs_close_conn(conn)
*/
/* ARGSUSED */
static int
-fs_init_fpe(fpe)
- FontPathElementPtr fpe;
+fs_init_fpe(FontPathElementPtr fpe)
{
FSFpePtr conn;
char *name;
int err;
+ int ret;
/* open font server */
/* create FS specific fpe info */
- errno = 0;
-
name = fpe->name;
/* hack for old style names */
if (*name == ':')
name++; /* skip ':' */
- conn = _fs_open_server(name);
- if (conn) {
- conn->requestedname = fpe->name; /* stash this for later init use */
- fpe->private = (pointer) conn;
- err = fs_send_init_packets(conn);
- if (err != Successful) {
- fs_close_conn(conn);
- xfree(conn->servername);
- xfree(conn->alts);
- xfree(conn);
- return err;
+ conn = _fs_init_conn (name);
+ if (!conn)
+ err = AllocError;
+ else
+ {
+ err = init_fs_handlers (fpe, fs_block_handler);
+ if (err != Successful)
+ {
+ _fs_free_conn (conn);
+ err = AllocError;
}
- if (init_fs_handlers(fpe, fs_block_handler) != Successful)
- return AllocError;
- FD_SET(conn->fs_fd, &_fs_fd_mask);
- conn->attemptReconnect = TRUE;
-
+ else
+ {
+ fpe->private = conn;
+ conn->next = fs_fpes;
+ fs_fpes = conn;
+ ret = _fs_wait_connect (conn);
+ if (ret != FSIO_READY)
+ {
+ fs_free_fpe (fpe);
+ err = BadFontPath;
+ }
+ else
+ err = Successful;
+ }
+ }
+
+ if (err == Successful)
+ {
#ifdef NCD
if (configData.ExtendedFontDiags)
printf("Connected to font server \"%s\"\n", name);
#endif
-
- return err;
+#ifdef DEBUG
+ fprintf (stderr, "connected to FS \"%s\"\n", name);
+#endif
}
-
+ else
+ {
#ifdef DEBUG
- fprintf(stderr, "failed to connect to FS \"%s\"\n", name);
+ fprintf(stderr, "failed to connect to FS \"%s\" %d\n", name, err);
#endif
-
#ifdef NCD
- if (configData.ExtendedFontDiags)
- printf("Failed to connect to font server \"%s\"\n", name);
+ if (configData.ExtendedFontDiags)
+ printf("Failed to connect to font server \"%s\"\n", name);
#endif
-
- return (errno == ENOMEM) ? AllocError : BadFontPath;
+ ;
+ }
+ return err;
}
static int
-fs_reset_fpe(fpe)
- FontPathElementPtr fpe;
+fs_reset_fpe(FontPathElementPtr fpe)
{
- (void) fs_send_init_packets((FSFpePtr) fpe->private);
+ (void) _fs_send_init_packets((FSFpePtr) fpe->private);
return Successful;
}
@@ -424,54 +349,44 @@ fs_reset_fpe(fpe)
*/
static int
-fs_free_fpe(fpe)
- FontPathElementPtr fpe;
+fs_free_fpe(FontPathElementPtr fpe)
{
- FSFpePtr conn = (FSFpePtr) fpe->private;
- FSFpePtr recon,
- *prev;
- prev = &awaiting_reconnect;
- while (*prev) {
- recon = *prev;
- if (conn == recon) {
- *prev = recon->next_reconnect;
+ FSFpePtr conn = (FSFpePtr) fpe->private, *prev;
+
+ /* unhook from chain of all font servers */
+ for (prev = &fs_fpes; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == conn)
+ {
+ *prev = conn->next;
break;
}
- prev = &recon->next_reconnect;
}
-
+ _fs_unmark_block (conn, conn->blockState);
fs_close_conn(conn);
-
- remove_fs_handlers(fpe, fs_block_handler,
- !XFD_ANYSET(&_fs_fd_mask) && !awaiting_reconnect);
-
- xfree(conn->alts);
- xfree(conn->servername);
- xfree(conn);
+ remove_fs_handlers(fpe, fs_block_handler, fs_fpes == 0);
+ _fs_free_conn (conn);
fpe->private = (pointer) 0;
#ifdef NCD
if (configData.ExtendedFontDiags)
printf("Disconnected from font server \"%s\"\n", fpe->name);
#endif
+#ifdef DEBUG
+ fprintf (stderr, "disconnect from FS \"%s\"\n", fpe->name);
+#endif
return Successful;
}
static FSBlockDataPtr
-fs_new_block_rec(fpe, client, type)
- FontPathElementPtr fpe;
- pointer client;
- int type;
+fs_new_block_rec(FontPathElementPtr fpe, pointer client, int type)
{
FSBlockDataPtr blockrec,
- br;
- FSFpePtr fsfpe = (FSFpePtr) fpe->private;
+ *prev;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
int size;
- blockrec = (FSBlockDataPtr) xalloc(sizeof(FSBlockDataRec));
- if (!blockrec)
- return (FSBlockDataPtr) 0;
switch (type) {
case FS_OPEN_FONT:
size = sizeof(FSBlockedFontRec);
@@ -486,208 +401,301 @@ fs_new_block_rec(fpe, client, type)
size = sizeof(FSBlockedListInfoRec);
break;
default:
+ size = 0;
break;
}
- blockrec->data = (pointer) xalloc(size);
- if (!blockrec->data) {
- xfree(blockrec);
+ blockrec = (FSBlockDataPtr) xalloc(sizeof(FSBlockDataRec) + size);
+ if (!blockrec)
return (FSBlockDataPtr) 0;
- }
+ blockrec->data = (pointer) (blockrec + 1);
blockrec->client = client;
- blockrec->sequence_number = fsfpe->current_seq;
+ blockrec->sequenceNumber = -1;
+ blockrec->errcode = StillWorking;
blockrec->type = type;
blockrec->depending = 0;
blockrec->next = (FSBlockDataPtr) 0;
-
+
/* stick it on the end of the list (since its expected last) */
- br = (FSBlockDataPtr) fsfpe->blocked_requests;
- if (!br) {
- fsfpe->blocked_requests = (pointer) blockrec;
- } else {
- while (br->next)
- br = br->next;
- br->next = blockrec;
- }
+ for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+ ;
+ *prev = blockrec;
return blockrec;
}
static void
-_fs_remove_block_rec(conn, blockrec)
- FSFpePtr conn;
- FSBlockDataPtr blockrec;
+_fs_set_pending_reply (FSFpePtr conn)
{
- FSBlockDataPtr br,
- last;
+ FSBlockDataPtr blockrec;
+
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ if (blockrec->errcode == StillWorking)
+ break;
+ if (blockrec)
+ {
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ }
+ else
+ _fs_unmark_block (conn, FS_PENDING_REPLY);
+}
- last = (FSBlockDataPtr) 0;
- br = (FSBlockDataPtr) conn->blocked_requests;
- while (br) {
- if (br == blockrec) {
- if (last)
- last->next = br->next;
- else
- conn->blocked_requests = (pointer) br->next;
- if (br->type == FS_LOAD_GLYPHS)
- {
- FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)br->data;
- if (bglyph->num_expected_ranges)
- xfree(bglyph->expected_ranges);
- }
- xfree(br->data);
- xfree(br);
- return;
+static void
+_fs_remove_block_rec(FSFpePtr conn, FSBlockDataPtr blockrec)
+{
+ FSBlockDataPtr *prev;
+
+ for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next)
+ if (*prev == blockrec)
+ {
+ *prev = blockrec->next;
+ break;
}
- last = br;
- br = br->next;
+ if (blockrec->type == FS_LOAD_GLYPHS)
+ {
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+ if (bglyph->num_expected_ranges)
+ xfree(bglyph->expected_ranges);
}
+ xfree(blockrec);
+ _fs_set_pending_reply (conn);
}
static void
-signal_clients_depending(clients_depending)
-FSClientsDependingPtr *clients_depending;
+_fs_signal_clients_depending(FSClientsDependingPtr *clients_depending)
{
- FSClientsDependingPtr p = *clients_depending, p2;
- *clients_depending = (FSClientsDependingPtr)0;
-
- while (p != (FSClientsDependingPtr)0)
+ FSClientsDependingPtr p;
+
+ while ((p = *clients_depending))
{
- p2 = p;
+ *clients_depending = p->next;
ClientSignal(p->client);
- p = p->next;
- xfree(p2);
+ xfree(p);
}
}
static int
-add_clients_depending(clients_depending, client)
-FSClientsDependingPtr *clients_depending;
-pointer client;
+_fs_add_clients_depending(FSClientsDependingPtr *clients_depending, pointer client)
{
- while (*clients_depending != (FSClientsDependingPtr)0)
+ FSClientsDependingPtr new, cd;
+
+ for (; (cd = *clients_depending);
+ clients_depending = &(*clients_depending)->next)
{
- if ((*clients_depending)->client == client) return Suspended;
- clients_depending = &(*clients_depending)->next;
+ if (cd->client == client)
+ return Suspended;
}
- *clients_depending = (FSClientsDependingPtr)xalloc(
- sizeof(FSClientsDependingRec));
- if (!*clients_depending)
+
+ new = (FSClientsDependingPtr)xalloc (sizeof (FSClientsDependingRec));
+ if (!new)
return BadAlloc;
- (*clients_depending)->client = client;
- (*clients_depending)->next = 0;
+ new->client = client;
+ new->next = 0;
+ *clients_depending = new;
return Suspended;
}
+/*
+ * When a request is aborted due to a font server failure,
+ * signal any depending clients to restart their dependant
+ * requests
+ */
static void
-clean_aborted_blockrec(blockrec)
- FSBlockDataPtr blockrec;
+_fs_clean_aborted_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
{
-
- switch(blockrec->type)
- {
- case FS_LOAD_GLYPHS:
- {
- FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
- FontPtr pfont = bglyph->pfont;
- int num_expected_ranges = bglyph->num_expected_ranges;
- fsRange *expected_ranges = bglyph->expected_ranges;
- _fs_clean_aborted_loadglyphs(pfont,
- num_expected_ranges,
- expected_ranges);
- signal_clients_depending(&bglyph->clients_depending);
- break;
- }
- case FS_OPEN_FONT:
- {
- FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data;
- signal_clients_depending(&bfont->clients_depending);
- break;
- }
- default:
- break;
+ switch(blockrec->type) {
+ case FS_OPEN_FONT: {
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data;
+
+ fs_cleanup_bfont (bfont);
+ _fs_signal_clients_depending(&bfont->clients_depending);
+ break;
+ }
+ case FS_LOAD_GLYPHS: {
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data;
+
+ _fs_clean_aborted_loadglyphs(bglyph->pfont,
+ bglyph->num_expected_ranges,
+ bglyph->expected_ranges);
+ _fs_signal_clients_depending(&bglyph->clients_depending);
+ break;
+ }
+ case FS_LIST_FONTS:
+ break;
+ case FS_LIST_WITH_INFO: {
+ FSBlockedListInfoPtr binfo;
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+ if (binfo->status == FS_LFWI_REPLY)
+ FD_SET(conn->fs_fd, &_fs_fd_mask);
+ _fs_free_props (&binfo->info);
+ }
+ default:
+ break;
}
}
static void
-fs_abort_blockrec(conn, blockrec)
- FSFpePtr conn;
- FSBlockDataPtr blockrec;
+fs_abort_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec)
{
- clean_aborted_blockrec(blockrec);
- _fs_remove_block_rec(conn, blockrec);
+ _fs_clean_aborted_blockrec (conn, blockrec);
+ _fs_remove_block_rec (conn, blockrec);
}
-
+/*
+ * Tell the font server we've failed to complete an open and
+ * then unload the partially created font
+ */
static void
-fs_free_font(bfont)
- FSBlockedFontPtr bfont;
+fs_cleanup_bfont (FSBlockedFontPtr bfont)
{
- FontPtr pfont;
FSFontDataRec *fsd;
- pfont = bfont->pfont;
- fsd = (FSFontDataRec *) pfont->fpePrivate;
-
- /* xfree better be able to handle NULL */
- (*pfont->unload_font)(pfont);
- DeleteFontClientID(fsd->fontid);
- xfree(fsd->name);
- xfree(pfont->info.isStringProp);
- xfree(pfont->info.props);
-
- xfree(pfont);
- xfree(fsd);
-
- bfont->pfont = (FontPtr) 0;
+ if (bfont->pfont)
+ {
+ fsd = (FSFontDataRec *) bfont->pfont->fpePrivate;
+
+ /* make sure the FS knows we choked on it */
+ fs_send_close_font(bfont->pfont->fpe, bfont->fontid);
+
+ /*
+ * Either unload the font if it's being opened for
+ * the first time, or smash the generation field to
+ * mark this font as an orphan
+ */
+ if (!(bfont->flags & FontReopen))
+ {
+ if (bfont->freeFont)
+ (*bfont->pfont->unload_font) (bfont->pfont);
+#ifdef DEBUG
+ else
+ fprintf (stderr, "Not freeing other font in cleanup_bfont\n");
+#endif
+ bfont->pfont = 0;
+ }
+ else
+ fsd->generation = -1;
+ }
}
-static void
-_fs_cleanup_font(bfont)
- FSBlockedFontPtr bfont;
+/*
+ * Check to see if a complete reply is waiting
+ */
+static fsGenericReply *
+fs_get_reply (FSFpePtr conn, int *error)
{
- FSFontDataRec *fsd;
+ char *buf;
+ fsGenericReply *rep;
+ int ret;
- if (bfont->pfont)
+ /* block if the connection is down or paused in lfwi */
+ if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
{
- fsd = (FSFontDataRec *) bfont->pfont->fpePrivate;
+ *error = FSIO_BLOCK;
+ return 0;
+ }
- /* make sure the FS knows we choked on it */
- fs_send_close_font(fsd->fpe, bfont->fontid);
+ ret = _fs_start_read (conn, sizeof (fsGenericReply), &buf);
+ if (ret != FSIO_READY)
+ {
+ *error = FSIO_BLOCK;
+ return 0;
+ }
- fs_free_font(bfont);
+ rep = (fsGenericReply *) buf;
+
+ ret = _fs_start_read (conn, rep->length << 2, &buf);
+ if (ret != FSIO_READY)
+ {
+ *error = FSIO_BLOCK;
+ return 0;
}
- bfont->errcode = AllocError;
+
+ *error = FSIO_READY;
+
+ return (fsGenericReply *) buf;
}
+static Bool
+fs_reply_ready (FSFpePtr conn)
+{
+ fsGenericReply *rep;
+
+ if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask))
+ return FALSE;
+ if (fs_data_read (conn) < sizeof (fsGenericReply))
+ return FALSE;
+ rep = (fsGenericReply *) (conn->inBuf.buf + conn->inBuf.remove);
+ if (fs_data_read (conn) < rep->length << 2)
+ return FALSE;
+ return TRUE;
+}
-static int
-fs_read_open_font(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+static void
+_fs_pending_reply (FSFpePtr conn)
{
- FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsOpenBitmapFontReply rep;
- FSBlockDataPtr blockOrig;
- FSBlockedFontPtr origBfont;
+ if (!(conn->blockState & FS_PENDING_REPLY))
+ {
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ }
+}
- /* pull out the OpenFont reply */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
+static void
+_fs_prepare_for_reply (FSFpePtr conn)
+{
+ _fs_pending_reply (conn);
+ _fs_flush (conn);
+}
- if (rep.type == FS_Error) {
- _fs_eat_rest_of_error(conn, (fsError *) & rep);
- return BadFontName;
- } else { /* get rest of reply */
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsOpenBitmapFontReply) - SIZEOF(fsGenericReply)) == -1) {
- /* If we're not reopening a font, we'll allocate the
- structures again after connection is reestablished. */
- if (!(bfont->flags & FontReopen)) fs_free_font(bfont);
- return StillWorking;
+/*
+ * Block (for a while) awaiting a complete reply
+ */
+static int
+fs_await_reply (FSFpePtr conn)
+{
+ int ret;
+
+ if (conn->blockState & FS_COMPLETE_REPLY)
+ return FSIO_READY;
+
+ while (!fs_get_reply (conn, &ret))
+ {
+ if (ret != FSIO_BLOCK)
+ return ret;
+ if (_fs_wait_for_readable (conn, FontServerRequestTimeout) != FSIO_READY)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
}
}
+ return FSIO_READY;
+}
+/*
+ * Process the reply to an OpenBitmapFont request
+ */
+static int
+fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ fsOpenBitmapFontReply *rep;
+ FSBlockDataPtr blockOrig;
+ FSBlockedFontPtr origBfont;
+ int ret;
+
+ rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
+ }
+
/* If we're not reopening a font and FS detected a duplicate font
open request, replace our reference to the new font with a
reference to an existing font (possibly one not finished
@@ -697,23 +705,27 @@ fs_read_open_font(fpe, blockrec)
if we we decide (in fs_read_query_info()) that we don't like what
we got. */
- if (rep.otherid && !(bfont->flags & FontReopen)) {
- (void) fs_send_close_font(fpe, bfont->fontid);
-
+ if (rep->otherid && !(bfont->flags & FontReopen))
+ {
+ fs_cleanup_bfont (bfont);
+
/* Find old font if we're completely done getting it from server. */
- fs_free_font(bfont);
- bfont->pfont = find_old_font(rep.otherid);
- bfont->fontid = rep.otherid;
+ bfont->pfont = find_old_font(rep->otherid);
+ bfont->freeFont = FALSE;
+ bfont->fontid = rep->otherid;
bfont->state = FS_DONE_REPLY;
/*
* look for a blocked request to open the same font
*/
- for (blockOrig = (FSBlockDataPtr) conn->blocked_requests;
+ for (blockOrig = conn->blockedRequests;
blockOrig;
- blockOrig = blockOrig->next) {
- if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) {
+ blockOrig = blockOrig->next)
+ {
+ if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT)
+ {
origBfont = (FSBlockedFontPtr) blockOrig->data;
- if (origBfont->fontid == rep.otherid) {
+ if (origBfont->fontid == rep->otherid)
+ {
blockrec->depending = blockOrig->depending;
blockOrig->depending = blockrec;
bfont->state = FS_DEPENDING;
@@ -725,252 +737,267 @@ fs_read_open_font(fpe, blockrec)
if (bfont->pfont == NULL)
{
/* XXX - something nasty happened */
- return BadFontName;
+ ret = BadFontName;
}
- return AccessDone;
+ else
+ ret = AccessDone;
}
-
- bfont->pfont->info.cachable = rep.cachable != 0;
- bfont->state = FS_INFO_REPLY;
- /* ask for the next stage */
- (void) fs_send_query_info(fpe, blockrec);
- return StillWorking;
+ else
+ {
+ bfont->pfont->info.cachable = rep->cachable != 0;
+ bfont->state = FS_INFO_REPLY;
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryInfoSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ ret = StillWorking;
+ }
+ _fs_done_read (conn, rep->length << 2);
+ return ret;
}
+static Bool
+fs_fonts_match (FontInfoPtr pInfo1, FontInfoPtr pInfo2)
+{
+ int i;
+
+ if (pInfo1->firstCol != pInfo2->firstCol ||
+ pInfo1->lastCol != pInfo2->lastCol ||
+ pInfo1->firstRow != pInfo2->firstRow ||
+ pInfo1->lastRow != pInfo2->lastRow ||
+ pInfo1->defaultCh != pInfo2->defaultCh ||
+ pInfo1->noOverlap != pInfo2->noOverlap ||
+ pInfo1->terminalFont != pInfo2->terminalFont ||
+ pInfo1->constantMetrics != pInfo2->constantMetrics ||
+ pInfo1->constantWidth != pInfo2->constantWidth ||
+ pInfo1->inkInside != pInfo2->inkInside ||
+ pInfo1->inkMetrics != pInfo2->inkMetrics ||
+ pInfo1->allExist != pInfo2->allExist ||
+ pInfo1->drawDirection != pInfo2->drawDirection ||
+ pInfo1->cachable != pInfo2->cachable ||
+ pInfo1->anamorphic != pInfo2->anamorphic ||
+ pInfo1->maxOverlap != pInfo2->maxOverlap ||
+ pInfo1->fontAscent != pInfo2->fontAscent ||
+ pInfo1->fontDescent != pInfo2->fontDescent ||
+ pInfo1->nprops != pInfo2->nprops)
+ return FALSE;
+
+#define MATCH(xci1, xci2) \
+ (((xci1).leftSideBearing == (xci2).leftSideBearing) && \
+ ((xci1).rightSideBearing == (xci2).rightSideBearing) && \
+ ((xci1).characterWidth == (xci2).characterWidth) && \
+ ((xci1).ascent == (xci2).ascent) && \
+ ((xci1).descent == (xci2).descent) && \
+ ((xci1).attributes == (xci2).attributes))
+
+ if (!MATCH(pInfo1->maxbounds, pInfo2->maxbounds) ||
+ !MATCH(pInfo1->minbounds, pInfo2->minbounds) ||
+ !MATCH(pInfo1->ink_maxbounds, pInfo2->ink_maxbounds) ||
+ !MATCH(pInfo1->ink_minbounds, pInfo2->ink_minbounds))
+ return FALSE;
+
+#undef MATCH
+
+ for (i = 0; i < pInfo1->nprops; i++)
+ if (pInfo1->isStringProp[i] !=
+ pInfo2->isStringProp[i] ||
+ pInfo1->props[i].name !=
+ pInfo2->props[i].name ||
+ pInfo1->props[i].value !=
+ pInfo2->props[i].value)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
static int
-fs_read_query_info(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsQueryXInfoReply rep;
- fsPropInfo pi;
- fsPropOffset *po;
- pointer pd;
- unsigned long prop_len;
- FSBlockedFontRec newbfont, *oldbfont;
- FontRec newpfont, *oldpfont;
- int err;
-
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ fsQueryXInfoReply *rep;
+ char *buf;
+ fsPropInfo *pi;
+ fsPropOffset *po;
+ pointer pd;
+ FontInfoPtr pInfo;
+ FontInfoRec tempInfo;
+ int err;
+ int ret;
+
+ rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
+ }
+
/* If this is a reopen, accumulate the query info into a dummy
font and compare to our original data. */
if (bfont->flags & FontReopen)
- {
- newbfont = *(oldbfont = bfont);
- bfont = &newbfont;
- newpfont = *(oldpfont = oldbfont->pfont);
- newpfont.info.isStringProp = NULL;
- newpfont.info.props = NULL;
- newbfont.pfont = &newpfont;
- err = StillWorking;
- }
-
- /* pull out the QueryXInfo reply */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsQueryXInfoReply) - SIZEOF(fsGenericReply)) == -1) {
- if (bfont->flags & FontReopen) goto bail;
- fs_free_font(bfont);
- return StillWorking;
- }
+ pInfo = &tempInfo;
+ else
+ pInfo = &bfont->pfont->info;
+
+ buf = (char *) rep;
+ buf += SIZEOF(fsQueryXInfoReply);
+
/* move the data over */
- fsUnpack_XFontInfoHeader(&rep, &bfont->pfont->info);
- _fs_init_fontinfo(conn, &bfont->pfont->info);
+ fsUnpack_XFontInfoHeader(rep, pInfo);
+
+ /* compute accelerators */
+ _fs_init_fontinfo(conn, pInfo);
- if (bfont->pfont->info.terminalFont)
- {
- bfont->format =
- (bfont->format & ~ (BitmapFormatImageRectMask)) |
- BitmapFormatImageRectMax;
- }
+ /* Compute offsets into the reply */
+ pi = (fsPropInfo *) buf;
+ buf += SIZEOF (fsPropInfo);
+
+ po = (fsPropOffset *) buf;
+ buf += pi->num_offsets * SIZEOF(fsPropOffset);
- if (_fs_read(conn, (char *) &pi, SIZEOF(fsPropInfo)) == -1) {
- if (bfont->flags & FontReopen) goto bail;
- fs_free_font(bfont);
- return StillWorking;
- }
- prop_len = pi.num_offsets * SIZEOF(fsPropOffset);
- po = (fsPropOffset *) xalloc(prop_len);
- pd = (pointer) xalloc(pi.data_len);
- if (!po || !pd) {
- xfree(pd);
- xfree(po);
- /* clear the wire */
- (void) _fs_drain_bytes(conn, prop_len + pi.data_len);
- /* clean up the font */
- if (bfont->flags & FontReopen) { err = AllocError ; goto bail; }
- (void) _fs_cleanup_font(bfont);
- return AllocError;
- }
- if (_fs_read_pad(conn, (char *) po, prop_len) == -1 ||
- _fs_read_pad(conn, (char *) pd, pi.data_len) == -1) {
- xfree(pd);
- xfree(po);
- if (bfont->flags & FontReopen) goto bail;
- fs_free_font(bfont);
- return StillWorking;
- }
- if (_fs_convert_props(&pi, po, pd, &bfont->pfont->info) == -1)
+ pd = (pointer) buf;
+ buf += pi->data_len;
+
+ /* convert the properties and step over the reply */
+ ret = _fs_convert_props(pi, po, pd, pInfo);
+ _fs_done_read (conn, rep->length << 2);
+
+ if (ret == -1)
{
- xfree(po);
- xfree(pd);
- if (bfont->flags & FontReopen) { err = AllocError ; goto bail; }
- (void) _fs_cleanup_font(bfont);
+ fs_cleanup_bfont (bfont);
return AllocError;
}
- xfree(po);
- xfree(pd);
if (bfont->flags & FontReopen)
{
- int i;
-
- err = BadFontName;
-
/* We're reopening a font that we lost because of a downed
connection. In the interest of avoiding corruption from
opening a different font than the old one (we already have
its metrics, extents, and probably some of its glyphs),
verify that the metrics and properties all match. */
- if (newpfont.info.firstCol != oldpfont->info.firstCol ||
- newpfont.info.lastCol != oldpfont->info.lastCol ||
- newpfont.info.firstRow != oldpfont->info.firstRow ||
- newpfont.info.lastRow != oldpfont->info.lastRow ||
- newpfont.info.defaultCh != oldpfont->info.defaultCh ||
- newpfont.info.noOverlap != oldpfont->info.noOverlap ||
- newpfont.info.terminalFont != oldpfont->info.terminalFont ||
- newpfont.info.constantMetrics != oldpfont->info.constantMetrics ||
- newpfont.info.constantWidth != oldpfont->info.constantWidth ||
- newpfont.info.inkInside != oldpfont->info.inkInside ||
- newpfont.info.inkMetrics != oldpfont->info.inkMetrics ||
- newpfont.info.allExist != oldpfont->info.allExist ||
- newpfont.info.drawDirection != oldpfont->info.drawDirection ||
- newpfont.info.cachable != oldpfont->info.cachable ||
- newpfont.info.anamorphic != oldpfont->info.anamorphic ||
- newpfont.info.maxOverlap != oldpfont->info.maxOverlap ||
- newpfont.info.fontAscent != oldpfont->info.fontAscent ||
- newpfont.info.fontDescent != oldpfont->info.fontDescent ||
- newpfont.info.nprops != oldpfont->info.nprops)
- goto bail;
-
-#define MATCH(xci1, xci2) \
- (((xci1).leftSideBearing == (xci2).leftSideBearing) && \
- ((xci1).rightSideBearing == (xci2).rightSideBearing) && \
- ((xci1).characterWidth == (xci2).characterWidth) && \
- ((xci1).ascent == (xci2).ascent) && \
- ((xci1).descent == (xci2).descent) && \
- ((xci1).attributes == (xci2).attributes))
-
- if (!MATCH(newpfont.info.maxbounds, oldpfont->info.maxbounds) ||
- !MATCH(newpfont.info.minbounds, oldpfont->info.minbounds) ||
- !MATCH(newpfont.info.ink_maxbounds, oldpfont->info.ink_maxbounds) ||
- !MATCH(newpfont.info.ink_minbounds, oldpfont->info.ink_minbounds))
- goto bail;
-
-#undef MATCH
-
- for (i = 0; i < newpfont.info.nprops; i++)
- if (newpfont.info.isStringProp[i] !=
- oldpfont->info.isStringProp[i] ||
- newpfont.info.props[i].name !=
- oldpfont->info.props[i].name ||
- newpfont.info.props[i].value !=
- oldpfont->info.props[i].value)
- goto bail;
-
- err = Successful;
- bail:
- if (err != Successful && err != StillWorking)
+ if (fs_fonts_match (pInfo, &bfont->pfont->info))
{
- /* Failure. Close the font. */
- fs_send_close_font(((FSFontDataPtr)oldpfont->fpePrivate)->fpe,
- bfont->fontid);
- ((FSFontDataPtr)oldpfont->fpePrivate)->generation = -1;
+ err = Successful;
+ bfont->state = FS_DONE_REPLY;
}
- xfree(newpfont.info.isStringProp);
- xfree(newpfont.info.props);
-
- if (err == Successful) oldbfont->state = FS_DONE_REPLY;
+ else
+ {
+ fs_cleanup_bfont (bfont);
+ err = BadFontName;
+ }
+ _fs_free_props (pInfo);
+
return err;
}
+ /*
+ * Ask for terminal format fonts if possible
+ */
+ if (bfont->pfont->info.terminalFont)
+ bfont->format = ((bfont->format & ~ (BitmapFormatImageRectMask)) |
+ BitmapFormatImageRectMax);
+
+ /*
+ * Figure out if the whole font should get loaded right now.
+ */
if (glyphCachingMode == CACHING_OFF ||
- glyphCachingMode == CACHE_16_BIT_GLYPHS && !bfont->pfont->info.lastRow)
+ (glyphCachingMode == CACHE_16_BIT_GLYPHS
+ && !bfont->pfont->info.lastRow))
+ {
bfont->flags |= FontLoadAll;
+ }
+
+ /*
+ * Ready to send the query bitmaps; the terminal font bit has
+ * been computed and glyphCaching has been considered
+ */
+ if (bfont->flags & FontLoadBitmaps)
+ {
+ fs_send_query_bitmaps (fpe, blockrec);
+ _fs_flush (conn);
+ }
bfont->state = FS_EXTENT_REPLY;
- fs_send_query_extents(fpe, blockrec);
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryExtentsSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+
return StillWorking;
}
static int
-fs_read_extent_info(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
- FSFontDataPtr fsd = (FSFontDataPtr) bfont->pfont->fpePrivate;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsQueryXExtents16Reply rep;
- int i;
- int numInfos;
- Bool haveInk = FALSE; /* need separate ink metrics? */
- CharInfoPtr ci,
- pCI;
- FSFontPtr fsfont = (FSFontPtr) bfont->pfont->fontPrivate;
- fsXCharInfo *fsci;
- fsXCharInfo fscilocal;
- pointer fscip;
-
- /* read the QueryXExtents reply */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsQueryXExtents16Reply) - SIZEOF(fsGenericReply)) == -1) {
- fs_free_font(bfont);
- return StillWorking;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFontDataPtr fsd = (FSFontDataPtr) bfont->pfont->fpePrivate;
+ FSFontPtr fsfont = (FSFontPtr) bfont->pfont->fontPrivate;
+ fsQueryXExtents16Reply *rep;
+ char *buf;
+ int i;
+ int numExtents;
+ int numInfos;
+ int ret;
+ Bool haveInk = FALSE; /* need separate ink metrics? */
+ CharInfoPtr ci, pCI;
+ char *fsci;
+ fsXCharInfo fscilocal;
+
+ rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont (bfont);
+ return BadFontName;
}
+
/* move the data over */
/* need separate inkMetrics for fixed font server protocol version */
- numInfos = rep.num_extents;
+ numExtents = rep->num_extents;
+ numInfos = numExtents;
if (bfont->pfont->info.terminalFont && conn->fsMajorVersion > 1)
{
numInfos *= 2;
haveInk = TRUE;
}
ci = pCI = (CharInfoPtr) xalloc(sizeof(CharInfoRec) * numInfos);
-/* XXX this could be done with an ALLOCATE_LOCAL */
- fsci = (fsXCharInfo *) xalloc(SIZEOF(fsXCharInfo) * rep.num_extents);
- if (!pCI || !fsci) {
- xfree(pCI);
- xfree(fsci);
- /* clear the unusable data */
- _fs_drain_bytes(conn, SIZEOF(fsXCharInfo) * rep.num_extents);
- _fs_cleanup_font(bfont);
+
+ if (!pCI)
+ {
+ _fs_done_read (conn, rep->length << 2);
+ fs_cleanup_bfont(bfont);
return AllocError;
}
fsfont->encoding = pCI;
if (haveInk)
- fsfont->inkMetrics = pCI + rep.num_extents;
+ fsfont->inkMetrics = pCI + numExtents;
else
fsfont->inkMetrics = pCI;
- if (_fs_read_pad(conn, (char *) fsci,
- SIZEOF(fsXCharInfo) * rep.num_extents) == -1) {
- fs_free_font(bfont);
- xfree(fsci);
- return StillWorking;
- }
+ buf = (char *) rep;
+ buf += SIZEOF (fsQueryXExtents16Reply);
+ fsci = buf;
+
fsd->glyphs_to_get = 0;
- fscip = (pointer) fsci;
ci = fsfont->inkMetrics;
- for (i = 0; i < rep.num_extents; i++) {
- memcpy(&fscilocal, fscip, SIZEOF(fsXCharInfo)); /* align it */
+ for (i = 0; i < numExtents; i++)
+ {
+ memcpy(&fscilocal, fsci, SIZEOF(fsXCharInfo)); /* align it */
_fs_convert_char_info(&fscilocal, &ci->metrics);
- fscip += SIZEOF(fsXCharInfo);
+ fsci = fsci + SIZEOF(fsXCharInfo);
/* Initialize the bits field for later glyph-caching use */
if (NONZEROMETRICS(&ci->metrics))
{
@@ -989,8 +1016,9 @@ fs_read_extent_info(fpe, blockrec)
ci++;
}
- xfree(fsci);
-
+ /* Done with reply */
+ _fs_done_read (conn, rep->length << 2);
+
/* build bitmap metrics, ImageRectMax style */
if (haveInk)
{
@@ -999,7 +1027,7 @@ fs_read_extent_info(fpe, blockrec)
ci = fsfont->encoding;
ii = fsfont->inkMetrics;
- for (i = 0; i < rep.num_extents; i++, ci++, ii++)
+ for (i = 0; i < numExtents; i++, ci++, ii++)
{
if (NONZEROMETRICS(&ii->metrics))
{
@@ -1042,164 +1070,190 @@ fs_read_extent_info(fpe, blockrec)
}
bfont->state = FS_GLYPHS_REPLY;
- if (bfont->flags & FontLoadBitmaps) {
- fs_send_query_bitmaps(fpe, blockrec);
+ if (bfont->flags & FontLoadBitmaps)
+ {
+ /*
+ * Reset the blockrec for the next reply
+ */
+ blockrec->sequenceNumber = bfont->queryBitmapsSequence;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
return StillWorking;
}
return Successful;
}
-/*
- * XXX should probably continue to read here if we can, but must be sure
- * it's our packet waiting, rather than another interspersed
- */
+#ifdef DEBUG
+static char *fs_open_states[] = {
+ "OPEN_REPLY ",
+ "INFO_REPLY ",
+ "EXTENT_REPLY",
+ "GLYPHS_REPLY",
+ "DONE_REPLY ",
+ "DEPENDING ",
+};
+#endif
+
static int
-fs_do_open_font(fpe, blockrec, readheader)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
- Bool readheader;
+fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- int err;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ int err;
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_open_font state %s %s\n",
+ fs_open_states[bfont->state],
+ ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name);
+#endif
+ err = BadFontName;
switch (bfont->state) {
case FS_OPEN_REPLY:
- if (readheader) {
- /* get the next header */
- if (_fs_read(conn, (char *) &blockrec->header,
- SIZEOF(fsGenericReply)) == -1) {
- fs_free_font(bfont);
- err = StillWorking;
- break;
- }
- }
- bfont->errcode = fs_read_open_font(fpe, blockrec);
- if (bfont->errcode != StillWorking) { /* already loaded, or error */
+ err = fs_read_open_font(fpe, blockrec);
+ if (err != StillWorking) { /* already loaded, or error */
/* if font's already loaded, massage error code */
switch (bfont->state) {
case FS_DONE_REPLY:
- bfont->errcode = Successful;
+ err = Successful;
break;
case FS_DEPENDING:
- bfont->errcode = StillWorking;
- break;
- }
- err = bfont->errcode;
- break;
- }
- /* if more data to read or Sync, fall thru, else return */
- if (!(bfont->flags & FontOpenSync)) {
- err = bfont->errcode;
- break;
- } else {
- if (_fs_read(conn, (char *) &blockrec->header,
- SIZEOF(fsGenericReply)) == -1) {
- fs_free_font(bfont);
err = StillWorking;
break;
}
}
- /* fall through */
+ break;
case FS_INFO_REPLY:
- bfont->errcode = fs_read_query_info(fpe, blockrec);
- if (bfont->errcode != StillWorking) {
- err = bfont->errcode;
- break;
- }
- if (!(bfont->flags & FontOpenSync)) {
- err = bfont->errcode;
- break;
- /* if more data to read, fall thru, else return */
- } else {
- if (_fs_read(conn, (char *) &blockrec->header,
- SIZEOF(fsGenericReply))) {
- fs_free_font(bfont);
- err = StillWorking;
- break;
- }
- }
- /* fall through */
+ err = fs_read_query_info(fpe, blockrec);
+ break;
case FS_EXTENT_REPLY:
- bfont->errcode = fs_read_extent_info(fpe, blockrec);
- if (bfont->errcode != StillWorking) {
- err = bfont->errcode;
- break;
- }
- if (!(bfont->flags & FontOpenSync)) {
- err = bfont->errcode;
- break;
- } else if (bfont->flags & FontLoadBitmaps) {
- if (_fs_read(conn, (char *) &blockrec->header,
- SIZEOF(fsGenericReply))) {
- fs_free_font(bfont);
- err = StillWorking;
- break;
- }
- }
- /* fall through */
+ err = fs_read_extent_info(fpe, blockrec);
+ break;
case FS_GLYPHS_REPLY:
- if (bfont->flags & FontLoadBitmaps) {
- bfont->errcode = fs_read_glyphs(fpe, blockrec);
- }
- err = bfont->errcode;
+ if (bfont->flags & FontLoadBitmaps)
+ err = fs_read_glyphs(fpe, blockrec);
break;
case FS_DEPENDING: /* can't happen */
- err = bfont->errcode;
default:
- err = bfont->errcode;
break;
}
- if (err != StillWorking) {
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_open_font err %d\n", err);
+#endif
+ if (err != StillWorking)
+ {
bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */
- while (blockrec = blockrec->depending) {
+ while ((blockrec = blockrec->depending))
+ {
bfont = (FSBlockedFontPtr) blockrec->data;
- bfont->errcode = err;
bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */
}
}
return err;
}
+void
+_fs_mark_block (FSFpePtr conn, CARD32 mask)
+{
+ conn->blockState |= mask;
+ fs_blockState |= mask;
+}
+
+void
+_fs_unmark_block (FSFpePtr conn, CARD32 mask)
+{
+ FSFpePtr c;
+
+ if (conn->blockState & mask)
+ {
+ conn->blockState &= ~mask;
+ fs_blockState = 0;
+ for (c = fs_fpes; c; c = c->next)
+ fs_blockState |= c->blockState;
+ }
+}
+
/* ARGSUSED */
static void
-fs_block_handler(data, wt, LastSelectMask)
- pointer data;
- struct timeval **wt;
- fd_set* LastSelectMask;
-{
- static struct timeval recon_timeout;
- Time_t now,
- soonest;
- FSFpePtr recon;
-
- XFD_ORSET(LastSelectMask, LastSelectMask, &_fs_fd_mask);
- if (recon = awaiting_reconnect) {
- now = time((Time_t *) 0);
- soonest = recon->time_to_try;
- while (recon = recon->next_reconnect) {
- if (recon->time_to_try < soonest)
- soonest = recon->time_to_try;
- }
- if (soonest < now)
- soonest = now;
- soonest = soonest - now;
- recon_timeout.tv_sec = soonest;
- recon_timeout.tv_usec = 0;
- if (*wt == (struct timeval *) 0) {
- *wt = &recon_timeout;
- } else if ((*wt)->tv_sec > soonest) {
- **wt = recon_timeout;
+fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask)
+{
+ static struct timeval block_timeout;
+ CARD32 now, earliest, wakeup;
+ int soonest;
+ FSFpePtr conn;
+
+ XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask,
+ &_fs_fd_mask);
+ /*
+ * Flush all pending output
+ */
+ if (fs_blockState & FS_PENDING_WRITE)
+ for (conn = fs_fpes; conn; conn = conn->next)
+ if (conn->blockState & FS_PENDING_WRITE)
+ _fs_flush (conn);
+ /*
+ * Check for any fpe with a complete reply, set sleep time to zero
+ */
+ if (fs_blockState & FS_COMPLETE_REPLY)
+ {
+ block_timeout.tv_sec = 0;
+ block_timeout.tv_usec = 0;
+ if (*wt == NULL)
+ *wt = &block_timeout;
+ else
+ **wt = block_timeout;
+ }
+ /*
+ * Walk through fpe list computing sleep time
+ */
+ else if (fs_blockState & (FS_BROKEN_WRITE|
+ FS_BROKEN_CONNECTION|
+ FS_PENDING_REPLY|
+ FS_RECONNECTING))
+ {
+ now = GetTimeInMillis ();
+ earliest = now + 10000000;
+ for (conn = fs_fpes; conn; conn = conn->next)
+ {
+ if (conn->blockState & FS_RECONNECTING)
+ {
+ wakeup = conn->blockedConnectTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_BROKEN_CONNECTION)
+ {
+ wakeup = conn->brokenConnectionTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_BROKEN_WRITE)
+ {
+ wakeup = conn->brokenWriteTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
+ if (conn->blockState & FS_PENDING_REPLY)
+ {
+ wakeup = conn->blockedReplyTime;
+ if (TimeCmp (wakeup, <, earliest))
+ earliest = wakeup;
+ }
}
+ soonest = earliest - now;
+ if (soonest < 0)
+ soonest = 0;
+ block_timeout.tv_sec = soonest / 1000;
+ block_timeout.tv_usec = (soonest % 1000) * 1000;
+ if (*wt == NULL)
+ *wt = &block_timeout;
+ else if (soonest < (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000)
+ **wt = block_timeout;
}
}
static void
-fs_handle_unexpected(conn, rep)
- FSFpePtr conn;
- fsGenericReply *rep;
+fs_handle_unexpected(FSFpePtr conn, fsGenericReply *rep)
{
- if (rep->type == FS_Event && rep->data1 == KeepAlive) {
+ if (rep->type == FS_Event && rep->data1 == KeepAlive)
+ {
fsNoopReq req;
/* ping it back */
@@ -1209,155 +1263,223 @@ fs_handle_unexpected(conn, rep)
_fs_write(conn, (char *) &req, SIZEOF(fsNoopReq));
}
/* this should suck up unexpected replies and events */
- _fs_eat_rest_of_error(conn, (fsError *) rep);
+ _fs_done_read (conn, rep->length << 2);
}
-static int
-fs_wakeup(fpe, LastSelectMask)
- FontPathElementPtr fpe;
- fd_set* LastSelectMask;
+static void
+fs_read_reply (FontPathElementPtr fpe, pointer client)
{
- FSBlockDataPtr blockrec,
- br;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- int err;
- fsGenericReply rep;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ int ret;
+ int err;
+ fsGenericReply *rep;
+
+ if ((rep = fs_get_reply (conn, &ret)))
+ {
+ _fs_add_rep_log (conn, rep);
+ for (blockrec = conn->blockedRequests;
+ blockrec;
+ blockrec = blockrec->next)
+ {
+ if (blockrec->sequenceNumber == rep->sequenceNumber)
+ break;
+ }
+ err = Successful;
+ if (!blockrec)
+ {
+ fs_handle_unexpected(conn, rep);
+ }
+ else
+ {
+ /*
+ * go read it, and if we're done,
+ * wake up the appropriate client
+ */
+ switch (blockrec->type) {
+ case FS_OPEN_FONT:
+ blockrec->errcode = fs_do_open_font(fpe, blockrec);
+ break;
+ case FS_LOAD_GLYPHS:
+ blockrec->errcode = fs_read_glyphs(fpe, blockrec);
+ break;
+ case FS_LIST_FONTS:
+ blockrec->errcode = fs_read_list(fpe, blockrec);
+ break;
+ case FS_LIST_WITH_INFO:
+ blockrec->errcode = fs_read_list_info(fpe, blockrec);
+ break;
+ default:
+ break;
+ }
+ err = blockrec->errcode;
+ if (err != StillWorking)
+ {
+ while (blockrec)
+ {
+ blockrec->errcode = err;
+ if (client != blockrec->client)
+ ClientSignal(blockrec->client);
+ blockrec = blockrec->depending;
+ }
+ _fs_unmark_block (conn, FS_PENDING_REPLY);
+ }
+ }
+ if (fs_reply_ready (conn))
+ _fs_mark_block (conn, FS_COMPLETE_REPLY);
+ else
+ _fs_unmark_block (conn, FS_COMPLETE_REPLY);
+ }
+}
- /* see if there's any data to be read */
+static int
+fs_wakeup(FontPathElementPtr fpe, unsigned long *mask)
+{
+ fd_set *LastSelectMask = (fd_set *) mask;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
/*
* Don't continue if the fd is -1 (which will be true when the
* font server terminates
*/
- if (conn->fs_fd == -1)
- return FALSE;
-
- if (FD_ISSET(conn->fs_fd, LastSelectMask)) {
+ if ((conn->blockState & FS_RECONNECTING))
+ _fs_check_reconnect (conn);
+ else if ((conn->blockState & FS_COMPLETE_REPLY) ||
+ (conn->fs_fd != -1 && FD_ISSET(conn->fs_fd, LastSelectMask)))
+ fs_read_reply (fpe, 0);
+ if (conn->blockState & (FS_PENDING_REPLY|FS_BROKEN_CONNECTION|FS_BROKEN_WRITE))
+ _fs_do_blocked (conn);
+#ifdef DEBUG
+ {
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
+ FSBlockedListPtr blist;
+ static CARD32 lastState;
+ static FSBlockDataPtr lastBlock;
-#ifdef NOTDEF /* bogus - doesn't deal with EOF very well,
- * now does it ... */
- /*
- * make sure it isn't spurious - mouse events seem to trigger extra
- * problems
- */
- if (_fs_data_ready(conn) <= 0) {
- return FALSE;
+ if (conn->blockState || conn->blockedRequests || lastState || lastBlock)
+ {
+ fprintf (stderr, " Block State 0x%x\n", (int) conn->blockState);
+ lastState = conn->blockState;
+ lastBlock = conn->blockedRequests;
}
-#endif
-
- /* get the header */
- if (_fs_read(conn, (char *) &rep, SIZEOF(fsGenericReply)) == -1)
- return FALSE;
-
- /* find the matching block record */
-
- for (br = (FSBlockDataPtr) conn->blocked_requests; br; br = br->next) {
- if ((CARD16)(br->sequence_number & 0xffff) ==
- (CARD16)(rep.sequenceNumber - 1))
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ switch (blockrec->type) {
+ case FS_OPEN_FONT:
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ fprintf (stderr, " Blocked font errcode %d sequence %d state %s %s\n",
+ blockrec->errcode,
+ blockrec->sequenceNumber,
+ fs_open_states[bfont->state],
+ bfont->pfont ?
+ ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name :
+ "<freed>");
+ break;
+ case FS_LIST_FONTS:
+ blist = (FSBlockedListPtr) blockrec->data;
+ fprintf (stderr, " Blocked list errcode %d sequence %d\n",
+ blockrec->errcode, blockrec->sequenceNumber);
+ break;
+ default:
+ fprintf (stderr, " Blocked type %d errcode %d sequence %d\n",
+ blockrec->type,
+ blockrec->errcode,
+ blockrec->sequenceNumber);
break;
- }
- if (!br) {
- fs_handle_unexpected(conn, &rep);
- return FALSE;
- }
- blockrec = br;
-
- memcpy(&blockrec->header, &rep, SIZEOF(fsGenericReply));
-
- /* go read it, and if we're done, wake up the appropriate client */
- switch (blockrec->type) {
- case FS_OPEN_FONT:
- err = fs_do_open_font(fpe, blockrec, FALSE);
- break;
- case FS_LOAD_GLYPHS:
- err = fs_read_glyphs(fpe, blockrec);
- break;
- case FS_LIST_FONTS:
- err = fs_read_list(fpe, blockrec);
- break;
- case FS_LIST_WITH_INFO:
- err = fs_read_list_info(fpe, blockrec);
- break;
- default:
- break;
- }
-
- if (err != StillWorking) {
- while (blockrec) {
- ClientSignal(blockrec->client);
- blockrec = blockrec->depending;
}
}
- /*
- * Xx we could loop here and eat any additional replies, but it should
- * feel more responsive for other clients if we come back later
- */
- } else if (awaiting_reconnect) {
- _fs_try_reconnect();
}
+#endif
return FALSE;
}
/*
- * Reconnection code
+ * Notice a dead connection and prepare for reconnect
*/
void
-_fs_connection_died(conn)
- FSFpePtr conn;
+_fs_connection_died(FSFpePtr conn)
{
- if (!conn->attemptReconnect)
+ if (conn->blockState & FS_BROKEN_CONNECTION)
return;
- conn->attemptReconnect = FALSE;
fs_close_conn(conn);
- conn->time_to_try = time((Time_t *) 0) + FS_RECONNECT_WAIT;
- conn->reconnect_delay = FS_RECONNECT_WAIT;
- conn->fs_fd = -1;
- conn->trans_conn = NULL;
- conn->next_reconnect = awaiting_reconnect;
- awaiting_reconnect = conn;
+ conn->brokenConnectionTime = GetTimeInMillis ();
+ _fs_mark_block (conn, FS_BROKEN_CONNECTION);
+ _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE|FS_RECONNECTING);
}
+/*
+ * Signal clients that the connection has come back up
+ */
static int
-_fs_restart_connection(conn)
- FSFpePtr conn;
+_fs_restart_connection(FSFpePtr conn)
{
FSBlockDataPtr block;
- conn->current_seq = 0;
- FD_SET(conn->fs_fd, &_fs_fd_mask);
- if (!fs_send_init_packets(conn))
- return FALSE;
- while (block = (FSBlockDataPtr) conn->blocked_requests) {
- ClientSignal(block->client);
- fs_abort_blockrec(conn, block);
+ _fs_unmark_block (conn, FS_GIVE_UP);
+ while ((block = (FSBlockDataPtr) conn->blockedRequests))
+ {
+ if (block->errcode == StillWorking)
+ {
+ ClientSignal(block->client);
+ fs_abort_blockrec(conn, block);
+ }
}
return TRUE;
}
+/*
+ * Declare this font server connection useless
+ */
static void
-_fs_try_reconnect()
-{
- FSFpePtr conn,
- *prev;
- Time_t now;
-
- prev = &awaiting_reconnect;
- now = time((Time_t *) 0);
- while (conn = *prev) {
- if (now - conn->time_to_try > 0) {
- if (_fs_reopen_server(conn) && _fs_restart_connection(conn)) {
- conn->attemptReconnect = TRUE;
- *prev = conn->next_reconnect;
- if (prev == &awaiting_reconnect) continue;
- } else {
- if (conn->reconnect_delay < FS_MAX_RECONNECT_WAIT)
- conn->reconnect_delay *= 2;
- now = time((Time_t *) 0);
- conn->time_to_try = now + conn->reconnect_delay;
- }
+_fs_giveup (FSFpePtr conn)
+{
+ FSBlockDataPtr block;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return;
+#ifdef DEBUG
+ fprintf (stderr, "give up on FS \"%s\"\n", conn->servername);
+#endif
+ _fs_mark_block (conn, FS_GIVE_UP);
+ while ((block = (FSBlockDataPtr) conn->blockedRequests))
+ {
+ if (block->errcode == StillWorking)
+ {
+ ClientSignal (block->client);
+ fs_abort_blockrec (conn, block);
+ }
+ }
+ if (conn->fs_fd >= 0)
+ _fs_connection_died (conn);
+}
+
+static void
+_fs_do_blocked (FSFpePtr conn)
+{
+ CARD32 now;
+
+ now = GetTimeInMillis ();
+ if ((conn->blockState & FS_PENDING_REPLY) &&
+ TimeCmp (conn->blockedReplyTime, <=, now))
+ {
+ _fs_giveup (conn);
+ }
+ else
+ {
+ if (conn->blockState & FS_BROKEN_CONNECTION)
+ {
+ /* Try to reconnect broken connections */
+ if (TimeCmp (conn->brokenConnectionTime, <=, now))
+ _fs_start_reconnect (conn);
+ }
+ else if (conn->blockState & FS_BROKEN_WRITE)
+ {
+ /* Try to flush blocked connections */
+ if (TimeCmp (conn->brokenWriteTime, <=, now))
+ _fs_flush (conn);
}
- prev = &conn->next_reconnect;
}
}
@@ -1366,50 +1488,50 @@ _fs_try_reconnect()
*/
/* ARGSUSED */
static int
-fs_send_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont)
- pointer client;
- FontPathElementPtr fpe;
- Mask flags;
- char *name;
- int namelen;
- fsBitmapFormat format;
- fsBitmapFormatMask fmask;
- XID id;
- FontPtr *ppfont;
-{
- FontPtr newfont;
- FSBlockDataPtr blockrec = NULL;
- FSBlockedFontPtr blockedfont;
- FSFontDataPtr fsd;
- FSFontPtr fsfont;
- FSFpePtr conn;
- fsOpenBitmapFontReq openreq;
- int err = Suspended;
- XID newid;
- unsigned char buf[1024];
- char *fontname;
-
+fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FontPtr font;
+ FSBlockDataPtr blockrec = NULL;
+ FSBlockedFontPtr bfont;
+ FSFontDataPtr fsd;
+ FSFontPtr fsfont;
+ fsOpenBitmapFontReq openreq;
+ fsQueryXInfoReq inforeq;
+ fsQueryXExtents16Req extreq;
+ int err;
+ unsigned char buf[1024];
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
+
+ if (namelen > sizeof (buf) - 1)
+ return BadFontName;
+
+ /*
+ * Get the font structure put together, either by reusing
+ * the existing one or creating a new one
+ */
if (flags & FontReopen)
{
- Atom nameatom, fn = None;
- int i;
+ Atom nameatom, fn = None;
+ int i;
- newfont = *ppfont;
- fsd = (FSFontDataPtr)newfont->fpePrivate;
- fsfont = (FSFontPtr)newfont->fontPrivate;
- fpe = newfont->fpe;
- format = fsd->format;
- fmask = fsd->fmask;
- newid = fsd->fontid;
+ font = *ppfont;
+ fsd = (FSFontDataPtr)font->fpePrivate;
+ fsfont = (FSFontPtr)font->fontPrivate;
/* This is an attempt to reopen a font. Did the font have a
NAME property? */
if ((nameatom = MakeAtom("FONT", 4, 0)) != None)
{
- for (i = 0; i < newfont->info.nprops; i++)
- if (newfont->info.props[i].name == nameatom &&
- newfont->info.isStringProp[i])
+ for (i = 0; i < font->info.nprops; i++)
+ if (font->info.props[i].name == nameatom &&
+ font->info.isStringProp[i])
{
- fn = newfont->info.props[i].value;
+ fn = font->info.props[i].value;
break;
}
}
@@ -1421,195 +1543,127 @@ fs_send_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont)
else
namelen = strlen(name);
}
-
- conn = (FSFpePtr) fpe->private;
- if (namelen > sizeof (buf) - 1)
- return BadFontName;
- _fs_client_access (conn, client, (flags & FontOpenSync) != 0);
- _fs_client_resolution(conn);
-
-
- if (!(flags & FontReopen))
+ else
{
-
- newid = GetNewFontClientID();
-
- /* make the font */
- newfont = (FontPtr) xalloc(sizeof(FontRec));
-
- /* and the FS data */
- fsd = (FSFontDataPtr) xalloc(sizeof(FSFontDataRec));
-
- fsfont = (FSFontPtr) xalloc(sizeof(FSFontRec));
-
- fontname = (char *)xalloc(namelen);
-
- if (!newfont || !fsd || !fsfont || !fontname) {
-lowmem:
- if (!(flags & FontReopen))
- {
- xfree((char *) newfont);
- xfree((char *) fsd);
- xfree((char *) fsfont);
- xfree((char *) fontname);
- }
- if (blockrec) fs_abort_blockrec(conn, blockrec);
+ font = fs_create_font (fpe, name, namelen, format, fmask);
+ if (!font)
return AllocError;
- }
- bzero((char *) newfont, sizeof(FontRec));
- bzero((char *) fsfont, sizeof(FSFontRec));
- bzero((char *) fsd, sizeof(FSFontDataRec));
+
+ fsd = (FSFontDataPtr)font->fpePrivate;
+ fsfont = (FSFontPtr)font->fontPrivate;
}
-
+
/* make a new block record, and add it to the end of the list */
- blockrec = fs_new_block_rec(fpe, client, FS_OPEN_FONT);
- if (!blockrec) {
- goto lowmem;
- }
-
- if (!(flags & FontReopen))
- {
- int bit, byte, scan, glyph;
-
- newfont->refcnt = 0;
- newfont->maxPrivate = -1;
- newfont->devPrivates = (pointer *) 0;
- newfont->format = format;
-
- /* These font components will be needed in packGlyphs */
- CheckFSFormat(format, BitmapFormatMaskBit |
- BitmapFormatMaskByte |
- BitmapFormatMaskScanLineUnit |
- BitmapFormatMaskScanLinePad,
- &bit,
- &byte,
- &scan,
- &glyph,
- NULL);
- newfont->bit = bit;
- newfont->byte = byte;
- newfont->scan = scan;
- newfont->glyph = glyph;
-
- newfont->fpe = fpe;
- newfont->fpePrivate = (pointer) fsd;
- newfont->fontPrivate = (pointer) fsfont;
- _fs_init_font(newfont);
-
- fsd->fpe = fpe;
- fsd->name = fontname;
- fsd->namelen = namelen;
- memcpy(fontname, name, namelen);
- fsd->format = format;
- fsd->fmask = fmask;
- }
- fsd->fontid = newid;
+ blockrec = fs_new_block_rec(font->fpe, client, FS_OPEN_FONT);
+ if (!blockrec)
+ {
+ if (!(flags & FontReopen))
+ (*font->unload_font) (font);
+ return AllocError;
+ }
+
+ /*
+ * Must check this before generating any protocol, otherwise we'll
+ * mess up a reconnect in progress
+ */
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
fsd->generation = conn->generation;
- blockedfont = (FSBlockedFontPtr) blockrec->data;
- blockedfont->fontid = newid;
- blockedfont->pfont = newfont;
- blockedfont->state = FS_OPEN_REPLY;
- blockedfont->flags = flags;
- blockedfont->format = format;
- blockedfont->clients_depending = (FSClientsDependingPtr)0;
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ bfont->fontid = fsd->fontid;
+ bfont->pfont = font;
+ bfont->state = FS_OPEN_REPLY;
+ bfont->flags = flags;
+ bfont->format = fsd->format;
+ bfont->clients_depending = (FSClientsDependingPtr)0;
+ bfont->freeFont = (flags & FontReopen) == 0;
+
+ _fs_client_access (conn, client, (flags & FontOpenSync) != 0);
+ _fs_client_resolution(conn);
- /* save the ID */
- if (!StoreFontClientFont(blockedfont->pfont, blockedfont->fontid)) {
- goto lowmem;
- }
/* do an FS_OpenFont, FS_QueryXInfo and FS_QueryXExtents */
buf[0] = (unsigned char) namelen;
memcpy(&buf[1], name, namelen);
- namelen++;
openreq.reqType = FS_OpenBitmapFont;
- openreq.fid = newid;
- openreq.format_hint = format;
- openreq.format_mask = fmask;
- openreq.length = (SIZEOF(fsOpenBitmapFontReq) + namelen + 3) >> 2;
+ openreq.fid = fsd->fontid;
+ openreq.format_hint = fsd->format;
+ openreq.format_mask = fsd->fmask;
+ openreq.length = (SIZEOF(fsOpenBitmapFontReq) + namelen + 4) >> 2;
_fs_add_req_log(conn, FS_OpenBitmapFont);
_fs_write(conn, (char *) &openreq, SIZEOF(fsOpenBitmapFontReq));
- _fs_write_pad(conn, (char *) buf, namelen);
+ _fs_write_pad(conn, (char *) buf, namelen + 1);
+
+ blockrec->sequenceNumber = conn->current_seq;
+
+ inforeq.reqType = FS_QueryXInfo;
+ inforeq.id = fsd->fontid;
+ inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2;
+ bfont->queryInfoSequence = conn->current_seq + 1;
+
+ _fs_add_req_log(conn, FS_QueryXInfo);
+ _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq));
+
+ if (!(bfont->flags & FontReopen))
+ {
+ extreq.reqType = FS_QueryXExtents16;
+ extreq.range = fsTrue;
+ extreq.fid = fsd->fontid;
+ extreq.num_ranges = 0;
+ extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2;
+
+ bfont->queryExtentsSequence = conn->current_seq + 1;
+
+ _fs_add_req_log(conn, FS_QueryXExtents16);
+ _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req));
+ }
+
#ifdef NCD
- if (configData.ExtendedFontDiags) {
+ if (configData.ExtendedFontDiags)
+ {
memcpy(buf, name, MIN(256, namelen));
buf[MIN(256, namelen)] = '\0';
printf("Requesting font \"%s\" from font server \"%s\"\n",
- buf, fpe->name);
+ buf, font->fpe->name);
}
#endif
-
- if (flags & FontOpenSync) {
- err = fs_do_open_font(fpe, blockrec, TRUE);
- if (blockedfont->errcode == Successful) {
- *ppfont = blockedfont->pfont;
- } else {
- _fs_cleanup_font(blockedfont);
+ _fs_prepare_for_reply (conn);
+
+ err = blockrec->errcode;
+ if (bfont->flags & FontOpenSync)
+ {
+ while (blockrec->errcode == StillWorking)
+ {
+ if (fs_await_reply (conn) != FSIO_READY)
+ {
+ blockrec->errcode = BadFontName;
+ break;
+ }
+ fs_read_reply (font->fpe, client);
}
- _fs_remove_block_rec(conn, blockrec);
+ err = blockrec->errcode;
+ if (err == Successful)
+ *ppfont = bfont->pfont;
+ else
+ fs_cleanup_bfont (bfont);
+ bfont->freeFont = FALSE;
+ _fs_remove_block_rec (conn, blockrec);
}
- return err;
-}
-
-static int
-fs_send_query_info(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
-{
- FSBlockedFontPtr bfont;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsQueryXInfoReq inforeq;
-
- bfont = (FSBlockedFontPtr) blockrec->data;
-
- inforeq.reqType = FS_QueryXInfo;
- inforeq.id = bfont->fontid;
- inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2;
-
- blockrec->sequence_number = conn->current_seq;
- _fs_add_req_log(conn, FS_QueryXInfo);
- _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq));
-
- return Successful;
+ return err == StillWorking ? Suspended : err;
}
-static int
-fs_send_query_extents(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
-{
- FSBlockedFontPtr bfont;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsQueryXExtents16Req extreq;
-
- bfont = (FSBlockedFontPtr) blockrec->data;
-
- extreq.reqType = FS_QueryXExtents16;
- extreq.range = fsTrue;
- extreq.fid = bfont->fontid;
- extreq.num_ranges = 0;
- extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2;
-
- blockrec->sequence_number = conn->current_seq;
- _fs_add_req_log(conn, FS_QueryXExtents16);
- _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req));
-
- return Successful;
-}
-
-static int
-fs_send_query_bitmaps(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+static void
+fs_send_query_bitmaps(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedFontPtr bfont;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsQueryXBitmaps16Req bitreq;
-
-
- bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ fsQueryXBitmaps16Req bitreq;
/* send the request */
bitreq.reqType = FS_QueryXBitmaps16;
@@ -1619,55 +1673,45 @@ fs_send_query_bitmaps(fpe, blockrec)
bitreq.length = SIZEOF(fsQueryXBitmaps16Req) >> 2;
bitreq.num_ranges = 0;
- blockrec->sequence_number = conn->current_seq;
+ bfont->queryBitmapsSequence = conn->current_seq + 1;
+
_fs_add_req_log(conn, FS_QueryXBitmaps16);
_fs_write(conn, (char *) &bitreq, SIZEOF(fsQueryXBitmaps16Req));
-
- return Successful;
}
/* ARGSUSED */
static int
-fs_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont,
- alias, non_cachable_font)
- pointer client;
- FontPathElementPtr fpe;
- Mask flags;
- char *name;
- fsBitmapFormat format;
- fsBitmapFormatMask fmask;
- int namelen;
- XID id;
- FontPtr *ppfont;
- char **alias;
- FontPtr non_cachable_font; /* Not used in this FPE */
+fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont,
+ char **alias, FontPtr non_cachable_font)
{
- FSFpePtr conn = (FSFpePtr) fpe->private;
- FSBlockDataPtr blockrec;
- FSBlockedFontPtr blockedfont;
- int err;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
+ int err;
/* libfont interface expects ImageRectMin glyphs */
- format = format & ~BitmapFormatImageRectMask | BitmapFormatImageRectMin;
+ format = (format & ~BitmapFormatImageRectMask) | BitmapFormatImageRectMin;
*alias = (char *) 0;
- /* XX if we find the blockrec for the font */
- blockrec = (FSBlockDataPtr) conn->blocked_requests;
- while (blockrec != (FSBlockDataPtr) 0) {
- if (blockrec->type == FS_OPEN_FONT &&
- blockrec->client == client) {
- blockedfont = (FSBlockedFontPtr) blockrec->data;
- err = blockedfont->errcode;
- if (err == Successful) {
- *ppfont = blockedfont->pfont;
- } else {
- _fs_cleanup_font(blockedfont);
- }
- /* cleanup */
- _fs_remove_block_rec(conn, blockrec);
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_OPEN_FONT && blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ if (err == Successful)
+ *ppfont = bfont->pfont;
+ else
+ fs_cleanup_bfont (bfont);
+ _fs_remove_block_rec (conn, blockrec);
return err;
}
- blockrec = blockrec->next;
}
return fs_send_open_font(client, fpe, flags, name, namelen, format, fmask,
id, ppfont);
@@ -1675,13 +1719,13 @@ fs_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont,
/* ARGSUSED */
static int
-fs_send_close_font(fpe, id)
- FontPathElementPtr fpe;
- Font id;
+fs_send_close_font(FontPathElementPtr fpe, Font id)
{
FSFpePtr conn = (FSFpePtr) fpe->private;
fsCloseReq req;
+ if (conn->blockState & FS_GIVE_UP)
+ return Successful;
/* tell the font server to close the font */
req.reqType = FS_CloseFont;
req.length = SIZEOF(fsCloseReq) >> 2;
@@ -1693,110 +1737,83 @@ fs_send_close_font(fpe, id)
}
/* ARGSUSED */
-static int
-fs_close_font(fpe, pfont)
- FontPathElementPtr fpe;
- FontPtr pfont;
+static void
+fs_close_font(FontPathElementPtr fpe, FontPtr pfont)
{
- FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate;
- FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
- /* XXX we may get called after the resource DB has been cleaned out */
- if (find_old_font(fsd->fontid))
- DeleteFontClientID(fsd->fontid);
if (conn->generation == fsd->generation)
fs_send_close_font(fpe, fsd->fontid);
- (*pfont->unload_font) (pfont);
-
-
- xfree(fsd->name);
- xfree(fsd);
- xfree(pfont->info.isStringProp);
- xfree(pfont->info.props);
- xfree(pfont->devPrivates);
- xfree(pfont);
+#ifdef DEBUG
+ {
+ FSBlockDataPtr blockrec;
+ FSBlockedFontPtr bfont;
- return Successful;
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_OPEN_FONT)
+ {
+ bfont = (FSBlockedFontPtr) blockrec->data;
+ if (bfont->pfont == pfont)
+ fprintf (stderr, "closing font which hasn't been opened\n");
+ }
+ }
+ }
+#endif
+ (*pfont->unload_font) (pfont);
}
static int
-fs_read_glyphs(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr) blockrec->data;
- FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- FontPtr pfont = bglyph->pfont; /* works for either blocked font
+ FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr) blockrec->data;
+ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FontPtr pfont = bglyph->pfont;
+ /* works for either blocked font
or glyph rec... pfont is at
the very beginning of both
blockrec->data structures */
- FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
- FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
- FontInfoPtr pfi = &pfont->info;
- fsQueryXBitmaps16Reply rep;
- fsOffset32 *ppbits;
- fsOffset32 local_off;
- char *off_adr;
- pointer pbitmaps;
- char *bits;
- int glyph_size,
- offset_size,
- i,
- err;
- int nranges = 0;
- fsRange *ranges, *nextrange;
- unsigned long minchar, maxchar;
-
- /* get reply header */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
- if (rep.type == FS_Error) {
-/* XXX -- translate FS error */
- _fs_eat_rest_of_error(conn, (fsError *) & rep);
- err = AllocError;
- goto bail;
- }
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsQueryXBitmaps16Reply) - SIZEOF(fsGenericReply)) == -1) {
- if (blockrec->type == FS_OPEN_FONT)
- fs_free_font(bfont);
- return StillWorking;
- }
- /* allocate space for glyphs */
- offset_size = SIZEOF(fsOffset32) * (rep.num_chars);
- glyph_size = (rep.length << 2) - SIZEOF(fsQueryXBitmaps16Reply)
- - offset_size;
- ppbits = (fsOffset32 *) xalloc(offset_size);
- pbitmaps = (pointer) xalloc(glyph_size);
- if (glyph_size && !pbitmaps || !ppbits)
+ FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
+ FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate;
+ FontInfoPtr pfi = &pfont->info;
+ fsQueryXBitmaps16Reply *rep;
+ char *buf;
+ fsOffset32 *ppbits;
+ fsOffset32 local_off;
+ char *off_adr;
+ pointer pbitmaps;
+ char *bits, *allbits;
+#ifdef DEBUG
+ char *origallbits;
+#endif
+ int i,
+ err;
+ int nranges = 0;
+ int ret;
+ fsRange *ranges, *nextrange = 0;
+ unsigned long minchar, maxchar;
+
+ rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
{
- xfree(pbitmaps);
- xfree(ppbits);
-
- /* clear wire */
- (void) _fs_drain_bytes_pad(conn, offset_size);
- (void) _fs_drain_bytes_pad(conn, glyph_size);
-
- if (blockrec->type == FS_OPEN_FONT)
- _fs_cleanup_font(bfont);
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
err = AllocError;
goto bail;
}
- /* read offsets */
- if (_fs_read_pad(conn, (char *) ppbits, offset_size) == -1) {
- if (blockrec->type == FS_OPEN_FONT)
- fs_free_font(bfont);
- return StillWorking;
- }
+ buf = (char *) rep;
+ buf += SIZEOF (fsQueryXBitmaps16Reply);
- /* read glyphs */
- if (_fs_read_pad(conn, (char *) pbitmaps, glyph_size) == -1) {
- if (blockrec->type == FS_OPEN_FONT)
- fs_free_font(bfont);
- return StillWorking;
- }
+ ppbits = (fsOffset32 *) buf;
+ buf += SIZEOF (fsOffset32) * (rep->num_chars);
+
+ pbitmaps = (pointer ) buf;
if (blockrec->type == FS_LOAD_GLYPHS)
{
@@ -1822,31 +1839,47 @@ fs_read_glyphs(fpe, blockrec)
else
{
minchar = 0;
- maxchar = rep.num_chars;
+ maxchar = rep->num_chars;
}
off_adr = (char *)ppbits;
- for (i = 0; i < rep.num_chars; i++)
+
+ allbits = fs_alloc_glyphs (pfont, rep->nbytes);
+
+ if (!allbits)
+ {
+ err = AllocError;
+ goto bail;
+ }
+
+#ifdef DEBUG
+ origallbits = allbits;
+ fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n",
+ (int) rep->num_chars, (int) rep->nbytes, fsd->name);
+#endif
+
+ for (i = 0; i < rep->num_chars; i++)
{
memcpy(&local_off, off_adr, SIZEOF(fsOffset32)); /* align it */
if (blockrec->type == FS_OPEN_FONT ||
fsdata->encoding[minchar].bits == &_fs_glyph_requested)
{
- if (local_off.length)
+ /*
+ * Broken X font server returns bits for missing characters
+ * when font is padded
+ */
+ if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
{
- bits = (char *)xalloc(local_off.length);
- if (bits == NULL)
+ if (local_off.length)
{
- xfree(ppbits);
- xfree(pbitmaps);
- err = AllocError;
- goto bail;
+ bits = allbits;
+ allbits += local_off.length;
+ memcpy(bits, (char *)pbitmaps + local_off.position,
+ local_off.length);
}
- memcpy(bits, pbitmaps + local_off.position,
- local_off.length);
+ else
+ bits = &_fs_glyph_zero_length;
}
- else if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics))
- bits = &_fs_glyph_zero_length;
else
bits = 0;
if (fsdata->encoding[minchar].bits == &_fs_glyph_requested)
@@ -1866,9 +1899,10 @@ fs_read_glyphs(fpe, blockrec)
}
off_adr += SIZEOF(fsOffset32);
}
-
- xfree(ppbits);
- xfree(pbitmaps);
+#ifdef DEBUG
+ fprintf (stderr, "Used %d bytes instead of %d\n",
+ (int) (allbits - origallbits), (int) rep->nbytes);
+#endif
if (blockrec->type == FS_OPEN_FONT)
{
@@ -1878,31 +1912,23 @@ fs_read_glyphs(fpe, blockrec)
err = Successful;
bail:
- if (blockrec->type == FS_LOAD_GLYPHS)
- {
- bglyph->done = TRUE;
- bglyph->errcode = err;
- }
-
+ _fs_done_read (conn, rep->length << 2);
return err;
}
-
-
static int
-fs_send_load_glyphs(client, pfont, nranges, ranges)
- pointer client;
- FontPtr pfont;
- int nranges;
- fsRange *ranges;
-{
- FSBlockedGlyphPtr blockedglyph;
- fsQueryXBitmaps16Req req;
- FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate);
- FontPathElementPtr fpe = fsd->fpe;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- FSBlockDataPtr blockrec;
-
+fs_send_load_glyphs(pointer client, FontPtr pfont,
+ int nranges, fsRange *ranges)
+{
+ FontPathElementPtr fpe = pfont->fpe;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedGlyphPtr blockedglyph;
+ fsQueryXBitmaps16Req req;
+ FSBlockDataPtr blockrec;
+
+ if (conn->blockState & FS_GIVE_UP)
+ return BadCharRange;
+
/* make a new block record, and add it to the end of the list */
blockrec = fs_new_block_rec(fpe, client, FS_LOAD_GLYPHS);
if (!blockrec)
@@ -1912,17 +1938,20 @@ fs_send_load_glyphs(client, pfont, nranges, ranges)
blockedglyph->num_expected_ranges = nranges;
/* Assumption: it's our job to free ranges */
blockedglyph->expected_ranges = ranges;
- blockedglyph->done = FALSE;
blockedglyph->clients_depending = (FSClientsDependingPtr)0;
- blockrec->sequence_number = conn->current_seq;
-
+ if (conn->blockState & (FS_BROKEN_CONNECTION|FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
/* send the request */
req.reqType = FS_QueryXBitmaps16;
req.fid = ((FSFontDataPtr) pfont->fpePrivate)->fontid;
req.format = pfont->format;
if (pfont->info.terminalFont)
- req.format = req.format & ~(BitmapFormatImageRectMask) |
+ req.format = (req.format & ~(BitmapFormatImageRectMask)) |
BitmapFormatImageRectMax;
req.range = TRUE;
/* each range takes up 4 bytes */
@@ -1931,6 +1960,8 @@ fs_send_load_glyphs(client, pfont, nranges, ranges)
_fs_add_req_log(conn, FS_QueryXBitmaps16);
_fs_write(conn, (char *) &req, SIZEOF(fsQueryXBitmaps16Req));
+ blockrec->sequenceNumber = conn->current_seq;
+
/* Send ranges to the server... pack into a char array by hand
to avoid structure-packing portability problems and to
handle swapping for version1 protocol */
@@ -1970,19 +2001,20 @@ fs_send_load_glyphs(client, pfont, nranges, ranges)
_fs_write(conn, range_buffer, i * 4);
}
+ _fs_prepare_for_reply (conn);
return Suspended;
}
+extern pointer serverClient; /* This could be any number that
+ doesn't conflict with existing
+ client values. */
+
int
-fs_load_all_glyphs(pfont)
- FontPtr pfont;
+fs_load_all_glyphs(FontPtr pfont)
{
- extern pointer serverClient; /* This could be any number that
- doesn't conflict with existing
- client values. */
- int err;
- FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
+ int err;
+ FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
/*
* The purpose of this procedure is to load all glyphs in the event
@@ -1999,67 +2031,49 @@ fs_load_all_glyphs(pfont)
while ((err = _fs_load_glyphs(serverClient, pfont, TRUE, 0, 0, NULL)) ==
Suspended)
{
- fd_set TempSelectMask;
-
- FD_ZERO (&TempSelectMask);
-
- if (_fs_wait_for_readable(conn) == -1)
+ if (fs_await_reply (conn) != FSIO_READY)
{
- /* We lost our connection. Don't wait to reestablish it;
- just give up. */
- _fs_connection_died(conn);
-
/* Get rid of blockrec */
fs_client_died(serverClient, pfont->fpe);
-
- return BadCharRange; /* As good an error as any other */
+ err = BadCharRange;
+ break;
}
- FD_SET(conn->fs_fd, &TempSelectMask);
- fs_wakeup(pfont->fpe, &TempSelectMask);
+ fs_read_reply (pfont->fpe, serverClient);
}
-
return err;
}
int
-_fs_load_glyphs(client, pfont, range_flag, nchars, item_size, data)
- pointer client;
- FontPtr pfont;
- Bool range_flag;
- unsigned int nchars;
- int item_size;
- unsigned char *data;
-{
-
- int nranges = 0;
- fsRange *ranges = NULL;
- int res;
- FSBlockDataPtr blockrec;
- FSBlockedGlyphPtr blockedglyph;
- FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
- FSClientsDependingPtr *clients_depending = NULL;
+_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag,
+ unsigned int nchars, int item_size, unsigned char *data)
+{
+ FSFpePtr conn = (FSFpePtr) pfont->fpe->private;
+ int nranges = 0;
+ fsRange *ranges = NULL;
+ int res;
+ FSBlockDataPtr blockrec;
+ FSBlockedGlyphPtr blockedglyph;
+ FSClientsDependingPtr *clients_depending = NULL;
+ int err;
/* see if the result is already there */
-
- blockrec = (FSBlockDataPtr) conn->blocked_requests;
- while (blockrec) {
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
if (blockrec->type == FS_LOAD_GLYPHS)
{
blockedglyph = (FSBlockedGlyphPtr) blockrec->data;
if (blockedglyph->pfont == pfont)
{
+ /* Look for this request */
if (blockrec->client == client)
{
- if (blockedglyph->done)
- {
- int errcode = blockedglyph->errcode;
- signal_clients_depending(&blockedglyph->
- clients_depending);
- _fs_remove_block_rec(conn, blockrec);
- return errcode;
- }
- else return Suspended;
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+ _fs_signal_clients_depending(&blockedglyph->clients_depending);
+ _fs_remove_block_rec(conn, blockrec);
+ return err;
}
/* We've found an existing LoadGlyphs blockrec for this
font but for another client. Rather than build a
@@ -2077,17 +2091,22 @@ _fs_load_glyphs(client, pfont, range_flag, nchars, item_size, data)
bfont = (FSBlockedFontPtr) blockrec->data;
if (bfont->pfont == pfont)
{
+ /*
+ * An OpenFont is pending for this font, this must
+ * be from a reopen attempt, so finish the open
+ * attempt and retry the LoadGlyphs
+ */
if (blockrec->client == client)
{
- if (bfont->state == FS_DONE_REPLY)
- {
- int errcode = bfont->errcode;
- signal_clients_depending(&bfont->clients_depending);
- _fs_remove_block_rec(conn, blockrec);
- if (errcode == Successful) break;
- else return errcode;
- }
- else return Suspended;
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
+
+ _fs_signal_clients_depending(&bfont->clients_depending);
+ _fs_remove_block_rec(conn, blockrec);
+ if (err != Successful)
+ return err;
+ break;
}
/* We've found an existing OpenFont blockrec for this
font but for another client. Rather than build a
@@ -2095,15 +2114,13 @@ _fs_load_glyphs(client, pfont, range_flag, nchars, item_size, data)
maintenance), we'll add it to a queue of clients to
be signalled when the existing OpenFont is
completed. */
- if (bfont->state != FS_DONE_REPLY)
+ if (blockrec->errcode == StillWorking)
{
clients_depending = &bfont->clients_depending;
break;
}
}
}
-
- blockrec = blockrec->next;
}
/*
@@ -2139,7 +2156,7 @@ _fs_load_glyphs(client, pfont, range_flag, nchars, item_size, data)
_fs_clean_aborted_loadglyphs(pfont, nranges, ranges);
xfree(ranges);
}
- return add_clients_depending(clients_depending, client);
+ return _fs_add_clients_depending(clients_depending, client);
}
/*
@@ -2177,87 +2194,70 @@ _fs_load_glyphs(client, pfont, range_flag, nchars, item_size, data)
return fs_send_load_glyphs(client, pfont, nranges, ranges);
}
-
-
static int
-fs_read_list(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedListPtr blist = (FSBlockedListPtr) blockrec->data;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsListFontsReply rep;
- char *data,
- *dp;
- int length,
- i;
-
- blist->done = TRUE;
-
- /* read reply header */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
- if (rep.type == FS_Error) {
-/* XXX -- translate FS error */
- _fs_eat_rest_of_error(conn, (fsError *) & rep);
- return AllocError;
- }
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsListFontsReply) - SIZEOF(fsGenericReply)) == -1) {
- /* nothing to free (i think) */
- return StillWorking;
- }
- length = (rep.length << 2) - SIZEOF(fsListFontsReply);
- data = (char *) xalloc(length);
- if (!data) {
- _fs_drain_bytes_pad(conn, length);
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockedListPtr blist = (FSBlockedListPtr) blockrec->data;
+ fsListFontsReply *rep;
+ char *data;
+ int length,
+ i,
+ ret;
+ int err;
+
+ rep = (fsListFontsReply *) fs_get_reply (conn, &ret);
+ if (!rep || rep->type == FS_Error)
+ {
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ if (rep)
+ _fs_done_read (conn, rep->length << 2);
return AllocError;
}
- /* read the list */
- if (_fs_read_pad(conn, data, length) == -1) {
- /* nothing to free (i think) */
- return StillWorking;
- }
+ data = (char *) rep + SIZEOF (fsListFontsReply);
+
+ err = Successful;
/* copy data into FontPathRecord */
- dp = data;
- for (i = 0; i < rep.nFonts; i++) {
- length = *(unsigned char *)dp++;
- if (AddFontNamesName(blist->names, dp, length) != Successful) {
- blist->errcode = AllocError;
+ for (i = 0; i < rep->nFonts; i++)
+ {
+ length = *(unsigned char *)data++;
+ err = AddFontNamesName(blist->names, data, length);
+ if (err != Successful)
break;
- }
- dp += length;
+ data += length;
}
-
- xfree(data);
- return Successful;
+ _fs_done_read (conn, rep->length << 2);
+ return err;
}
static int
-fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
- pointer client;
- FontPathElementPtr fpe;
- char *pattern;
- int patlen;
- int maxnames;
- FontNamesPtr newnames;
-{
- FSBlockDataPtr blockrec;
- FSBlockedListPtr blockedlist;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsListFontsReq req;
-
- _fs_client_access (conn, client, FALSE);
- _fs_client_resolution(conn);
+fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern,
+ int patlen, int maxnames, FontNamesPtr newnames)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListPtr blockedlist;
+ fsListFontsReq req;
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
+
/* make a new block record, and add it to the end of the list */
blockrec = fs_new_block_rec(fpe, client, FS_LIST_FONTS);
if (!blockrec)
return AllocError;
blockedlist = (FSBlockedListPtr) blockrec->data;
- blockedlist->patlen = patlen;
- blockedlist->errcode = Successful;
blockedlist->names = newnames;
- blockedlist->done = FALSE;
+
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ _fs_client_access (conn, client, FALSE);
+ _fs_client_resolution(conn);
/* send the request */
req.reqType = FS_ListFonts;
@@ -2268,6 +2268,8 @@ fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
_fs_write(conn, (char *) &req, SIZEOF(fsListFontsReq));
_fs_write_pad(conn, (char *) pattern, patlen);
+ blockrec->sequenceNumber = conn->current_seq;
+
#ifdef NCD
if (configData.ExtendedFontDiags) {
char buf[256];
@@ -2279,198 +2281,155 @@ fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
}
#endif
+ _fs_prepare_for_reply (conn);
return Suspended;
}
static int
-fs_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
- pointer client;
- FontPathElementPtr fpe;
- char *pattern;
- int patlen;
- int maxnames;
- FontNamesPtr newnames;
-{
- FSBlockDataPtr blockrec;
- FSBlockedListPtr blockedlist;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- int err;
+fs_list_fonts(pointer client, FontPathElementPtr fpe,
+ char *pattern, int patlen, int maxnames, FontNamesPtr newnames)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListPtr blockedlist;
+ int err;
/* see if the result is already there */
- blockrec = (FSBlockDataPtr) conn->blocked_requests;
- while (blockrec) {
- if (blockrec->type == FS_LIST_FONTS && blockrec->client == client) {
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ {
+ if (blockrec->type == FS_LIST_FONTS && blockrec->client == client)
+ {
+ err = blockrec->errcode;
+ if (err == StillWorking)
+ return Suspended;
blockedlist = (FSBlockedListPtr) blockrec->data;
- if (blockedlist->patlen == patlen && blockedlist->done) {
- err = blockedlist->errcode;
- _fs_remove_block_rec(conn, blockrec);
- return err;
- }
+ _fs_remove_block_rec(conn, blockrec);
+ return err;
}
- blockrec = blockrec->next;
}
/* didn't find waiting record, so send a new one */
return fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames);
}
-static int padlength[4] = {0, 3, 2, 1};
-
+/*
+ * Read a single list info reply and restart for the next reply
+ */
static int
-fs_read_list_info(fpe, blockrec)
- FontPathElementPtr fpe;
- FSBlockDataPtr blockrec;
+fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec)
{
- FSBlockedListInfoPtr binfo = (FSBlockedListInfoPtr) blockrec->data;
- fsListFontsWithXInfoReply rep;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- fsPropInfo pi;
- fsPropOffset *po;
- char *name;
- pointer pd;
- int err;
+ FSBlockedListInfoPtr binfo = (FSBlockedListInfoPtr) blockrec->data;
+ fsListFontsWithXInfoReply *rep;
+ char *buf;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ fsPropInfo *pi;
+ fsPropOffset *po;
+ pointer pd;
+ int ret;
+ int err;
/* clean up anything from the last trip */
- if (binfo->name)
- {
- xfree(binfo->name);
- binfo->name = NULL;
- }
- if (binfo->pfi) {
- xfree(binfo->pfi->isStringProp);
- xfree(binfo->pfi->props);
- xfree(binfo->pfi);
- binfo->pfi = NULL;
- }
- /* get reply header */
- memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply));
- if (rep.type == FS_Error) {
-/* XXX -- translate FS error */
- _fs_eat_rest_of_error(conn, (fsError *) & rep);
- binfo->errcode = AllocError;
- return AllocError;
- }
- if (conn->fsMajorVersion > 1)
- if (rep.nameLength == 0)
- goto done;
- /* old protocol sent a full-length reply even for the last one */
- if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply),
- SIZEOF(fsListFontsWithXInfoReply) - SIZEOF(fsGenericReply)) == -1) {
- goto done;
- }
- if (rep.nameLength == 0)
- goto done;
+ _fs_free_props (&binfo->info);
- /* read the data */
- name = (char *) xalloc(rep.nameLength);
- binfo->pfi = (FontInfoPtr) xalloc(sizeof(FontInfoRec));
- if (!name || !binfo->pfi) {
- xfree(name);
- xfree(binfo->pfi);
- binfo->pfi = NULL;
- _fs_drain_bytes(conn,
- rep.length - (SIZEOF(fsListFontsWithXInfoReply) -
- SIZEOF(fsGenericReply)));
- binfo->errcode = AllocError;
- return AllocError;
- }
- if (conn->fsMajorVersion == 1)
- if (_fs_read_pad(conn, name, rep.nameLength) == -1)
- goto done;
- if (_fs_read_pad(conn, (char *) &pi, SIZEOF(fsPropInfo)) == -1)
- goto done;
-
- po = (fsPropOffset *) xalloc(SIZEOF(fsPropOffset) * pi.num_offsets);
- pd = (pointer) xalloc(pi.data_len);
- if (!po || !pd) {
- xfree(name);
- xfree(po);
- xfree(pd);
- xfree (binfo->pfi);
- binfo->pfi = NULL;
- binfo->errcode = AllocError;
- return AllocError;
- }
- err = _fs_read_pad(conn, (char *) po,
- (pi.num_offsets * SIZEOF(fsPropOffset)));
- if (err != -1)
+ rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret);
+ if (rep == 0)
{
- if (conn->fsMajorVersion > 1)
- err = _fs_read(conn, (char *) pd, pi.data_len);
- else
- err = _fs_read_pad(conn, (char *) pd, pi.data_len);
+ if (ret == FSIO_BLOCK)
+ return StillWorking;
+ binfo->status = FS_LFWI_FINISHED;
+ err = AllocError;
+ goto done;
}
- if (err != -1 && conn->fsMajorVersion != 1)
+ /*
+ * Normal termination -- the list ends with a name of length 0
+ */
+ if (rep->nameLength == 0)
{
- err = _fs_read(conn, name, rep.nameLength);
- if (err != -1)
- err = _fs_drain_bytes(conn, padlength[(pi.data_len+rep.nameLength)&3]);
+#ifdef DEBUG
+ fprintf (stderr, "fs_read_list_info done\n");
+#endif
+ binfo->status = FS_LFWI_FINISHED;
+ err = BadFontName;
+ goto done;
}
- if (err == -1) {
- xfree(name);
- xfree(po);
- xfree(pd);
- xfree (binfo->pfi);
- binfo->pfi = NULL;
- goto done;
+ buf = (char *) rep + SIZEOF (fsListFontsWithXInfoReply);
+
+ /*
+ * The original FS implementation didn't match
+ * the spec, version 1 was respecified to match the FS.
+ * Version 2 matches the original intent
+ */
+ if (conn->fsMajorVersion <= 1)
+ {
+ memcpy (binfo->name, buf, rep->nameLength);
+ buf += _fs_pad_length (rep->nameLength);
+ }
+ pi = (fsPropInfo *) buf;
+ buf += SIZEOF (fsPropInfo);
+ po = (fsPropOffset *) buf;
+ buf += pi->num_offsets * SIZEOF (fsPropOffset);
+ pd = (pointer) buf;
+ buf += pi->data_len;
+ if (conn->fsMajorVersion > 1)
+ {
+ memcpy (binfo->name, buf, rep->nameLength);
+ buf += _fs_pad_length (rep->nameLength);
}
- if (_fs_convert_lfwi_reply(conn, binfo->pfi, &rep, &pi, po, pd) != Successful)
+#ifdef DEBUG
+ binfo->name[rep->nameLength] = '\0';
+ fprintf (stderr, "fs_read_list_info %s\n", binfo->name);
+#endif
+ err = _fs_convert_lfwi_reply(conn, &binfo->info, rep, pi, po, pd);
+ if (err != Successful)
{
- xfree(name);
- xfree(po);
- xfree(pd);
- xfree (binfo->pfi);
- binfo->pfi = NULL;
+ binfo->status = FS_LFWI_FINISHED;
goto done;
}
- xfree(po);
- xfree(pd);
- binfo->name = name;
- binfo->namelen = rep.nameLength;
- binfo->remaining = rep.nReplies;
+ binfo->namelen = rep->nameLength;
+ binfo->remaining = rep->nReplies;
binfo->status = FS_LFWI_REPLY;
- binfo->errcode = Suspended;
+
/* disable this font server until we've processed this response */
+ _fs_unmark_block (conn, FS_COMPLETE_REPLY);
FD_CLR(conn->fs_fd, &_fs_fd_mask);
-
- return Successful;
-
-done:
- binfo->status = FS_LFWI_FINISHED;
- binfo->errcode = BadFontName;
- binfo->name = (char *) 0;
- return Successful;
+done:
+ _fs_done_read (conn, rep->length << 2);
+ return err;
}
/* ARGSUSED */
static int
-fs_start_list_with_info(client, fpe, pattern, len, maxnames, pdata)
- pointer client;
- FontPathElementPtr fpe;
- char *pattern;
- int len;
- int maxnames;
- pointer *pdata;
-{
- FSBlockDataPtr blockrec;
- FSBlockedListInfoPtr blockedinfo;
+fs_start_list_with_info(pointer client, FontPathElementPtr fpe,
+ char *pattern, int len, int maxnames, pointer *pdata)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListInfoPtr binfo;
fsListFontsWithXInfoReq req;
- FSFpePtr conn = (FSFpePtr) fpe->private;
- _fs_client_access (conn, client, FALSE);
- _fs_client_resolution(conn);
+ if (conn->blockState & FS_GIVE_UP)
+ return BadFontName;
/* make a new block record, and add it to the end of the list */
blockrec = fs_new_block_rec(fpe, client, FS_LIST_WITH_INFO);
if (!blockrec)
return AllocError;
- blockedinfo = (FSBlockedListInfoPtr) blockrec->data;
- bzero((char *) blockedinfo, sizeof(FSBlockedListInfoRec));
- blockedinfo->status = FS_LFWI_WAITING;
- blockedinfo->errcode = Suspended;
+
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+ bzero((char *) binfo, sizeof(FSBlockedListInfoRec));
+ binfo->status = FS_LFWI_WAITING;
+
+ if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING))
+ {
+ _fs_pending_reply (conn);
+ return Suspended;
+ }
+
+ _fs_client_access (conn, client, FALSE);
+ _fs_client_resolution(conn);
/* send the request */
req.reqType = FS_ListFontsWithXInfo;
@@ -2481,6 +2440,8 @@ fs_start_list_with_info(client, fpe, pattern, len, maxnames, pdata)
(void) _fs_write(conn, (char *) &req, SIZEOF(fsListFontsWithXInfoReq));
(void) _fs_write_pad(conn, pattern, len);
+ blockrec->sequenceNumber = conn->current_seq;
+
#ifdef NCD
if (configData.ExtendedFontDiags) {
char buf[256];
@@ -2492,35 +2453,26 @@ fs_start_list_with_info(client, fpe, pattern, len, maxnames, pdata)
}
#endif
+ _fs_prepare_for_reply (conn);
return Successful;
}
/* ARGSUSED */
static int
-fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, numFonts,
- private)
- pointer client;
- FontPathElementPtr fpe;
- char **namep;
- int *namelenp;
- FontInfoPtr *pFontInfo;
- int *numFonts;
- pointer private;
-{
- FSBlockDataPtr blockrec;
- FSBlockedListInfoPtr blockedinfo;
- FSFpePtr conn = (FSFpePtr) fpe->private;
+fs_next_list_with_info(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo, int *numFonts,
+ pointer private)
+{
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec;
+ FSBlockedListInfoPtr binfo;
+ int err;
/* see if the result is already there */
- blockrec = (FSBlockDataPtr) conn->blocked_requests;
- while (blockrec) {
- if (blockrec->type == FS_LIST_WITH_INFO &&
- blockrec->client == client) {
- blockedinfo = (FSBlockedListInfoPtr) blockrec->data;
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
+ if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client)
break;
- }
- blockrec = blockrec->next;
- }
if (!blockrec)
{
@@ -2533,26 +2485,35 @@ fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, numFonts,
return BadFontName;
}
- if (blockedinfo->status == FS_LFWI_WAITING)
+ binfo = (FSBlockedListInfoPtr) blockrec->data;
+
+ if (binfo->status == FS_LFWI_WAITING)
return Suspended;
- *namep = blockedinfo->name;
- *namelenp = blockedinfo->namelen;
- *pFontInfo = blockedinfo->pfi;
- *numFonts = blockedinfo->remaining;
+ *namep = binfo->name;
+ *namelenp = binfo->namelen;
+ *pFontInfo = &binfo->info;
+ *numFonts = binfo->remaining;
+
+ /* Restart reply processing from this font server */
FD_SET(conn->fs_fd, &_fs_fd_mask);
- if (blockedinfo->status == FS_LFWI_FINISHED) {
- int err = blockedinfo->errcode;
-
+ if (fs_reply_ready (conn))
+ _fs_mark_block (conn, FS_COMPLETE_REPLY);
+
+ err = blockrec->errcode;
+ switch (binfo->status) {
+ case FS_LFWI_FINISHED:
_fs_remove_block_rec(conn, blockrec);
- return err;
- }
- if (blockedinfo->status == FS_LFWI_REPLY) {
- blockedinfo->status = FS_LFWI_WAITING;
- return Successful;
- } else {
- return blockedinfo->errcode;
+ break;
+ case FS_LFWI_REPLY:
+ binfo->status = FS_LFWI_WAITING;
+ blockrec->errcode = StillWorking;
+ conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout;
+ _fs_mark_block (conn, FS_PENDING_REPLY);
+ break;
}
+
+ return err;
}
/*
@@ -2560,17 +2521,15 @@ fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, numFonts,
*/
static void
-fs_client_died(client, fpe)
- pointer client;
- FontPathElementPtr fpe;
+fs_client_died(pointer client, FontPathElementPtr fpe)
{
- FSFpePtr conn = (FSFpePtr) fpe->private;
- FSBlockDataPtr blockrec,
- depending;
- FSClientPtr *prev, cur;
- fsFreeACReq freeac;
+ FSFpePtr conn = (FSFpePtr) fpe->private;
+ FSBlockDataPtr blockrec,
+ depending;
+ FSClientPtr *prev, cur;
+ fsFreeACReq freeac;
- for (prev = &conn->clients; cur = *prev; prev = &cur->next)
+ for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
{
if (cur->client == client) {
freeac.reqType = FS_FreeAC;
@@ -2583,36 +2542,17 @@ fs_client_died(client, fpe)
break;
}
}
- /* see if the result is already there */
- blockrec = (FSBlockDataPtr) conn->blocked_requests;
- while (blockrec) {
+ /* find a pending requests */
+ for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next)
if (blockrec->client == client)
break;
- blockrec = blockrec->next;
- }
+
if (!blockrec)
return;
- if (blockrec->type == FS_LIST_WITH_INFO)
- {
- FSBlockedListInfoPtr binfo;
- binfo = (FSBlockedListInfoPtr) blockrec->data;
- if (binfo->status == FS_LFWI_REPLY)
- FD_SET(conn->fs_fd, &_fs_fd_mask);
- if (binfo->name)
- {
- xfree(binfo->name);
- binfo->name = NULL;
- }
- if (binfo->pfi)
- {
- xfree(binfo->pfi->isStringProp);
- xfree(binfo->pfi->props);
- xfree(binfo->pfi);
- binfo->pfi = NULL;
- }
- }
+
/* replace the client pointers in this block rec with the chained one */
- if (depending = blockrec->depending) {
+ if ((depending = blockrec->depending))
+ {
blockrec->client = depending->client;
blockrec->depending = depending->depending;
blockrec = depending;
@@ -2621,20 +2561,22 @@ fs_client_died(client, fpe)
}
static void
-_fs_client_access (conn, client, sync)
- FSFpePtr conn;
- pointer client;
- Bool sync;
+_fs_client_access (FSFpePtr conn, pointer client, Bool sync)
{
FSClientPtr *prev, cur;
fsCreateACReq crac;
fsSetAuthorizationReq setac;
- fsGenericReply rep;
char *authorizations;
int authlen;
Bool new_cur = FALSE;
- for (prev = &conn->clients; cur = *prev; prev = &cur->next)
+#ifdef DEBUG
+ if (conn->blockState & (FS_RECONNECTING|FS_BROKEN_CONNECTION))
+ {
+ fprintf (stderr, "Sending requests without a connection\n");
+ }
+#endif
+ for (prev = &conn->clients; (cur = *prev); prev = &cur->next)
{
if (cur->client == client)
{
@@ -2678,15 +2620,6 @@ _fs_client_access (conn, client, sync)
_fs_add_req_log(conn, FS_CreateAC);
_fs_write(conn, (char *) &crac, sizeof (fsCreateACReq));
_fs_write(conn, authorizations, authlen);
- /* if we're synchronous, open_font will be confused by
- * the reply; eat it and continue
- */
- if (sync)
- {
- if (_fs_read(conn, (char *) &rep, sizeof (fsGenericReply)) == -1)
- return;
- fs_handle_unexpected(conn, &rep);
- }
/* ignore reply; we don't even care about it */
conn->curacid = 0;
cur->auth_generation = client_auth_generation(client);
@@ -2703,11 +2636,512 @@ _fs_client_access (conn, client, sync)
}
/*
+ * Poll a pending connect
+ */
+
+static int
+_fs_check_connect (FSFpePtr conn)
+{
+ int ret;
+
+ ret = _fs_poll_connect (conn->trans_conn, 0);
+ switch (ret) {
+ case FSIO_READY:
+ conn->fs_fd = _FontTransGetConnectionNumber (conn->trans_conn);
+ FD_SET (conn->fs_fd, &_fs_fd_mask);
+ break;
+ case FSIO_BLOCK:
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Return an FSIO status while waiting for the completed connection
+ * reply to arrive
+ */
+
+static fsConnSetup *
+_fs_get_conn_setup (FSFpePtr conn, int *error, int *setup_len)
+{
+ int ret;
+ char *data;
+ int headlen;
+ int len;
+ fsConnSetup *setup;
+ fsConnSetupAccept *accept;
+
+ ret = _fs_start_read (conn, SIZEOF (fsConnSetup), &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+
+ setup = (fsConnSetup *) data;
+ if (setup->major_version > FS_PROTOCOL)
+ {
+ *error = FSIO_ERROR;
+ return 0;
+ }
+
+ headlen = (SIZEOF (fsConnSetup) +
+ (setup->alternate_len << 2) +
+ (setup->auth_len << 2));
+ /* On anything but Success, no extra data is sent */
+ if (setup->status != AuthSuccess)
+ {
+ len = headlen;
+ }
+ else
+ {
+ ret = _fs_start_read (conn, headlen + SIZEOF (fsConnSetupAccept), &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+ setup = (fsConnSetup *) data;
+ accept = (fsConnSetupAccept *) (data + headlen);
+ len = headlen + (accept->length << 2);
+ }
+ ret = _fs_start_read (conn, len, &data);
+ if (ret != FSIO_READY)
+ {
+ *error = ret;
+ return 0;
+ }
+ *setup_len = len;
+ return (fsConnSetup *) data;
+}
+
+static int
+_fs_send_conn_client_prefix (FSFpePtr conn)
+{
+ fsConnClientPrefix req;
+ int endian;
+ int ret;
+
+ /* send setup prefix */
+ endian = 1;
+ if (*(char *) &endian)
+ req.byteOrder = 'l';
+ else
+ req.byteOrder = 'B';
+
+ req.major_version = FS_PROTOCOL;
+ req.minor_version = FS_PROTOCOL_MINOR;
+
+/* XXX add some auth info here */
+ req.num_auths = 0;
+ req.auth_len = 0;
+ ret = _fs_write (conn, (char *) &req, SIZEOF (fsConnClientPrefix));
+ if (ret != FSIO_READY)
+ return FSIO_ERROR;
+ conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+ return ret;
+}
+
+static int
+_fs_recv_conn_setup (FSFpePtr conn)
+{
+ int ret;
+ fsConnSetup *setup;
+ FSFpeAltPtr alts;
+ int i, alt_len;
+ int setup_len;
+ char *alt_save, *alt_names;
+
+ setup = _fs_get_conn_setup (conn, &ret, &setup_len);
+ if (!setup)
+ return ret;
+ conn->current_seq = 0;
+ conn->fsMajorVersion = setup->major_version;
+ /*
+ * Create an alternate list from the initial server, but
+ * don't chain looking for alternates.
+ */
+ if (conn->alternate == 0)
+ {
+ /*
+ * free any existing alternates list, allowing the list to
+ * be updated
+ */
+ if (conn->alts)
+ {
+ xfree (conn->alts);
+ conn->alts = 0;
+ conn->numAlts = 0;
+ }
+ if (setup->num_alternates)
+ {
+ alts = (FSFpeAltPtr) xalloc (setup->num_alternates *
+ sizeof (FSFpeAltRec) +
+ (setup->alternate_len << 2));
+ if (alts)
+ {
+ alt_names = (char *) (setup + 1);
+ alt_save = (char *) (alts + setup->num_alternates);
+ for (i = 0; i < setup->num_alternates; i++)
+ {
+ alts[i].subset = alt_names[0];
+ alt_len = alt_names[1];
+ alts[i].name = alt_save;
+ memcpy (alt_save, alt_names + 2, alt_len);
+ alt_save[alt_len] = '\0';
+ alt_save += alt_len + 1;
+ alt_names += _fs_pad_length (alt_len + 2);
+ }
+ conn->numAlts = setup->num_alternates;
+ conn->alts = alts;
+ }
+ }
+ }
+ _fs_done_read (conn, setup_len);
+ if (setup->status != AuthSuccess)
+ return FSIO_ERROR;
+ return FSIO_READY;
+}
+
+static int
+_fs_open_server (FSFpePtr conn)
+{
+ int ret;
+ char *servername;
+
+ if (conn->alternate == 0)
+ servername = conn->servername;
+ else
+ servername = conn->alts[conn->alternate-1].name;
+ conn->trans_conn = _fs_connect (servername, &ret);
+ conn->blockedConnectTime = GetTimeInMillis () + FS_RECONNECT_WAIT;
+ return ret;
+}
+
+static char *
+_fs_catalog_name (char *servername)
+{
+ char *sp;
+
+ sp = strchr (servername, '/');
+ if (!sp)
+ return 0;
+ return strrchr (sp + 1, '/');
+}
+
+static int
+_fs_send_init_packets (FSFpePtr conn)
+{
+ fsSetResolutionReq srreq;
+ fsSetCataloguesReq screq;
+ int num_cats,
+ clen;
+ char *catalogues;
+ char *cat;
+ char len;
+ char *end;
+ int num_res;
+ FontResolutionPtr res;
+
+#define CATALOGUE_SEP '+'
+
+ res = GetClientResolutions(&num_res);
+ if (num_res)
+ {
+ srreq.reqType = FS_SetResolution;
+ srreq.num_resolutions = num_res;
+ srreq.length = (SIZEOF(fsSetResolutionReq) +
+ (num_res * SIZEOF(fsResolution)) + 3) >> 2;
+
+ _fs_add_req_log(conn, FS_SetResolution);
+ if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != FSIO_READY)
+ return FSIO_ERROR;
+ if (_fs_write_pad(conn, (char *) res, (num_res * SIZEOF(fsResolution))) != FSIO_READY)
+ return FSIO_ERROR;
+ }
+
+ catalogues = 0;
+ if (conn->alternate != 0)
+ catalogues = _fs_catalog_name (conn->alts[conn->alternate-1].name);
+ if (!catalogues)
+ catalogues = _fs_catalog_name (conn->servername);
+
+ if (!catalogues)
+ {
+ conn->has_catalogues = FALSE;
+ return FSIO_READY;
+ }
+ conn->has_catalogues = TRUE;
+
+ /* turn cats into counted list */
+ catalogues++;
+
+ cat = catalogues;
+ num_cats = 0;
+ clen = 0;
+ while (*cat)
+ {
+ num_cats++;
+ end = strchr(cat, CATALOGUE_SEP);
+ if (!end)
+ end = cat + strlen (cat);
+ clen += (end - cat) + 1; /* length byte + string */
+ cat = end;
+ }
+
+ screq.reqType = FS_SetCatalogues;
+ screq.num_catalogues = num_cats;
+ screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2;
+
+ _fs_add_req_log(conn, FS_SetCatalogues);
+ if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) != FSIO_READY)
+ return FSIO_ERROR;
+
+ while (*cat)
+ {
+ num_cats++;
+ end = strchr(cat, CATALOGUE_SEP);
+ if (!end)
+ end = cat + strlen (cat);
+ len = end - cat;
+ if (_fs_write (conn, &len, 1) != FSIO_READY)
+ return FSIO_ERROR;
+ if (_fs_write (conn, cat, (int) len) != FSIO_READY)
+ return FSIO_ERROR;
+ cat = end;
+ }
+
+ if (_fs_write (conn, "....", _fs_pad_length (clen) - clen) != FSIO_READY)
+ return FSIO_ERROR;
+
+ return FSIO_READY;
+}
+
+static int
+_fs_send_cat_sync (FSFpePtr conn)
+{
+ fsListCataloguesReq lcreq;
+
+ /*
+ * now sync up with the font server, to see if an error was generated
+ * by a bogus catalogue
+ */
+ lcreq.reqType = FS_ListCatalogues;
+ lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2;
+ lcreq.maxNames = 0;
+ lcreq.nbytes = 0;
+ _fs_add_req_log(conn, FS_SetCatalogues);
+ if (_fs_write(conn, (char *) &lcreq, SIZEOF(fsListCataloguesReq)) != FSIO_READY)
+ return FSIO_ERROR;
+ conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout;
+ return FSIO_READY;
+}
+
+static int
+_fs_recv_cat_sync (FSFpePtr conn)
+{
+ fsGenericReply *reply;
+ fsError *error;
+ int err;
+ int ret;
+
+ reply = fs_get_reply (conn, &err);
+ if (!reply)
+ return err;
+
+ ret = FSIO_READY;
+ if (reply->type == FS_Error)
+ {
+ error = (fsError *) reply;
+ if (error->major_opcode == FS_SetCatalogues)
+ ret = FSIO_ERROR;
+ }
+ _fs_done_read (conn, reply->length << 2);
+ return ret;
+}
+
+static void
+_fs_close_server (FSFpePtr conn)
+{
+ _fs_unmark_block (conn, FS_PENDING_WRITE|FS_BROKEN_WRITE|FS_COMPLETE_REPLY|FS_BROKEN_CONNECTION);
+ if (conn->trans_conn)
+ {
+ _FontTransClose (conn->trans_conn);
+ conn->trans_conn = 0;
+ _fs_io_reinit (conn);
+ }
+ if (conn->fs_fd >= 0)
+ {
+ FD_CLR (conn->fs_fd, &_fs_fd_mask);
+ conn->fs_fd = -1;
+ }
+ conn->fs_conn_state = FS_CONN_UNCONNECTED;
+}
+
+static int
+_fs_do_setup_connection (FSFpePtr conn)
+{
+ int ret;
+
+ do
+ {
+#ifdef DEBUG
+ fprintf (stderr, "fs_do_setup_connection state %d\n", conn->fs_conn_state);
+#endif
+ switch (conn->fs_conn_state) {
+ case FS_CONN_UNCONNECTED:
+ ret = _fs_open_server (conn);
+ if (ret == FSIO_BLOCK)
+ conn->fs_conn_state = FS_CONN_CONNECTING;
+ break;
+ case FS_CONN_CONNECTING:
+ ret = _fs_check_connect (conn);
+ break;
+ case FS_CONN_CONNECTED:
+ ret = _fs_send_conn_client_prefix (conn);
+ break;
+ case FS_CONN_SENT_PREFIX:
+ ret = _fs_recv_conn_setup (conn);
+ break;
+ case FS_CONN_RECV_INIT:
+ ret = _fs_send_init_packets (conn);
+ if (conn->has_catalogues)
+ ret = _fs_send_cat_sync (conn);
+ break;
+ case FS_CONN_SENT_CAT:
+ if (conn->has_catalogues)
+ ret = _fs_recv_cat_sync (conn);
+ else
+ ret = FSIO_READY;
+ break;
+ default:
+ ret = FSIO_READY;
+ break;
+ }
+ switch (ret) {
+ case FSIO_READY:
+ if (conn->fs_conn_state < FS_CONN_RUNNING)
+ conn->fs_conn_state++;
+ break;
+ case FSIO_BLOCK:
+ if (TimeCmp (GetTimeInMillis (), <, conn->blockedConnectTime))
+ break;
+ ret = FSIO_ERROR;
+ /* fall through... */
+ case FSIO_ERROR:
+ _fs_close_server (conn);
+ /*
+ * Try the next alternate
+ */
+ if (conn->alternate < conn->numAlts)
+ {
+ conn->alternate++;
+ ret = FSIO_READY;
+ }
+ else
+ conn->alternate = 0;
+ break;
+ }
+ } while (conn->fs_conn_state != FS_CONN_RUNNING && ret == FSIO_READY);
+ if (ret == FSIO_READY)
+ conn->generation = ++generationCount;
+ return ret;
+}
+
+static int
+_fs_wait_connect (FSFpePtr conn)
+{
+ int ret;
+
+ for (;;)
+ {
+ ret = _fs_do_setup_connection (conn);
+ if (ret != FSIO_BLOCK)
+ break;
+ if (conn->fs_conn_state <= FS_CONN_CONNECTING)
+ ret = _fs_poll_connect (conn->trans_conn, 1000);
+ else
+ ret = _fs_wait_for_readable (conn, 1000);
+ if (ret == FSIO_ERROR)
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Poll a connection in the process of reconnecting
+ */
+static void
+_fs_check_reconnect (FSFpePtr conn)
+{
+ int ret;
+
+ ret = _fs_do_setup_connection (conn);
+ switch (ret) {
+ case FSIO_READY:
+ _fs_unmark_block (conn, FS_RECONNECTING|FS_GIVE_UP);
+ _fs_restart_connection (conn);
+ break;
+ case FSIO_BLOCK:
+ break;
+ case FSIO_ERROR:
+ conn->brokenConnectionTime = GetTimeInMillis () + FS_RECONNECT_POLL;
+ break;
+ }
+}
+
+/*
+ * Start the reconnection process
+ */
+static void
+_fs_start_reconnect (FSFpePtr conn)
+{
+ if (conn->blockState & FS_RECONNECTING)
+ return;
+ conn->alternate = 0;
+ _fs_mark_block (conn, FS_RECONNECTING);
+ _fs_unmark_block (conn, FS_BROKEN_CONNECTION);
+ _fs_check_reconnect (conn);
+}
+
+
+static FSFpePtr
+_fs_init_conn (char *servername)
+{
+ FSFpePtr conn;
+
+ conn = xalloc (sizeof (FSFpeRec) + strlen (servername) + 1);
+ if (!conn)
+ return 0;
+ memset (conn, '\0', sizeof (FSFpeRec));
+ if (!_fs_io_init (conn))
+ {
+ xfree (conn);
+ return 0;
+ }
+ conn->servername = (char *) (conn + 1);
+ conn->fs_conn_state = FS_CONN_UNCONNECTED;
+ conn->fs_fd = -1;
+ strcpy (conn->servername, servername);
+ return conn;
+}
+
+static void
+_fs_free_conn (FSFpePtr conn)
+{
+ _fs_close_server (conn);
+ _fs_io_fini (conn);
+ if (conn->alts)
+ xfree (conn->alts);
+ xfree (conn);
+}
+
+/*
* called at server init time
*/
void
-fs_register_fpe_functions()
+fs_register_fpe_functions(void)
{
fs_font_type = RegisterFPEFunctions(fs_name_check,
fs_init_fpe,
@@ -2718,28 +3152,20 @@ fs_register_fpe_functions()
fs_list_fonts,
fs_start_list_with_info,
fs_next_list_with_info,
- fs_wakeup,
+ (WakeupFpeFunc)fs_wakeup,
fs_client_died,
_fs_load_glyphs,
- (int (*))0,
- (int (*))0,
- (void (*))0);
+ NULL,
+ NULL,
+ NULL);
}
static int
-check_fs_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont,
- alias, non_cachable_font)
- pointer client;
- FontPathElementPtr fpe;
- Mask flags;
- char *name;
- fsBitmapFormat format;
- fsBitmapFormatMask fmask;
- int namelen;
- XID id;
- FontPtr *ppfont;
- char **alias;
- FontPtr non_cachable_font; /* Not used in this FPE */
+check_fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags,
+ char *name, int namelen,
+ fsBitmapFormat format, fsBitmapFormatMask fmask,
+ XID id, FontPtr *ppfont,
+ char **alias, FontPtr non_cachable_font)
{
if (XpClientIsBitmapClient(client))
return (fs_open_font(client, fpe, flags, name, namelen, format,
@@ -2748,13 +3174,9 @@ check_fs_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont,
}
static int
-check_fs_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
- pointer client;
- FontPathElementPtr fpe;
- char *pattern;
- int patlen;
- int maxnames;
- FontNamesPtr newnames;
+check_fs_list_fonts(pointer client, FontPathElementPtr fpe,
+ char *pattern, int patlen, int maxnames,
+ FontNamesPtr newnames)
{
if (XpClientIsBitmapClient(client))
return (fs_list_fonts(client, fpe, pattern, patlen, maxnames,
@@ -2763,13 +3185,9 @@ check_fs_list_fonts(client, fpe, pattern, patlen, maxnames, newnames)
}
static int
-check_fs_start_list_with_info(client, fpe, pattern, len, maxnames, pdata)
- pointer client;
- FontPathElementPtr fpe;
- char *pattern;
- int len;
- int maxnames;
- pointer *pdata;
+check_fs_start_list_with_info(pointer client, FontPathElementPtr fpe,
+ char *pattern, int len, int maxnames,
+ pointer *pdata)
{
if (XpClientIsBitmapClient(client))
return (fs_start_list_with_info(client, fpe, pattern, len, maxnames,
@@ -2778,15 +3196,10 @@ check_fs_start_list_with_info(client, fpe, pattern, len, maxnames, pdata)
}
static int
-check_fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, numFonts,
- private)
- pointer client;
- FontPathElementPtr fpe;
- char **namep;
- int *namelenp;
- FontInfoPtr *pFontInfo;
- int *numFonts;
- pointer private;
+check_fs_next_list_with_info(pointer client, FontPathElementPtr fpe,
+ char **namep, int *namelenp,
+ FontInfoPtr *pFontInfo, int *numFonts,
+ pointer private)
{
if (XpClientIsBitmapClient(client))
return (fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo,
@@ -2795,7 +3208,7 @@ check_fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, numFonts,
}
void
-check_fs_register_fpe_functions()
+check_fs_register_fpe_functions(void)
{
fs_font_type = RegisterFPEFunctions(fs_name_check,
fs_init_fpe,
@@ -2806,10 +3219,10 @@ check_fs_register_fpe_functions()
check_fs_list_fonts,
check_fs_start_list_with_info,
check_fs_next_list_with_info,
- fs_wakeup,
+ (WakeupFpeFunc)fs_wakeup,
fs_client_died,
_fs_load_glyphs,
- (int (*))0,
- (int (*))0,
- (void (*))0);
+ NULL,
+ NULL,
+ NULL);
}
diff --git a/src/fc/fserve.h b/src/fc/fserve.h
index b5370d0..9d69257 100644
--- a/src/fc/fserve.h
+++ b/src/fc/fserve.h
@@ -24,6 +24,7 @@
* Author: Dave Lemke, Network Computing Devices, Inc
*
*/
+/* $XFree86: xc/lib/font/fc/fserve.h,v 1.5 2001/04/05 17:42:28 dawes Exp $ */
#ifndef _FSERVE_H_
#define _FSERVE_H_
@@ -50,6 +51,12 @@
#define FS_LFWI_REPLY 1
#define FS_LFWI_FINISHED 2
+/* states of connection */
+#define FS_CONN_CLOSED 0
+#define FS_CONN_CONNECTING 1
+#define FS_CONN_READ_HEADER 2
+#define FS_CONN_READ_DATA 3
+
#define AccessDone 0x400
typedef struct _fs_font_data *FSFontDataPtr;
@@ -59,10 +66,31 @@ typedef struct _fs_blocked_list *FSBlockedListPtr;
typedef struct _fs_blocked_list_info *FSBlockedListInfoPtr;
typedef struct _fs_block_data *FSBlockDataPtr;
typedef struct _fs_font_table *FSFontTablePtr;
+typedef struct _fs_fpe_data *FSFpePtr;
typedef struct _fs_blocked_bitmaps *FSBlockedBitmapPtr;
typedef struct _fs_blocked_extents *FSBlockedExtentPtr;
-extern void fs_convert_char_info();
+extern void _fs_convert_char_info ( fsXCharInfo *src, xCharInfo *dst );
+extern void _fs_free_props (FontInfoPtr pfi);
+extern FontPtr fs_create_font (FontPathElementPtr fpe,
+ char *name,
+ int namelen,
+ fsBitmapFormat format,
+ fsBitmapFormatMask fmask);
+
+extern int fs_load_all_glyphs ( FontPtr pfont );
+extern int _fs_load_glyphs ( pointer client, FontPtr pfont, Bool range_flag,
+ unsigned int nchars, int item_size,
+ unsigned char *data );
+
+/*
+ * These should be declared elsewhere, but I'm concerned that moving them
+ * would cause problems building other pieces
+ */
+extern FontPtr find_old_font (Font id);
+extern int set_font_authorizations (char **a, int *len, pointer client);
+extern long GetTimeInMillis (void);
+
#endif /* _FSERVE_H_ */
diff --git a/src/fc/fservestr.h b/src/fc/fservestr.h
index 891d4ae..20c85f6 100644
--- a/src/fc/fservestr.h
+++ b/src/fc/fservestr.h
@@ -23,6 +23,7 @@
*
* Author: Dave Lemke, Network Computing Devices, Inc
*/
+/* $XFree86: xc/lib/font/fc/fservestr.h,v 3.4 2001/07/25 15:04:56 dawes Exp $ */
#ifndef _FSERVESTR_H_
#define _FSERVESTR_H_
@@ -37,18 +38,21 @@
* font server private storage
*/
+typedef struct _fs_glyph {
+ struct _fs_glyph *next;
+} FSGlyphRec, *FSGlyphPtr;
typedef struct _fs_font {
CharInfoPtr pDefault;
CharInfoPtr encoding;
CharInfoPtr inkMetrics;
+ FSGlyphPtr glyphs;
} FSFontRec, *FSFontPtr;
/* FS special data for the font */
typedef struct _fs_font_data {
long fontid;
int generation; /* FS generation when opened */
- FontPathElementPtr fpe;
unsigned long glyphs_to_get; /* # glyphs remaining to be gotten */
/* Following data needed in case font needs to be reopened. */
@@ -65,22 +69,23 @@ typedef struct fs_clients_depending {
/* OpenFont specific data for blocked request */
typedef struct _fs_blocked_font {
- FontPtr pfont;
+ FontPtr pfont; /* must be first for fs_read_glyphs */
long fontid;
int state; /* how many of the replies have landed */
- int errcode;
int flags;
+ Bool freeFont; /* free this font on failure */
+ CARD16 queryInfoSequence;
+ CARD16 queryExtentsSequence;
+ CARD16 queryBitmapsSequence;
fsBitmapFormat format;
FSClientsDependingPtr clients_depending;
} FSBlockedFontRec;
/* LoadGlyphs data for blocked request */
typedef struct _fs_blocked_glyphs {
- FontPtr pfont;
+ FontPtr pfont; /* must be first for fs_read_glyphs */
int num_expected_ranges;
fsRange *expected_ranges;
- int errcode;
- Bool done;
FSClientsDependingPtr clients_depending;
} FSBlockedGlyphRec;
@@ -89,7 +94,6 @@ typedef struct _fs_blocked_extents {
FontPtr pfont;
fsRange *expected_ranges;
int nranges;
- Bool done;
unsigned long nextents;
fsXCharInfo *extents;
} FSBlockedExtentRec;
@@ -99,7 +103,6 @@ typedef struct _fs_blocked_bitmaps {
FontPtr pfont;
fsRange *expected_ranges;
int nranges;
- Bool done;
unsigned long size;
unsigned long nglyphs;
fsOffset32 *offsets;
@@ -109,29 +112,25 @@ typedef struct _fs_blocked_bitmaps {
/* state for blocked ListFonts */
typedef struct _fs_blocked_list {
FontNamesPtr names;
- int patlen;
- int errcode;
- Bool done;
} FSBlockedListRec;
/* state for blocked ListFontsWithInfo */
typedef struct _fs_blocked_list_info {
int status;
- char *name;
int namelen;
- FontInfoPtr pfi;
+ FontInfoRec info;
+ char name[256];
int remaining;
- int errcode;
} FSBlockedListInfoRec;
/* state for blocked request */
typedef struct _fs_block_data {
- int type; /* Open Font, LoadGlyphs, ListFonts,
- * ListWithInfo */
+ int type; /* Open Font, LoadGlyphs, ListFonts,
+ * ListWithInfo */
pointer client; /* who wants it */
- int sequence_number;/* expected */
- fsGenericReply header;
+ CARD16 sequenceNumber; /* expected */
pointer data; /* type specific data */
+ int errcode; /* Suspended, et al. */
struct _fs_block_data *depending; /* clients depending on this one */
struct _fs_block_data *next;
} FSBlockDataRec;
@@ -142,7 +141,7 @@ typedef struct _fs_reconnect {
} FSReconnectRec, *FSReconnectPtr;
-#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#if !defined(UNIXCPP) || defined(ANSICPP)
#define fsCat(x,y) x##_##y
#else
#define fsCat(x,y) x/**/_/**/y
@@ -184,5 +183,29 @@ typedef struct _fs_reconnect {
fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->maxbounds); \
fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->ink_maxbounds)
-
+extern void _fs_init_fontinfo ( FSFpePtr conn, FontInfoPtr pfi );
+extern int _fs_convert_props ( fsPropInfo *pi, fsPropOffset *po, pointer pd,
+ FontInfoPtr pfi );
+extern int _fs_convert_lfwi_reply ( FSFpePtr conn, FontInfoPtr pfi,
+ fsListFontsWithXInfoReply *fsrep,
+ fsPropInfo *pi, fsPropOffset *po,
+ pointer pd );
+extern int fs_build_range ( FontPtr pfont, Bool range_flag,
+ unsigned int count, int item_size,
+ unsigned char *data, int *nranges,
+ fsRange **ranges );
+extern void _fs_clean_aborted_loadglyphs ( FontPtr pfont,
+ int num_expected_ranges,
+ fsRange *expected_ranges );
+extern int _fs_check_extents ( FontPtr pfont, Mask flags, int nranges,
+ fsRange *range, FSBlockDataPtr blockrec );
+extern int _fs_check_bitmaps ( FontPtr pfont, fsBitmapFormat format,
+ Mask flags, int nranges, fsRange *range,
+ FSBlockDataPtr blockrec );
+extern int _fs_get_glyphs ( FontPtr pFont, unsigned long count,
+ unsigned char *chars, FontEncoding charEncoding,
+ unsigned long *glyphCount, CharInfoPtr *glyphs );
+extern void _fs_unload_font ( FontPtr pfont );
+extern void _fs_init_font ( FontPtr pfont );
+extern pointer fs_alloc_glyphs (FontPtr pFont, int size);
#endif /* _FSERVESTR_H_ */
diff --git a/src/fc/fsio.c b/src/fc/fsio.c
index 578d86a..b5d9de0 100644
--- a/src/fc/fsio.c
+++ b/src/fc/fsio.c
@@ -23,6 +23,7 @@
*
* Author: Dave Lemke, Network Computing Devices, Inc
*/
+/* $XFree86: xc/lib/font/fc/fsio.c,v 3.16 2002/05/31 18:45:49 dawes Exp $ */
/*
* font server i/o routines
*/
@@ -31,113 +32,84 @@
#define _WILLWINSOCK_
#endif
-#include "FS.h"
-#include "FSproto.h"
-
#include "X11/Xtrans.h"
#include "X11/Xpoll.h"
+#include "FS.h"
+#include "FSproto.h"
#include "fontmisc.h"
-#include "fsio.h"
+#include "fontstruct.h"
+#include "fservestr.h"
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
-#ifndef WIN32
+#if !defined(WIN32)
+#ifndef Lynx
#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
#endif
#include <errno.h>
-#ifdef X_NOT_STDC_ENV
-extern int errno;
-#endif
#ifdef WIN32
#define EWOULDBLOCK WSAEWOULDBLOCK
#undef EINTR
#define EINTR WSAEINTR
#endif
-/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
- * systems are broken and return EWOULDBLOCK when they should return EAGAIN
- */
-#ifdef WIN32
-#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
-#else
-#if defined(EAGAIN) && defined(EWOULDBLOCK)
-#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
-#else
-#ifdef EAGAIN
-#define ETEST() (errno == EAGAIN)
-#else
-#define ETEST() (errno == EWOULDBLOCK)
-#endif
-#endif
-#endif
-#ifdef WIN32
-#define ECHECK(err) (WSAGetLastError() == err)
-#define ESET(val) WSASetLastError(val)
-#else
-#define ECHECK(err) (errno == err)
-#define ESET(val) errno = val
+#ifdef __UNIXOS2__
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
#endif
+
static int padlength[4] = {0, 3, 2, 1};
fd_set _fs_fd_mask;
-int _fs_wait_for_readable();
+static int
+_fs_resize (FSBufPtr buf, long size);
-#ifdef SIGNALRETURNSINT
-#define SIGNAL_T int
-#else
-#define SIGNAL_T void
-#endif
-
-/* ARGSUSED */
-static SIGNAL_T
-_fs_alarm(foo)
- int foo;
+static void
+_fs_downsize (FSBufPtr buf, long size);
+
+int
+_fs_poll_connect (XtransConnInfo trans_conn, int timeout)
{
- return;
+ fd_set w_mask;
+ struct timeval tv;
+ int fs_fd = _FontTransGetConnectionNumber (trans_conn);
+ int ret;
+
+ do
+ {
+ tv.tv_usec = 0;
+ tv.tv_sec = timeout;
+ FD_ZERO (&w_mask);
+ FD_SET (fs_fd, &w_mask);
+ ret = Select (fs_fd + 1, NULL, &w_mask, NULL, &tv);
+ } while (ret < 0 && ECHECK(EINTR));
+ if (ret == 0)
+ return FSIO_BLOCK;
+ if (ret < 0)
+ return FSIO_ERROR;
+ return FSIO_READY;
}
-static XtransConnInfo
-_fs_connect(servername, timeout)
- char *servername;
- int timeout;
+XtransConnInfo
+_fs_connect(char *servername, int *err)
{
- XtransConnInfo trans_conn; /* transport connection object */
- int ret = -1;
-#ifdef SIGALRM
- unsigned oldTime;
-
- SIGNAL_T(*oldAlarm) ();
-#endif
+ XtransConnInfo trans_conn; /* transport connection object */
+ int ret;
+ int i = 0;
+ int retries = 5;
/*
* Open the network connection.
*/
if( (trans_conn=_FontTransOpenCOTSClient(servername)) == NULL )
- {
- return (NULL);
- }
-
-#ifdef SIGALRM
- oldTime = alarm((unsigned) 0);
- oldAlarm = signal(SIGALRM, _fs_alarm);
- alarm((unsigned) timeout);
-#endif
-
- ret = _FontTransConnect(trans_conn,servername);
-
-#ifdef SIGALRM
- alarm((unsigned) 0);
- signal(SIGALRM, oldAlarm);
- alarm(oldTime);
-#endif
-
- if (ret < 0)
- {
- _FontTransClose(trans_conn);
- return (NULL);
- }
+ {
+ *err = FSIO_ERROR;
+ return 0;
+ }
/*
* Set the connection non-blocking since we use select() to block.
@@ -145,330 +117,310 @@ _fs_connect(servername, timeout)
_FontTransSetOption(trans_conn, TRANS_NONBLOCKING, 1);
- return trans_conn;
-}
-
-static int generationCount;
-
-/* ARGSUSED */
-static Bool
-_fs_setup_connection(conn, servername, timeout, copy_name_p)
- FSFpePtr conn;
- char *servername;
- int timeout;
- Bool copy_name_p;
-{
- fsConnClientPrefix prefix;
- fsConnSetup rep;
- int setuplength;
- fsConnSetupAccept conn_accept;
- int endian;
- int i;
- int alt_len;
- char *auth_data = NULL,
- *vendor_string = NULL,
- *alt_data = NULL,
- *alt_dst;
- FSFpeAltPtr alts;
- int nalts;
-
- if ((conn->trans_conn = _fs_connect(servername, 5)) == NULL)
- return FALSE;
-
- conn->fs_fd = _FontTransGetConnectionNumber (conn->trans_conn);
-
- conn->generation = ++generationCount;
+ do {
+ if (i == TRANS_TRY_CONNECT_AGAIN)
+ sleep(1);
+ i = _FontTransConnect(trans_conn,servername);
+ } while ((i == TRANS_TRY_CONNECT_AGAIN) && (retries-- > 0));
- /* send setup prefix */
- endian = 1;
- if (*(char *) &endian)
- prefix.byteOrder = 'l';
+ if (i < 0)
+ {
+ if (i == TRANS_IN_PROGRESS)
+ ret = FSIO_BLOCK;
+ else
+ ret = FSIO_ERROR;
+ }
else
- prefix.byteOrder = 'B';
-
- prefix.major_version = FS_PROTOCOL;
- prefix.minor_version = FS_PROTOCOL_MINOR;
+ ret = FSIO_READY;
-/* XXX add some auth info here */
- prefix.num_auths = 0;
- prefix.auth_len = 0;
-
- if (_fs_write(conn, (char *) &prefix, SIZEOF(fsConnClientPrefix)) == -1)
- return FALSE;
-
- /* read setup info */
- if (_fs_read(conn, (char *) &rep, SIZEOF(fsConnSetup)) == -1)
- return FALSE;
+ if (ret == FSIO_ERROR)
+ {
+ _FontTransClose(trans_conn);
+ trans_conn = 0;
+ }
- conn->fsMajorVersion = rep.major_version;
- if (rep.major_version > FS_PROTOCOL)
- return FALSE;
+ *err = ret;
+ return trans_conn;
+}
- alts = 0;
- /* parse alternate list */
- if ((nalts = rep.num_alternates)) {
- setuplength = rep.alternate_len << 2;
- alts = (FSFpeAltPtr) xalloc(nalts * sizeof(FSFpeAltRec) +
- setuplength);
- if (!alts) {
- _FontTransClose(conn->trans_conn);
- errno = ENOMEM;
- return FALSE;
- }
- alt_data = (char *) (alts + nalts);
- if (_fs_read(conn, (char *) alt_data, setuplength) == -1) {
- xfree(alts);
- return FALSE;
+int
+_fs_fill (FSFpePtr conn)
+{
+ long avail, need;
+ long bytes_read;
+ Bool waited = FALSE;
+
+ if (_fs_flush (conn) < 0)
+ return FSIO_ERROR;
+ /*
+ * Don't go overboard here; stop reading when we've
+ * got enough to satisfy the pending request
+ */
+ while ((need = conn->inNeed - (conn->inBuf.insert -
+ conn->inBuf.remove)) > 0)
+ {
+ avail = conn->inBuf.size - conn->inBuf.insert;
+ /*
+ * For SVR4 with a unix-domain connection, ETEST() after selecting
+ * readable means the server has died. To do this here, we look for
+ * two consecutive reads returning ETEST().
+ */
+ ESET (0);
+ bytes_read =_FontTransRead(conn->trans_conn,
+ conn->inBuf.buf + conn->inBuf.insert,
+ avail);
+ if (bytes_read > 0) {
+ conn->inBuf.insert += bytes_read;
+ waited = FALSE;
}
- alt_dst = alt_data;
- for (i = 0; i < nalts; i++) {
- alts[i].subset = alt_data[0];
- alt_len = alt_data[1];
- alts[i].name = alt_dst;
- memmove(alt_dst, alt_data + 2, alt_len);
- alt_dst[alt_len] = '\0';
- alt_dst += (alt_len + 1);
- alt_data += (2 + alt_len + padlength[(2 + alt_len) & 3]);
+ else
+ {
+ if (bytes_read == 0 || ETEST ())
+ {
+ if (!waited)
+ {
+ waited = TRUE;
+ if (_fs_wait_for_readable (conn, 0) == FSIO_BLOCK)
+ return FSIO_BLOCK;
+ continue;
+ }
+ }
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
}
}
- if (conn->alts)
- xfree(conn->alts);
- conn->alts = alts;
- conn->numAlts = nalts;
-
- setuplength = rep.auth_len << 2;
- if (setuplength &&
- !(auth_data = (char *) xalloc((unsigned int) setuplength))) {
- _FontTransClose(conn->trans_conn);
- errno = ENOMEM;
- return FALSE;
- }
- if (_fs_read(conn, (char *) auth_data, setuplength) == -1) {
- xfree(auth_data);
- return FALSE;
- }
- if (rep.status != AuthSuccess) {
- xfree(auth_data);
- _FontTransClose(conn->trans_conn);
- errno = EPERM;
- return FALSE;
- }
- /* get rest */
- if (_fs_read(conn, (char *) &conn_accept, (long) SIZEOF(fsConnSetupAccept)) == -1) {
- xfree(auth_data);
- return FALSE;
- }
- if ((vendor_string = (char *)
- xalloc((unsigned) conn_accept.vendor_len + 1)) == NULL) {
- xfree(auth_data);
- _FontTransClose(conn->trans_conn);
- errno = ENOMEM;
- return FALSE;
- }
- if (_fs_read_pad(conn, (char *) vendor_string, conn_accept.vendor_len) == -1) {
- xfree(vendor_string);
- xfree(auth_data);
- return FALSE;
+ return FSIO_READY;
+}
+
+/*
+ * Make space and return whether data have already arrived
+ */
+
+int
+_fs_start_read (FSFpePtr conn, long size, char **buf)
+{
+ int ret;
+
+ conn->inNeed = size;
+ if (fs_inqueued(conn) < size)
+ {
+ if (_fs_resize (&conn->inBuf, size) != FSIO_READY)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ ret = _fs_fill (conn);
+ if (ret == FSIO_ERROR)
+ return ret;
+ if (ret == FSIO_BLOCK || fs_inqueued(conn) < size)
+ return FSIO_BLOCK;
}
- xfree(auth_data);
- xfree(vendor_string);
+ if (buf)
+ *buf = conn->inBuf.buf + conn->inBuf.remove;
+ return FSIO_READY;
+}
- if (copy_name_p)
+void
+_fs_done_read (FSFpePtr conn, long size)
+{
+ if (conn->inBuf.insert - conn->inBuf.remove < size)
{
- conn->servername = (char *) xalloc(strlen(servername) + 1);
- if (conn->servername == NULL)
- return FALSE;
- strcpy(conn->servername, servername);
+#ifdef DEBUG
+ fprintf (stderr, "_fs_done_read skipping to many bytes\n");
+#endif
+ return;
}
- else
- conn->servername = servername;
+ conn->inBuf.remove += size;
+ conn->inNeed -= size;
+ _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
- return TRUE;
+long
+_fs_pad_length (long len)
+{
+ return len + padlength[len&3];
}
-static Bool
-_fs_try_alternates(conn, timeout)
- FSFpePtr conn;
- int timeout;
+int
+_fs_flush (FSFpePtr conn)
{
- int i;
+ long bytes_written;
+ long remain;
+
+ /* XXX - hack. The right fix is to remember that the font server
+ has gone away when we first discovered it. */
+ if (conn->fs_fd < 0)
+ return FSIO_ERROR;
- for (i = 0; i < conn->numAlts; i++)
- if (_fs_setup_connection(conn, conn->alts[i].name, timeout, TRUE))
- return TRUE;
- return FALSE;
+ while ((remain = conn->outBuf.insert - conn->outBuf.remove) > 0)
+ {
+ bytes_written = _FontTransWrite(conn->trans_conn,
+ conn->outBuf.buf + conn->outBuf.remove,
+ (int) remain);
+ if (bytes_written > 0)
+ {
+ conn->outBuf.remove += bytes_written;
+ }
+ else
+ {
+ if (bytes_written == 0 || ETEST ())
+ {
+ conn->brokenWriteTime = GetTimeInMillis () + FS_FLUSH_POLL;
+ _fs_mark_block (conn, FS_BROKEN_WRITE);
+ break;
+ }
+ if (!ECHECK (EINTR))
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
+ }
+ }
+ }
+ if (conn->outBuf.remove == conn->outBuf.insert)
+ {
+ _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE);
+ if (conn->outBuf.size > FS_BUF_INC)
+ conn->outBuf.buf = xrealloc (conn->outBuf.buf, FS_BUF_INC);
+ conn->outBuf.remove = conn->outBuf.insert = 0;
+ }
+ return FSIO_READY;
}
-#define FS_OPEN_TIMEOUT 30
-#define FS_REOPEN_TIMEOUT 10
-
-FSFpePtr
-_fs_open_server(servername)
- char *servername;
+static int
+_fs_resize (FSBufPtr buf, long size)
{
- FSFpePtr conn;
+ char *new;
+ long new_size;
- conn = (FSFpePtr) xalloc(sizeof(FSFpeRec));
- if (!conn) {
- errno = ENOMEM;
- return (FSFpePtr) NULL;
- }
- bzero((char *) conn, sizeof(FSFpeRec));
- if (!_fs_setup_connection(conn, servername, FS_OPEN_TIMEOUT, TRUE)) {
- if (!_fs_try_alternates(conn, FS_OPEN_TIMEOUT)) {
- xfree(conn->alts);
- xfree(conn);
- return (FSFpePtr) NULL;
+ if (buf->remove)
+ {
+ if (buf->remove != buf->insert)
+ {
+ memmove (buf->buf,
+ buf->buf + buf->remove,
+ buf->insert - buf->remove);
}
+ buf->insert -= buf->remove;
+ buf->remove = 0;
}
- return conn;
+ if (buf->size - buf->remove < size)
+ {
+ new_size = ((buf->remove + size + FS_BUF_INC) / FS_BUF_INC) * FS_BUF_INC;
+ new = xrealloc (buf->buf, new_size);
+ if (!new)
+ return FSIO_ERROR;
+ buf->buf = new;
+ buf->size = new_size;
+ }
+ return FSIO_READY;
}
-Bool
-_fs_reopen_server(conn)
- FSFpePtr conn;
+static void
+_fs_downsize (FSBufPtr buf, long size)
{
- if (_fs_setup_connection(conn, conn->servername, FS_REOPEN_TIMEOUT, FALSE))
- return TRUE;
- if (_fs_try_alternates(conn, FS_REOPEN_TIMEOUT))
- return TRUE;
- return FALSE;
+ if (buf->insert == buf->remove)
+ {
+ buf->insert = buf->remove = 0;
+ if (buf->size > size)
+ {
+ buf->buf = xrealloc (buf->buf, size);
+ buf->size = size;
+ }
+ }
}
-/*
- * expects everything to be here. *not* to be called when reading huge
- * numbers of replies, but rather to get each chunk
- */
-int
-_fs_read(conn, data, size)
- FSFpePtr conn;
- char *data;
- unsigned long size;
+void
+_fs_io_reinit (FSFpePtr conn)
{
- long bytes_read;
-
- if (size == 0) {
-
-#ifdef DEBUG
- fprintf(stderr, "tried to read 0 bytes \n");
-#endif
+ conn->outBuf.insert = conn->outBuf.remove = 0;
+ _fs_downsize (&conn->outBuf, FS_BUF_INC);
+ conn->inBuf.insert = conn->inBuf.remove = 0;
+ _fs_downsize (&conn->inBuf, FS_BUF_MAX);
+}
- return 0;
- }
- ESET(0);
- while ((bytes_read = _FontTransRead(conn->trans_conn,
- data, (int) size)) != size) {
- if (bytes_read > 0) {
- size -= bytes_read;
- data += bytes_read;
- } else if (ETEST()) {
- /* in a perfect world, this shouldn't happen */
- /* ... but then, its less than perfect... */
- if (_fs_wait_for_readable(conn) == -1) { /* check for error */
- _fs_connection_died(conn);
- ESET(EPIPE);
- return -1;
- }
- ESET(0);
- } else if (ECHECK(EINTR)) {
- continue;
- } else { /* something bad happened */
- if (conn->fs_fd > 0)
- _fs_connection_died(conn);
- ESET(EPIPE);
- return -1;
- }
+Bool
+_fs_io_init (FSFpePtr conn)
+{
+ conn->outBuf.insert = conn->outBuf.remove = 0;
+ conn->outBuf.buf = xalloc (FS_BUF_INC);
+ if (!conn->outBuf.buf)
+ return FALSE;
+ conn->outBuf.size = FS_BUF_INC;
+
+ conn->inBuf.insert = conn->inBuf.remove = 0;
+ conn->inBuf.buf = xalloc (FS_BUF_INC);
+ if (!conn->inBuf.buf)
+ {
+ xfree (conn->outBuf.buf);
+ conn->outBuf.buf = 0;
+ return FALSE;
}
- return 0;
+ conn->inBuf.size = FS_BUF_INC;
+
+ return TRUE;
}
-int
-_fs_write(conn, data, size)
- FSFpePtr conn;
- char *data;
- unsigned long size;
+void
+_fs_io_fini (FSFpePtr conn)
{
- long bytes_written;
+ if (conn->outBuf.buf)
+ xfree (conn->outBuf.buf);
+ if (conn->inBuf.buf)
+ xfree (conn->inBuf.buf);
+}
+static int
+_fs_do_write(FSFpePtr conn, char *data, long len, long size)
+{
if (size == 0) {
-
#ifdef DEBUG
fprintf(stderr, "tried to write 0 bytes \n");
#endif
-
- return 0;
+ return FSIO_READY;
}
- /* XXX - hack. The right fix is to remember that the font server
- has gone away when we first discovered it. */
- if (!conn->trans_conn)
- return -1;
-
- ESET(0);
- while ((bytes_written = _FontTransWrite(conn->trans_conn,
- data, (int) size)) != size) {
- if (bytes_written > 0) {
- size -= bytes_written;
- data += bytes_written;
- } else if (ETEST()) {
- /* XXX -- we assume this can't happen */
-
-#ifdef DEBUG
- fprintf(stderr, "fs_write blocking\n");
-#endif
- } else if (ECHECK(EINTR)) {
- continue;
- } else { /* something bad happened */
- _fs_connection_died(conn);
- ESET(EPIPE);
- return -1;
+ if (conn->fs_fd == -1)
+ return FSIO_ERROR;
+
+ while (conn->outBuf.insert + size > conn->outBuf.size)
+ {
+ if (_fs_flush (conn) < 0)
+ return FSIO_ERROR;
+ if (_fs_resize (&conn->outBuf, size) < 0)
+ {
+ _fs_connection_died (conn);
+ return FSIO_ERROR;
}
}
- return 0;
+ memcpy (conn->outBuf.buf + conn->outBuf.insert, data, len);
+ conn->outBuf.insert += size;
+ _fs_mark_block (conn, FS_PENDING_WRITE);
+ return FSIO_READY;
}
+/*
+ * Write the indicated bytes
+ */
int
-_fs_read_pad(conn, data, len)
- FSFpePtr conn;
- char *data;
- int len;
+_fs_write (FSFpePtr conn, char *data, long len)
{
- char pad[3];
-
- if (_fs_read(conn, data, len) == -1)
- return -1;
-
- /* read the junk */
- if (padlength[len & 3]) {
- return _fs_read(conn, pad, padlength[len & 3]);
- }
- return 0;
+ return _fs_do_write (conn, data, len, len);
}
-
+
+/*
+ * Write the indicated bytes adding any appropriate pad
+ */
int
-_fs_write_pad(conn, data, len)
- FSFpePtr conn;
- char *data;
- int len;
+_fs_write_pad(FSFpePtr conn, char *data, long len)
{
- static char pad[3];
-
- if (_fs_write(conn, data, len) == -1)
- return -1;
-
- /* write the pad */
- if (padlength[len & 3]) {
- return _fs_write(conn, pad, padlength[len & 3]);
- }
- return 0;
+ return _fs_do_write (conn, data, len, len + padlength[len & 3]);
}
/*
* returns the amount of data waiting to be read
*/
int
-_fs_data_ready(conn)
- FSFpePtr conn;
+_fs_data_ready(FSFpePtr conn)
{
BytesReadable_t readable;
@@ -478,73 +430,65 @@ _fs_data_ready(conn)
}
int
-_fs_wait_for_readable(conn)
- FSFpePtr conn;
+_fs_wait_for_readable(FSFpePtr conn, int ms)
{
- fd_set r_mask;
- fd_set e_mask;
+ fd_set r_mask;
+ fd_set e_mask;
int result;
+ struct timeval tv;
-#ifdef DEBUG
- fprintf(stderr, "read would block\n");
-#endif
-
- do {
+ for (;;) {
+ if (conn->fs_fd < 0)
+ return FSIO_ERROR;
FD_ZERO(&r_mask);
FD_ZERO(&e_mask);
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000;
FD_SET(conn->fs_fd, &r_mask);
FD_SET(conn->fs_fd, &e_mask);
- result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, NULL);
- if (result == -1) {
+ result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, &tv);
+ if (result < 0)
+ {
if (ECHECK(EINTR) || ECHECK(EAGAIN))
continue;
else
- return -1;
+ return FSIO_ERROR;
}
- if (result && FD_ISSET(conn->fs_fd, &e_mask))
- return -1;
- } while (result <= 0);
-
- return 0;
+ if (result == 0)
+ return FSIO_BLOCK;
+ if (FD_ISSET(conn->fs_fd, &r_mask))
+ return FSIO_READY;
+ return FSIO_ERROR;
+ }
}
int
-_fs_set_bit(mask, fd)
- fd_set* mask;
- int fd;
+_fs_set_bit(fd_set *mask, int fd)
{
FD_SET(fd, mask);
return fd;
}
int
-_fs_is_bit_set(mask, fd)
- fd_set* mask;
- int fd;
+_fs_is_bit_set(fd_set *mask, int fd)
{
return FD_ISSET(fd, mask);
}
void
-_fs_bit_clear(mask, fd)
- fd_set* mask;
- int fd;
+_fs_bit_clear(fd_set *mask, int fd)
{
FD_CLR(fd, mask);
}
int
-_fs_any_bit_set(mask)
- fd_set* mask;
+_fs_any_bit_set(fd_set *mask)
{
return XFD_ANYSET(mask);
}
void
-_fs_or_bits(dst, m1, m2)
- fd_set* dst;
- fd_set* m1;
- fd_set* m2;
+_fs_or_bits(fd_set *dst, fd_set *m1, fd_set *m2)
{
#ifdef WIN32
int i;
@@ -564,49 +508,3 @@ _fs_or_bits(dst, m1, m2)
XFD_ORSET(dst, m1, m2);
#endif
}
-
-int
-_fs_drain_bytes(conn, len)
- FSFpePtr conn;
- int len;
-{
- char buf[128];
-
-#ifdef DEBUG
- fprintf(stderr, "draining wire\n");
-#endif
-
- while (len > 0) {
- if (_fs_read(conn, buf, (len < 128) ? len : 128) < 0)
- return -1;
- len -= 128;
- }
- return 0;
-}
-
-void
-_fs_drain_bytes_pad(conn, len)
- FSFpePtr conn;
- int len;
-{
- _fs_drain_bytes(conn, len);
-
- /* read the junk */
- if (padlength[len & 3]) {
- _fs_drain_bytes(conn, padlength[len & 3]);
- }
-}
-
-void
-_fs_eat_rest_of_error(conn, err)
- FSFpePtr conn;
- fsError *err;
-{
- int len = (err->length - (SIZEOF(fsGenericReply) >> 2)) << 2;
-
-#ifdef DEBUG
- fprintf(stderr, "clearing error\n");
-#endif
-
- _fs_drain_bytes(conn, len);
-}
diff --git a/src/fc/fsio.h b/src/fc/fsio.h
index dd33cdf..974ef4a 100644
--- a/src/fc/fsio.h
+++ b/src/fc/fsio.h
@@ -23,10 +23,12 @@
*
* Author: Dave Lemke, Network Computing Devices, Inc
*/
+/* $XFree86: xc/lib/font/fc/fsio.h,v 1.6 2001/01/17 19:43:29 dawes Exp $ */
#ifndef _FSIO_H_
#define _FSIO_H_
+#undef DEBUG
#define REQUEST_LOG_SIZE 100
typedef struct _fs_fpe_alternate {
@@ -43,18 +45,52 @@ typedef struct _fs_client_data {
int auth_generation;
} FSClientRec, *FSClientPtr;
-#define FS_RECONNECT_WAIT 5
-#define FS_MAX_RECONNECT_WAIT 80
+#define FS_RECONNECT_POLL 1000
+#define FS_RECONNECT_WAIT 5000
+#define FS_GIVEUP_WAIT 20000
+#define FS_REQUEST_TIMEOUT 20000
+#define FS_OPEN_TIMEOUT 30000
+#define FS_REOPEN_TIMEOUT 10000
+#define FS_FLUSH_POLL 1000
+
+typedef struct _fs_buf {
+ char *buf; /* data */
+ long size; /* sizeof data */
+ long insert; /* where to insert new data */
+ long remove; /* where to remove old data */
+} FSBufRec, *FSBufPtr;
+
+#define FS_BUF_INC 1024
+#define FS_BUF_MAX 32768
+
+#define FS_PENDING_WRITE 0x01 /* some write data is queued */
+#define FS_BROKEN_WRITE 0x02 /* writes are broken */
+#define FS_BROKEN_CONNECTION 0x04 /* connection is broken */
+#define FS_PENDING_REPLY 0x08 /* waiting for a reply */
+#define FS_GIVE_UP 0x10 /* font server declared useless */
+#define FS_COMPLETE_REPLY 0x20 /* complete reply ready */
+#define FS_RECONNECTING 0x40
+
+#define FS_CONN_UNCONNECTED 0
+#define FS_CONN_CONNECTING 1
+#define FS_CONN_CONNECTED 2
+#define FS_CONN_SENT_PREFIX 3
+#define FS_CONN_RECV_INIT 4
+#define FS_CONN_SENT_CAT 5
+#define FS_CONN_RUNNING 6
/* FS specific font FontPathElement data */
typedef struct _fs_fpe_data {
- int fs_fd;
+ FSFpePtr next; /* list of all active fs fpes */
+ int fs_fd; /* < 0 when not running */
+ int fs_conn_state; /* connection state */
int current_seq;
char *servername;
- char *requestedname; /* client's name for this connection */
+ Bool has_catalogues;
int generation;
int numAlts;
+ int alternate; /* which alternate is in use +1 */
int fsMajorVersion; /* font server major version number */
FSFpeAltPtr alts;
@@ -62,21 +98,90 @@ typedef struct _fs_fpe_data {
XID curacid;
#ifdef DEBUG
int reqindex;
- int reqbuffer[REQUEST_LOG_SIZE];
+ struct {
+ int opcode;
+ int sequence;
+ } reqbuffer[REQUEST_LOG_SIZE];
#endif
+ FSBufRec outBuf; /* request queue */
+ FSBufRec inBuf; /* reply queue */
+ long inNeed; /* amount needed for reply */
- int attemptReconnect;
-
-/* XXX massive crock to get around stupid #include interferences */
- pointer blocked_requests;
-/* Data for reconnect - put it here to avoid allocate failure nightmare */
- long time_to_try;
- long reconnect_delay;
- struct _fs_fpe_data *next_reconnect;
+ CARD32 blockState;
+ CARD32 blockedReplyTime; /* time to abort blocked read */
+ CARD32 brokenWriteTime; /* time to retry broken write */
+ CARD32 blockedConnectTime; /* time to abort blocked connect */
+ CARD32 brokenConnectionTime; /* time to retry broken connection */
+
+ FSBlockDataPtr blockedRequests;
+
struct _XtransConnInfo *trans_conn; /* transport connection object */
-} FSFpeRec, *FSFpePtr;
+} FSFpeRec;
+
+#define fs_outspace(conn) ((conn)->outBuf.size - (conn)->outBuf.insert)
+#define fs_outqueued(conn) ((conn)->outBuf.insert - (conn)->outBuf.remove)
+#define fs_inqueued(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove)
+#define fs_needsflush(conn) (fs_outqueued(conn) != 0)
+#define fs_needsfill(conn) (fs_inqueued(conn) < (conn)->inNeed)
+#define fs_needsconnect(conn) ((conn)->fs_fd < 0)
+#define fs_data_read(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove)
+
+#define FSIO_READY 1
+#define FSIO_BLOCK 0
+#define FSIO_ERROR -1
+
+extern Bool _fs_reopen_server ( FSFpePtr conn );
+extern int _fs_write ( FSFpePtr conn, char *data, long size );
+extern int _fs_write_pad ( FSFpePtr conn, char *data, long len );
+extern int _fs_data_ready ( FSFpePtr conn );
+extern int _fs_wait_for_readable ( FSFpePtr conn, int ms );
+extern int _fs_set_bit ( fd_set * mask, int fd );
+extern int _fs_is_bit_set ( fd_set * mask, int fd );
+extern void _fs_bit_clear ( fd_set * mask, int fd );
+extern int _fs_any_bit_set ( fd_set * mask );
+extern void _fs_or_bits ( fd_set * dst, fd_set * m1, fd_set * m2 );
+extern long _fs_pad_length (long len);
-FSFpePtr _fs_open_server();
-void _fs_bit_clear();
+extern void _fs_connection_died ( FSFpePtr conn );
+
+extern int _fs_fill (FSFpePtr conn);
+extern int _fs_flush (FSFpePtr conn);
+extern void _fs_mark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask);
+extern void _fs_done_read (FSFpePtr conn, long size);
+extern void _fs_io_reinit (FSFpePtr conn);
+extern int _fs_start_read (FSFpePtr conn, long size, char **buf);
+extern Bool _fs_io_init (FSFpePtr conn);
+extern void _fs_io_fini (FSFpePtr conn);
+extern int _fs_poll_connect (XtransConnInfo trans_conn, int timeout);
+extern XtransConnInfo _fs_connect(char *servername, int *ret);
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifdef WIN32
+#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK)
+#else
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST() (errno == EAGAIN)
+#else
+#define ETEST() (errno == EWOULDBLOCK)
+#endif
+#endif
+#endif
+#ifdef WIN32
+#define ECHECK(err) (WSAGetLastError() == err)
+#define ESET(val) WSASetLastError(val)
+#else
+#ifdef ISC
+#define ECHECK(err) ((errno == err) || ETEST())
+#else
+#define ECHECK(err) (errno == err)
+#endif
+#define ESET(val) errno = val
+#endif
#endif /* _FSIO_H_ */
diff --git a/src/fc/fslibos.h b/src/fc/fslibos.h
index d666ea4..8ca2a8a 100644
--- a/src/fc/fslibos.h
+++ b/src/fc/fslibos.h
@@ -31,6 +31,7 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
+/* $XFree86: xc/lib/font/fc/fslibos.h,v 3.7 2002/05/31 18:45:49 dawes Exp $ */
/*
* FSlib networking & os include file
@@ -56,8 +57,12 @@ from The Open Group.
#endif
#endif
#ifndef OPEN_MAX
-#ifdef SVR4
+#if defined(SVR4) || defined(__UNIXOS2__)
+#ifdef SCO325
+#define OPEN_MAX sysconf(_SC_OPEN_MAX)
+#else
#define OPEN_MAX 256
+#endif
#else
#include <sys/param.h>
#ifndef OPEN_MAX