summaryrefslogtreecommitdiff
path: root/app/xfs/difs
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:43:48 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:43:48 +0000
commit022ad3d01558dbc1a59aefd36cd80afbf034d415 (patch)
tree7809beb94b49355c5b5d9d9abe4c1ccea5669463 /app/xfs/difs
parent5a94fa48c7f977f6ae8745a7bb15a8be696be655 (diff)
Importing from X.Org indiviual releases
Diffstat (limited to 'app/xfs/difs')
-rw-r--r--app/xfs/difs/atom.c205
-rw-r--r--app/xfs/difs/cache.c385
-rw-r--r--app/xfs/difs/charinfo.c639
-rw-r--r--app/xfs/difs/difsutils.c672
-rw-r--r--app/xfs/difs/dispatch.c1138
-rw-r--r--app/xfs/difs/events.c134
-rw-r--r--app/xfs/difs/extensions.c300
-rw-r--r--app/xfs/difs/fontinfo.c437
-rw-r--r--app/xfs/difs/fonts.c1554
-rw-r--r--app/xfs/difs/globals.c67
-rw-r--r--app/xfs/difs/initfonts.c133
-rw-r--r--app/xfs/difs/main.c209
-rw-r--r--app/xfs/difs/resource.c571
-rw-r--r--app/xfs/difs/swaprep.c507
-rw-r--r--app/xfs/difs/swapreq.c297
-rw-r--r--app/xfs/difs/tables.c164
16 files changed, 7412 insertions, 0 deletions
diff --git a/app/xfs/difs/atom.c b/app/xfs/difs/atom.c
new file mode 100644
index 000000000..55d878fbb
--- /dev/null
+++ b/app/xfs/difs/atom.c
@@ -0,0 +1,205 @@
+/* $Xorg: atom.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * font server atom manipulations
+ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * @(#)atom.c 4.1 5/2/91
+ *
+ */
+/* $XFree86: xc/programs/xfs/difs/atom.c,v 3.4tsi Exp $ */
+
+#include "misc.h"
+#include "fsresource.h"
+#include "difs.h"
+
+#define InitialTableSize 100
+#define FSA_LAST_PREDEFINED 0 /* only None is predefined */
+
+typedef struct _Node {
+ struct _Node *left,
+ *right;
+ Atom a;
+ unsigned int fingerPrint;
+ char *string;
+} NodeRec, *NodePtr;
+
+static Atom lastAtom = None;
+static NodePtr atomRoot = (NodePtr) NULL;
+static unsigned long tableLength;
+static NodePtr *nodeTable;
+
+Atom
+MakeAtom(char *string, unsigned int len, Bool makeit)
+{
+ register NodePtr *np;
+ unsigned i;
+ int comp;
+ register unsigned int fp = 0;
+
+ np = &atomRoot;
+ for (i = 0; i < (len + 1) / 2; i++) {
+ fp = fp * 27 + string[i];
+ fp = fp * 27 + string[len - 1 - i];
+ }
+ while (*np != (NodePtr) NULL) {
+ if (fp < (*np)->fingerPrint)
+ np = &((*np)->left);
+ else if (fp > (*np)->fingerPrint)
+ np = &((*np)->right);
+ else { /* now start testing the strings */
+ comp = strncmp(string, (*np)->string, (int) len);
+ if ((comp < 0) || ((comp == 0) && (len < strlen((*np)->string))))
+ np = &((*np)->left);
+ else if (comp > 0)
+ np = &((*np)->right);
+ else
+ return (*np)->a;
+ }
+ }
+ if (makeit) {
+ register NodePtr nd;
+
+ nd = (NodePtr) fsalloc(sizeof(NodeRec));
+ if (!nd)
+ return BAD_RESOURCE;
+#if FSA_LAST_PREDEFINED > 0
+ if (lastAtom < FSA_LAST_PREDEFINED) {
+ nd->string = string;
+ } else
+#endif
+ {
+ nd->string = (char *) fsalloc(len + 1);
+ if (!nd->string) {
+ fsfree(nd);
+ return BAD_RESOURCE;
+ }
+ strncpy(nd->string, string, (int) len);
+ nd->string[len] = 0;
+ }
+ if ((lastAtom + 1) >= tableLength) {
+ NodePtr *table;
+
+ table = (NodePtr *) fsrealloc(nodeTable,
+ tableLength * (2 * sizeof(NodePtr)));
+ if (!table) {
+ if (nd->string != string)
+ fsfree(nd->string);
+ fsfree(nd);
+ return BAD_RESOURCE;
+ }
+ tableLength <<= 1;
+ nodeTable = table;
+ }
+ *np = nd;
+ nd->left = nd->right = (NodePtr) NULL;
+ nd->fingerPrint = fp;
+ nd->a = (++lastAtom);
+ *(nodeTable + lastAtom) = nd;
+ return nd->a;
+ } else
+ return None;
+}
+
+int
+ValidAtom(Atom atom)
+{
+ return (atom != None) && (atom <= lastAtom);
+}
+
+char *
+NameForAtom(Atom atom)
+{
+ NodePtr node;
+
+ if (atom > lastAtom)
+ return 0;
+ if ((node = nodeTable[atom]) == (NodePtr) NULL)
+ return 0;
+ return node->string;
+}
+
+static void
+atom_error(void)
+{
+ FatalError("initializing atoms\n");
+}
+
+static void
+free_atom(NodePtr patom)
+{
+ if (patom->left)
+ free_atom(patom->left);
+ if (patom->right)
+ free_atom(patom->right);
+ if (patom->a > FSA_LAST_PREDEFINED)
+ fsfree(patom->string);
+ fsfree(patom);
+}
+
+static void
+free_all_atoms(void)
+{
+ if (atomRoot == (NodePtr) NULL)
+ return;
+ free_atom(atomRoot);
+ atomRoot = (NodePtr) NULL;
+ fsfree(nodeTable);
+ nodeTable = (NodePtr *) NULL;
+ lastAtom = None;
+}
+
+void
+InitAtoms(void)
+{
+ free_all_atoms();
+ tableLength = InitialTableSize;
+ nodeTable = (NodePtr *) fsalloc(InitialTableSize * sizeof(NodePtr));
+ if (!nodeTable)
+ atom_error();
+ nodeTable[None] = (NodePtr) NULL;
+ lastAtom = FSA_LAST_PREDEFINED;
+}
diff --git a/app/xfs/difs/cache.c b/app/xfs/difs/cache.c
new file mode 100644
index 000000000..905feacbd
--- /dev/null
+++ b/app/xfs/difs/cache.c
@@ -0,0 +1,385 @@
+/* $XdotOrg: $ */
+/* $Xorg: cache.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * @(#)cache.c 4.2 91/05/02
+ *
+ */
+/* $XFree86: xc/programs/xfs/difs/cache.c,v 1.6 2001/12/14 20:01:33 dawes Exp $ */
+
+#include "cachestr.h"
+#include "misc.h"
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+
+#define ENTRYOFFSET 22
+#define CACHE_ENTRY_MASK 0x3FFFFF
+#define CACHE_ENTRY_BITS(id) ((id) & 0x1fc00000)
+#define CACHE_ID(id) ((int)(CACHE_ENTRY_BITS(id) >> ENTRYOFFSET))
+
+#define NullCacheEntry ((CacheEntryPtr) 0)
+
+#define MAX_NUM_CACHES 32
+/* XXX make this dynamic? */
+static CachePtr caches[MAX_NUM_CACHES];
+static int num_caches = 1;
+
+/*-
+ * Notes on cache implementation
+ *
+ * This is basically the X11 resource code, with some modifications
+ * to handle aging.
+ *
+ * Its currently optimized for lookup & store. Flushing old stuff
+ * is a lot slower than it should probably be, but there's tradeoffs
+ * in tuning.
+ */
+
+Cache
+CacheInit(unsigned long maxsize)
+{
+ Cache id = (Cache) num_caches;
+ CachePtr cache;
+
+ cache = (CachePtr) fsalloc(sizeof(CacheRec));
+ if (!cache)
+ return (Cache) 0;
+ cache->entries = (CacheEntryPtr *)
+ fsalloc(INITBUCKETS * sizeof(CacheEntryPtr));
+ bzero((char *) cache->entries, (INITBUCKETS * sizeof(CacheEntryPtr)));
+ if (!cache->entries) {
+ fsfree(cache);
+ return (Cache) 0;
+ }
+ caches[id] = cache;
+ cache->elements = 0;
+ cache->buckets = INITBUCKETS;
+ cache->hashsize = INITHASHSIZE;
+ cache->maxsize = maxsize;
+ cache->cursize = 0;
+ cache->nextid = id << ENTRYOFFSET;
+ cache->id = id;
+ num_caches++;
+ return id;
+}
+
+static int
+hash(CacheID cid)
+{
+ CachePtr cache = caches[CACHE_ID(cid)];
+
+ switch (cache->hashsize) {
+#ifdef DEBUG /* only need this if INITHASHSIZE < 6 */
+ case 2:
+ return ((int) (0x03 & (cid ^ (cid >> 2) ^ (cid >> 8))));
+ case 3:
+ return ((int) (0x07 & (cid ^ (cid >> 3) ^ (cid >> 9))));
+ case 4:
+ return ((int) (0x0F & (cid ^ (cid >> 4) ^ (cid >> 10))));
+ case 5:
+ return ((int) (0x01F & (cid ^ (cid >> 5) ^ (cid >> 11))));
+#endif
+ case 6:
+ return ((int) (0x03F & (cid ^ (cid >> 6) ^ (cid >> 12))));
+ case 7:
+ return ((int) (0x07F & (cid ^ (cid >> 7) ^ (cid >> 13))));
+ case 8:
+ return ((int) (0x0FF & (cid ^ (cid >> 8) ^ (cid >> 16))));
+ case 9:
+ return ((int) (0x1FF & (cid ^ (cid >> 9))));
+ case 10:
+ return ((int) (0x3FF & (cid ^ (cid >> 10))));
+ case 11:
+ return ((int) (0x7FF & (cid ^ (cid >> 11))));
+ }
+ return -1;
+}
+
+static void
+rebuild_cache(CachePtr cache)
+{
+ int j;
+ CacheEntryPtr cp,
+ next,
+ **tails,
+ *entries,
+ **tptr,
+ *cptr;
+
+ assert(cache);
+ j = 2 * cache->buckets;
+ tails = (CacheEntryPtr **) ALLOCATE_LOCAL(j * sizeof(CacheEntryPtr *));
+ if (!tails)
+ return;
+ entries = (CacheEntryPtr *) fsalloc(j * sizeof(CacheEntryPtr));
+ if (!entries) {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (cptr = entries, tptr = tails; --j >= 0; cptr++, tptr++) {
+ *cptr = NullCacheEntry;
+ *tptr = cptr;
+ }
+ cache->hashsize++;
+ for (j = cache->buckets, cptr = cache->entries; --j >= 0; cptr++) {
+ for (cp = *cptr; cp; cp = next) {
+ next = cp->next;
+ cp->next = NullCacheEntry;
+ tptr = &tails[hash(cp->id)];
+ **tptr = cp;
+ *tptr = &cp->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ cache->buckets *= 2;
+ fsfree(cache->entries);
+ cache->entries = entries;
+}
+
+/*
+ * throws out all existing entries
+ */
+void
+CacheReset(void)
+{
+ CacheEntryPtr cp;
+ CachePtr cache;
+ int i,
+ j;
+
+ for (j = 0; j < num_caches; j++) {
+ cache = caches[j];
+ if (!cache)
+ continue;
+ for (i = 0; i < cache->buckets; i++) {
+ for (cp = cache->entries[i]; cp; cp = cp->next) {
+ cache->elements--;
+ cache->cursize -= cp->size;
+ (*cp->free_func) (cp->id, cp->data, CacheWasReset);
+ fsfree(cp);
+ }
+ cache->entries[i] = (CacheEntryPtr) 0;
+ }
+ assert(cache->cursize == 0);
+ }
+}
+
+static void
+flush_cache(CachePtr cache, unsigned long needed)
+{
+/* XXX -- try to set oldprev properly inside search loop */
+ CacheEntryPtr cp,
+ oldest,
+ *oldprev;
+ int oldbucket = -1,
+ i;
+
+ while ((cache->cursize + needed) > cache->maxsize) {
+ oldest = (CacheEntryPtr) 0;
+ /* find oldest */
+ for (i = 0; i < cache->buckets; i++) {
+ cp = cache->entries[i];
+ if (!cp)
+ continue;
+ if (!oldest) {
+ oldbucket = i;
+ oldest = cp;
+ }
+ while (cp) {
+ if (cp->timestamp < oldest->timestamp) {
+ oldest = cp;
+ oldbucket = i;
+ }
+ cp = cp->next;
+ }
+ }
+ /* fixup list */
+ oldprev = &cache->entries[oldbucket];
+ cp = *oldprev;
+ for (; (cp = *oldprev) != 0; oldprev = &cp->next) {
+ if (cp == oldest) {
+ *oldprev = oldest->next;
+ break;
+ }
+ }
+ /* clobber it */
+ cache->elements--;
+ cache->cursize -= oldest->size;
+ (*oldest->free_func) (oldest->id, oldest->data, CacheEntryOld);
+ fsfree(oldest);
+ }
+}
+
+void
+CacheResize(Cache cid, unsigned newsize)
+{
+ CachePtr cache = caches[cid];
+
+ if (!cache)
+ return;
+
+ if (newsize < cache->maxsize) {
+ /* have to toss some stuff */
+ flush_cache(cache, cache->maxsize - newsize);
+ }
+ cache->maxsize = newsize;
+}
+
+CacheID
+CacheStoreMemory(
+ Cache cid,
+ pointer data,
+ unsigned long size,
+ CacheFree free_func)
+{
+ CacheID id;
+ CacheEntryPtr cp,
+ *head;
+ CachePtr cache = caches[cid];
+
+ if (size > cache->maxsize) /* beyond cache limits */
+ return (CacheID) 0;
+
+ if ((cache->elements >= 4 * cache->buckets) &&
+ (cache->hashsize < MAXHASHSIZE)) {
+ rebuild_cache(cache);
+ }
+ id = cache->nextid++;
+
+ if ((cache->cursize + size) > cache->maxsize) {
+ flush_cache(cache, size);
+ }
+ head = &cache->entries[hash(id)];
+ cp = (CacheEntryPtr) fsalloc(sizeof(CacheEntryRec));
+ if (!cp) {
+ return (CacheID) 0;
+ }
+ cp->next = *head;
+ cp->id = id;
+ cp->timestamp = GetTimeInMillis();
+ cp->free_func = free_func;
+ cp->size = size;
+ cp->data = data;
+ cache->cursize += size;
+ cache->elements++;
+ *head = cp;
+
+ return id;
+}
+
+pointer
+CacheFetchMemory(
+ CacheID cid,
+ Bool update)
+{
+ CachePtr cache = caches[CACHE_ID(cid)];
+ CacheEntryPtr cp,
+ *head;
+
+ head = &cache->entries[hash(cid)];
+ for (cp = *head; cp; cp = cp->next) {
+ if (cp->id == cid) {
+ if (update) {
+ cp->timestamp = GetTimeInMillis();
+ if (cp != *head) { /* put it in the front */
+ cp->next = *head;
+ *head = cp;
+ }
+ }
+ return cp->data;
+ }
+ }
+ return (pointer) 0;
+}
+
+void
+CacheFreeMemory(
+ CacheID cid,
+ Bool notify)
+{
+ CachePtr cache = caches[CACHE_ID(cid)];
+ CacheEntryPtr cp,
+ *prev,
+ *head;
+ int *elptr;
+ int elements;
+ Bool found = FALSE;
+
+ head = &cache->entries[hash(cid)];
+ elptr = &cache->elements;
+ prev = head;
+ while ((cp = *prev) != NullCacheEntry) {
+ if (cp->id == cid) {
+ *prev = cp->next;
+ elements = --*elptr;
+ if (notify) {
+ (*(cp->free_func)) (cid, cp->data, CacheEntryFreed);
+ }
+ cache->cursize -= cp->size;
+ fsfree(cp);
+ if (*elptr != elements)
+ prev = head;
+ found = TRUE;
+ } else {
+ prev = &cp->next;
+ }
+ }
+ if (!found)
+ FatalError("freeing cache entry %d which isn't there\n", cid);
+}
+
+/* ARGSUSED */
+void
+CacheSimpleFree(
+ CacheID cid,
+ pointer data,
+ int reason)
+{
+ fsfree(data);
+}
diff --git a/app/xfs/difs/charinfo.c b/app/xfs/difs/charinfo.c
new file mode 100644
index 000000000..f47665f2c
--- /dev/null
+++ b/app/xfs/difs/charinfo.c
@@ -0,0 +1,639 @@
+/* $Xorg: charinfo.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/*
+ * Defines GetExtents() and GetBitmaps(), which are
+ * called from routines in fontinfo.c.
+ * This file was once on the other side of
+ * the font library interface as util/fsfuncs.c.
+ */
+/* $XFree86: xc/programs/xfs/difs/charinfo.c,v 1.11 2001/10/28 03:34:34 tsi Exp $ */
+
+#include <X11/Xos.h>
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fontutil.h>
+#include "clientstr.h"
+#define FSMD_H
+#include <X11/fonts/FSproto.h>
+#include "difs.h"
+
+extern void TwoByteSwap(unsigned char *, int);
+extern void FourByteSwap(unsigned char *, int);
+
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+ ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \
+ :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \
+ :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \
+ :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \
+ : 0)
+
+#define GLYPH_SIZE(ch, nbytes) \
+ GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+ (ch)->metrics.leftSideBearing, (nbytes))
+
+#define n2dChars(pfi) (((pfi)->lastRow - (pfi)->firstRow + 1) * \
+ ((pfi)->lastCol - (pfi)->firstCol + 1))
+
+#if 0
+static CharInfoRec junkDefault;
+#endif
+
+typedef int (*MetricsFunc)(FontPtr, unsigned long, unsigned char *,
+ FontEncoding, unsigned long *, CharInfoPtr *);
+
+static int
+getCharInfos (
+ FontPtr pfont,
+ int num_ranges,
+ fsRange *range,
+ Bool ink_metrics,
+ int *nump, /* return */
+ CharInfoPtr **retp) /* return */
+{
+ CharInfoPtr *xchars, *xci;
+ int nchars;
+ FontInfoPtr pinfo = &pfont->info;
+ unsigned int r, c;
+ unsigned char ch[2];
+ int firstCol = pinfo->firstCol;
+ int firstRow = pinfo->firstRow;
+ int lastRow = pinfo->lastRow;
+ int lastCol = pinfo->lastCol;
+ fsRange local_range, *rp;
+ int i;
+ FontEncoding encoding;
+ int err;
+ unsigned long glyphCount;
+ unsigned short defaultCh;
+ CharInfoPtr defaultPtr;
+ MetricsFunc metrics_func;
+
+ /*
+ * compute nchars
+ */
+ if (num_ranges == 0) {
+ if (lastRow)
+ nchars = n2dChars(pinfo);
+ else
+ nchars = lastCol - firstCol + 1;
+ local_range.min_char_low = firstCol;
+ local_range.min_char_high = firstRow;
+ local_range.max_char_low = lastCol;
+ local_range.max_char_high = lastRow;
+ range = &local_range;
+ num_ranges = 1;
+ } else {
+ nchars = 0;
+ for (i = 0, rp = range; i < num_ranges; i++, rp++) {
+ if (rp->min_char_high > rp->max_char_high ||
+ rp->min_char_low > rp->max_char_low)
+ return BadCharRange;
+ nchars += (rp->max_char_high - rp->min_char_high + 1) *
+ (rp->max_char_low - rp->min_char_low + 1);
+ }
+ }
+
+ xchars = (CharInfoPtr *) fsalloc (sizeof (CharInfoPtr) * nchars);
+ if (!xchars)
+ return AllocError;
+ bzero (xchars, sizeof (CharInfoPtr) * nchars);
+
+ if (ink_metrics)
+ metrics_func = (MetricsFunc)pfont->get_metrics;
+ else
+ metrics_func = pfont->get_glyphs;
+
+ xci = xchars;
+ encoding = Linear16Bit;
+ if (lastRow)
+ encoding = TwoD16Bit;
+ defaultCh = pinfo->defaultCh;
+ ch[0] = defaultCh >> 8;
+ ch[1] = defaultCh & 0xff;
+ /* get the default character */
+ (*metrics_func) (pfont, 1, ch, encoding,
+ &glyphCount, &defaultPtr);
+ if (glyphCount != 1)
+ defaultPtr = 0;
+
+ /* for each range, get each character individually, undoing the
+ default character substitution so we get zero metrics for
+ non-existent characters. */
+ for (i = 0, rp = range; i < num_ranges; i++, rp++) {
+ for (r = rp->min_char_high; r <= rp->max_char_high; r++)
+ {
+ for (c = rp->min_char_low; c <= rp->max_char_low; c++) {
+ ch[0] = r;
+ ch[1] = c;
+ err = (*metrics_func) (pfont, 1, ch, encoding,
+ &glyphCount, xci);
+ if (err != Successful)
+ {
+ fsfree (xchars);
+ return err;
+ }
+#if 0
+ if (glyphCount != 1 ||
+ (*xci == defaultPtr && defaultCh != ((r<<8)+c)))
+ *xci = &junkDefault;
+#endif
+ xci++;
+ }
+ }
+ }
+ *retp = xchars;
+ *nump = nchars;
+ return Successful;
+}
+
+int
+GetExtents(
+ ClientPtr client,
+ FontPtr pfont,
+ Mask flags,
+ unsigned long num_ranges,
+ fsRange *range,
+ unsigned long *num_extents, /* return */
+ fsXCharInfo **data) /* return */
+{
+ unsigned long size;
+ fsXCharInfo *ci;
+ fsXCharInfo cilocal;
+ char *pci;
+ CharInfoPtr *xchars, *xchars_cur;
+ CharInfoPtr xci;
+ int nchars;
+ int err;
+
+ if (flags & LoadAll)
+ num_ranges = 0;
+ err = getCharInfos (pfont, num_ranges, range,
+ client->major_version > 1 ? TRUE : FALSE,
+ &nchars, &xchars);
+ if (err != Successful)
+ return err;
+
+ size = SIZEOF(fsXCharInfo) * nchars;
+ pci = (char *) fsalloc(size);
+ if (!pci) {
+ fsfree (xchars);
+ return AllocError;
+ }
+
+ ci = (fsXCharInfo *) pci;
+ *num_extents = nchars;
+
+ /* pack the data */
+ xchars_cur = xchars;
+ while (nchars--) {
+ xci = *xchars_cur++;
+ cilocal.ascent = xci->metrics.ascent;
+ cilocal.descent = xci->metrics.descent;
+ cilocal.left = xci->metrics.leftSideBearing;
+ cilocal.right = xci->metrics.rightSideBearing;
+ cilocal.width = xci->metrics.characterWidth;
+ cilocal.attributes = xci->metrics.attributes;
+ memcpy(pci, &cilocal, SIZEOF(fsXCharInfo));
+ pci += SIZEOF(fsXCharInfo);
+ }
+
+ fsfree (xchars);
+
+ *data = ci;
+
+ return Successful;
+}
+
+static int
+packGlyphs (
+ ClientPtr client,
+ FontPtr pfont,
+ int format,
+ Mask flags,
+ unsigned long num_ranges,
+ fsRange *range,
+ int *tsize,
+ unsigned long *num_glyphs,
+ fsOffset32 **offsets,
+ pointer *data,
+ int *freeData)
+{
+ int i;
+ fsOffset32 *lengths, *l;
+ unsigned long size = 0;
+ pointer gdata;
+ unsigned char *gd;
+ int bitorder, byteorder, scanlinepad, scanlineunit, mappad;
+ int height = 0, dstbpr = 0, charsize = 0;
+ int dst_off = 0, src_off;
+ Bool contiguous, reformat;
+ int nchars;
+ int src_glyph_pad = pfont->glyph;
+ int src_bit_order = pfont->bit;
+ int src_byte_order = pfont->byte;
+ int err;
+ int max_ascent = 0, max_descent = 0;
+ int min_left = 0, max_right;
+ int srcbpr;
+ int lshift = 0, rshift = 0, dst_left_bytes = 0, src_left_bytes = 0;
+ unsigned char *srcp;
+ unsigned char *dstp;
+ unsigned char bits1, bits2;
+ int width;
+ int src_extra;
+ int dst_extra;
+ int r, w;
+ CharInfoPtr *bitChars, *bitCharsFree, bitc;
+ CharInfoPtr *inkChars, *inkCharsFree = 0, inkc;
+ FontInfoPtr pinfo = &pfont->info;
+ xCharInfo *bitm, *inkm;
+
+ err = CheckFSFormat(format, (fsBitmapFormatMask) ~ 0,
+ &bitorder, &byteorder, &scanlineunit, &scanlinepad, &mappad);
+
+ if (err != Successful)
+ return err;
+
+ if (flags & LoadAll)
+ num_ranges = 0;
+
+ err = getCharInfos (pfont, num_ranges, range, FALSE, &nchars, &bitCharsFree);
+
+ if (err != Successful)
+ return err;
+
+ /* compute dstbpr for padded out fonts */
+ reformat = bitorder != src_bit_order || byteorder != src_byte_order;
+
+ /* we need the ink metrics when shrink-wrapping a TE font (sigh),
+ * but only for protocol version > 1 */
+ if (mappad != BitmapFormatImageRectMax &&
+ pinfo->inkMetrics &&
+ client->major_version > 1)
+ {
+ err = getCharInfos (pfont, num_ranges, range, TRUE, &nchars, &inkCharsFree);
+ if (err != Successful)
+ {
+ fsfree (bitCharsFree);
+ return err;
+ }
+ reformat = TRUE;
+ }
+
+ /* get space for glyph offsets */
+ lengths = (fsOffset32 *) fsalloc(SIZEOF(fsOffset32) * nchars);
+ if (!lengths) {
+ fsfree (bitCharsFree);
+ fsfree (inkCharsFree);
+ return AllocError;
+ }
+
+ switch (mappad)
+ {
+ case BitmapFormatImageRectMax:
+ max_ascent = FONT_MAX_ASCENT(pinfo);
+ max_descent = FONT_MAX_DESCENT(pinfo);
+ height = max_ascent + max_descent;
+ /* do font ascent and font descent match bitmap bounds ? */
+ if (height != pinfo->minbounds.ascent + pinfo->minbounds.descent)
+ reformat = TRUE;
+ /* fall through */
+ case BitmapFormatImageRectMaxWidth:
+ min_left = FONT_MIN_LEFT(pinfo);
+ max_right = FONT_MAX_RIGHT(pinfo);
+ if (min_left != pinfo->maxbounds.leftSideBearing)
+ reformat = TRUE;
+ if (max_right != pinfo->maxbounds.rightSideBearing)
+ reformat = TRUE;
+ dstbpr = GLWIDTHBYTESPADDED(max_right - min_left, scanlinepad);
+ break;
+ case BitmapFormatImageRectMin:
+ break;
+ }
+ if (mappad == BitmapFormatImageRectMax)
+ charsize = dstbpr * height;
+ size = 0;
+ gdata = 0;
+ contiguous = TRUE;
+ l = lengths;
+ inkChars = inkCharsFree;
+ bitChars = bitCharsFree;
+ for (i = 0; i < nchars; i++)
+ {
+ inkc = bitc = *bitChars++;
+ /* when ink metrics != bitmap metrics, use ink metrics */
+ if (inkChars)
+ inkc = *inkChars++;
+ l->position = size;
+ /*
+ * Do not repad characters with no bits except for those
+ * with non-zero width.
+ */
+ if (bitc && (bitc->bits || bitc->metrics.characterWidth)) {
+ if (!gdata)
+ gdata = (pointer) bitc->bits;
+ if ((char *) gdata + size != bitc->bits)
+ contiguous = FALSE;
+ if (mappad == BitmapFormatImageRectMin)
+ dstbpr = GLYPH_SIZE(inkc, scanlinepad);
+ if (dstbpr != GLYPH_SIZE(bitc, src_glyph_pad)) reformat = TRUE;
+ if (mappad != BitmapFormatImageRectMax)
+ {
+ height = inkc->metrics.ascent + inkc->metrics.descent;
+ charsize = height * dstbpr;
+ }
+ l->length = charsize;
+ size += charsize;
+ }
+ else
+ l->length = 0;
+ l++;
+ }
+ if (contiguous && !reformat)
+ {
+ *num_glyphs = nchars;
+ *freeData = FALSE;
+ *data = gdata;
+ *tsize = size;
+ *offsets = lengths;
+ fsfree (bitCharsFree);
+ fsfree (inkCharsFree);
+ return Successful;
+ }
+ if (size)
+ {
+ gdata = (pointer) fsalloc(size);
+ if (!gdata) {
+ fsfree (bitCharsFree);
+ fsfree (inkCharsFree);
+ fsfree (lengths);
+ return AllocError;
+ }
+ bzero ((char *) gdata, size);
+ }
+ else
+ gdata = NULL;
+
+ *freeData = TRUE;
+ l = lengths;
+ gd = gdata;
+
+ /* finally do the work */
+ bitChars = bitCharsFree;
+ inkChars = inkCharsFree;
+ for (i = 0; i < nchars; i++, l++)
+ {
+ inkc = bitc = *bitChars++;
+ if (inkChars)
+ inkc = *inkChars++;
+
+ /* ignore missing chars */
+ if (l->length == 0)
+ continue;
+
+ bitm = &bitc->metrics;
+ inkm = &inkc->metrics;
+
+ /* start address for the destination of bits for this char */
+
+ dstp = gd;
+
+ if (mappad == BitmapFormatImageRectMax)
+ height = max_ascent + max_descent;
+ else
+ height = inkm->ascent + inkm->descent;
+
+ /* adjust destination and calculate shift offsets */
+ switch (mappad) {
+ case BitmapFormatImageRectMax:
+ /* leave the first padded rows blank */
+ if (max_ascent > inkm->ascent)
+ {
+ height -= (max_ascent - inkm->ascent);
+ dstp += dstbpr * (max_ascent - inkm->ascent);
+ }
+ if (max_descent > inkm->descent)
+ {
+ height -= (max_descent - inkm->descent);
+ }
+ /* fall thru */
+ case BitmapFormatImageRectMaxWidth:
+ dst_off = inkm->leftSideBearing - min_left;
+ if (dst_off < 0) dst_off = 0;
+ break;
+ case BitmapFormatImageRectMin:
+ dst_off = 0;
+ dstbpr = GLYPH_SIZE(inkc, scanlinepad);
+ break;
+ }
+
+ srcbpr = GLYPH_SIZE (bitc, src_glyph_pad);
+ srcp = (unsigned char *) bitc->bits;
+
+ /* adjust source */
+ src_off = 0;
+ if (inkm != bitm)
+ {
+ srcp += (bitm->ascent - inkm->ascent) * srcbpr;
+ src_off = inkm->leftSideBearing - bitm->leftSideBearing;
+ }
+
+ dst_left_bytes = dst_off >> 3;
+ dst_off &= 7;
+ src_left_bytes = src_off >> 3;
+ src_off &= 7;
+
+ /* minimum of source/dest bytes per row */
+ width = srcbpr - src_left_bytes;
+ if (width > dstbpr - dst_left_bytes)
+ width = dstbpr - dst_left_bytes;
+ /* extra bytes in source and dest for padding */
+ src_extra = srcbpr - width - src_left_bytes;
+ dst_extra = dstbpr - width - dst_left_bytes;
+
+#define MSBBitLeft(b,c) ((b) << (c))
+#define MSBBitRight(b,c) ((b) >> (c))
+#define LSBBitLeft(b,c) ((b) >> (c))
+#define LSBBitRight(b,c) ((b) << (c))
+
+ if (dst_off == src_off)
+ {
+ if (srcbpr == dstbpr && src_left_bytes == dst_left_bytes)
+ {
+ r = height * srcbpr;
+ memmove( dstp, srcp, r);
+ dstp += r;
+ }
+ else
+ {
+ for (r = height; r; r--)
+ {
+ dstp += dst_left_bytes;
+ srcp += src_left_bytes;
+ for (w = width; w; w--)
+ *dstp++ = *srcp++;
+ dstp += dst_extra;
+ srcp += src_extra;
+ }
+ }
+ }
+ else
+ {
+ if (dst_off > src_off)
+ {
+ rshift = dst_off - src_off;
+ lshift = 8 - rshift;
+ }
+ else
+ {
+ lshift = src_off - dst_off;
+ rshift = 8 - lshift;
+ /* run the loop one fewer time if necessary */
+ if (src_extra <= dst_extra)
+ {
+ dst_extra++;
+ width--;
+ }
+ else
+ src_extra--;
+ }
+
+ for (r = inkm->ascent + inkm->descent; r; r--)
+ {
+ dstp += dst_left_bytes;
+ srcp += src_left_bytes;
+ bits2 = 0;
+ /* fetch first part of source when necessary */
+ if (dst_off < src_off)
+ bits2 = *srcp++;
+ /*
+ * XXX I bet this does not work when
+ * src_bit_order != src_byte_order && scanlineunit > 1
+ */
+ for (w = width; w; w--)
+ {
+ bits1 = *srcp++;
+ if (src_bit_order == MSBFirst)
+ {
+ *dstp++ = MSBBitRight(bits1, rshift) |
+ MSBBitLeft (bits2, lshift);
+ }
+ else
+ {
+ *dstp++ = LSBBitRight(bits1, rshift) |
+ LSBBitLeft (bits2, lshift);
+ }
+ bits2 = bits1;
+ }
+ /* get the last few bits if we have a place to store them */
+ if (dst_extra > 0)
+ {
+ if (src_bit_order == MSBFirst)
+ *dstp = MSBBitLeft (bits2, lshift);
+ else
+ *dstp = LSBBitLeft (bits2, lshift);
+ }
+ dstp += dst_extra;
+ srcp += src_extra;
+ }
+ }
+ /* skip the amount we just filled in */
+ gd += l->length;
+ }
+
+
+ /* now do the bit, byte, word swapping */
+ if (bitorder != src_bit_order)
+ BitOrderInvert(gdata, size);
+ if (byteorder != src_byte_order)
+ {
+ if (scanlineunit == 2)
+ TwoByteSwap(gdata, size);
+ else if (scanlineunit == 4)
+ FourByteSwap(gdata, size);
+ }
+ fsfree (bitCharsFree);
+ fsfree (inkCharsFree);
+ *num_glyphs = nchars;
+ *data = gdata;
+ *tsize = size;
+ *offsets = lengths;
+
+ return Successful;
+}
+
+/* ARGSUSED */
+int
+GetBitmaps(
+ ClientPtr client,
+ FontPtr pfont,
+ fsBitmapFormat format,
+ Mask flags,
+ unsigned long num_ranges,
+ fsRange *range,
+ int *size,
+ unsigned long *num_glyphs,
+ fsOffset32 **offsets,
+ pointer *data,
+ int *freeData)
+{
+ int err;
+
+ assert(pfont);
+
+ *size = 0;
+ *data = (pointer) 0;
+
+ err = LoadGlyphRanges(client, pfont, TRUE, num_ranges * 2, 0,
+ (fsChar2b *)range);
+
+ if (err != Successful)
+ return err;
+
+ return packGlyphs (client, pfont, format, flags,
+ num_ranges, range, size, num_glyphs,
+ offsets, data, freeData);
+}
diff --git a/app/xfs/difs/difsutils.c b/app/xfs/difs/difsutils.c
new file mode 100644
index 000000000..48f7d5254
--- /dev/null
+++ b/app/xfs/difs/difsutils.c
@@ -0,0 +1,672 @@
+/* $Xorg: difsutils.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * misc utility routines
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/difsutils.c,v 1.6 2001/01/17 23:45:28 dawes Exp $ */
+
+#define XK_LATIN1
+
+#include <difsutils.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include "misc.h"
+#include "globals.h"
+#include "clientstr.h"
+#include "accstr.h"
+#include <X11/fonts/fontstruct.h>
+#include <X11/keysymdef.h>
+
+#include "authstr.h"
+#include "auth.h"
+#include "client.h"
+
+extern ClientPtr currentClient;
+static FontResolutionPtr default_resolutions;
+static int num_resolutions;
+static int default_point_size = 120;
+
+AuthContextPtr
+GetClientAuthorization(void)
+{
+ return currentClient->auth;
+}
+
+void
+SetDefaultPointSize(int ps)
+{
+ int i;
+
+ default_point_size = ps;
+ for (i = 0; i < num_resolutions; i++)
+ default_resolutions[i].point_size = ps;
+}
+
+int
+SetDefaultResolutions(char *str)
+{
+ int num,
+ numr = 0,
+ n;
+ char *s;
+ FontResolutionPtr new,
+ nr;
+ int state;
+
+ s = str;
+ while (*s) { /* count commas */
+ if (*s == ',')
+ numr++;
+ s++;
+ }
+
+ if ((numr % 2) != 1) { /* must be multiple of 2 + 1 */
+ return FSBadResolution;
+ }
+ numr = (numr + 1) / 2;
+ nr = new = (FontResolutionPtr) fsalloc(sizeof(FontResolutionRec)
+ * numr);
+ if (!new)
+ return FSBadAlloc;
+ s = str;
+ num = 0;
+ state = 0;
+ while (*s) {
+ if (*s == ',') {
+ if (state == 0) {
+ nr->x_resolution = num;
+ state++;
+ } else {
+ state = 0;
+ nr->y_resolution = num;
+ nr->point_size = default_point_size;
+ nr++;
+ }
+ num = 0;
+ s++;
+ continue;
+ }
+ if (!isdigit(*s)) {
+ fsfree((char *) new);
+ return FSBadResolution;
+ }
+ n = *s - '0';
+ num = num * 10 + n;
+ s++;
+ }
+
+ /* do the last one */
+ assert(state == 1);
+ nr->y_resolution = num;
+ nr->point_size = default_point_size;
+
+ if (default_resolutions) {
+ fsfree((char *) default_resolutions);
+ }
+ default_resolutions = new;
+ num_resolutions = numr;
+ return FSSuccess;
+}
+
+FontResolutionPtr
+GetClientResolutions(int *num)
+{
+ /* return the client's if it has them, otherwise the default values */
+ if (currentClient->num_resolutions) {
+ *num = currentClient->num_resolutions;
+ return (FontResolutionPtr) currentClient->resolutions;
+ } else {
+ *num = num_resolutions;
+ return default_resolutions;
+ }
+}
+
+int
+GetDefaultPointSize(void)
+{
+ FontResolutionPtr res;
+ int num;
+
+ res = GetClientResolutions(&num);
+ if (res)
+ return res->point_size;
+ else
+ return default_point_size;
+}
+
+Bool
+XpClientIsBitmapClient(ClientPtr client)
+{
+ return TRUE;
+}
+
+Bool
+XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe)
+{
+ return FALSE;
+}
+
+void
+CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length)
+{
+ register int i;
+
+ for (i = 0; i < length; i++, source++, dest++) {
+ if ((*source >= XK_A) && (*source <= XK_Z))
+ *dest = *source + (XK_a - XK_A);
+ else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis))
+ *dest = *source + (XK_agrave - XK_Agrave);
+ else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn))
+ *dest = *source + (XK_oslash - XK_Ooblique);
+ else
+ *dest = *source;
+ }
+ *dest = '\0';
+}
+
+int
+strncmpnocase(
+ char *first,
+ char *second,
+ int n)
+{
+ register unsigned char *ap,
+ *bp;
+
+ for (ap = (unsigned char *) first,
+ bp = (unsigned char *) second;
+ /* SUPPRESS 112 */
+ n > 0 && *ap && *bp; n--, ap++, bp++) {
+ register unsigned char a,
+ b;
+
+ /* SUPPRESS 112 */
+ if ((a = *ap) != (b = *bp)) {
+ /* try lowercasing and try again */
+
+ if ((a >= XK_A) && (a <= XK_Z))
+ a += (XK_a - XK_A);
+ else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
+ a += (XK_agrave - XK_Agrave);
+ else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
+ a += (XK_oslash - XK_Ooblique);
+
+ if ((b >= XK_A) && (b <= XK_Z))
+ b += (XK_a - XK_A);
+ else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis))
+ b += (XK_agrave - XK_Agrave);
+ else if ((b >= XK_Ooblique) && (b <= XK_Thorn))
+ b += (XK_oslash - XK_Ooblique);
+
+ if (a != b)
+ break;
+ }
+ }
+ /* SUPPRESS 112 */
+ return (n ? (((int) *ap) - ((int) *bp)) : 0);
+}
+
+void
+NoopDDA(void)
+{
+}
+
+/* host list manipulation */
+int
+AddHost(
+ HostList *list,
+ HostAddress *addr)
+{
+ HostAddress *new;
+
+ new = (HostAddress *) fsalloc(sizeof(HostAddress));
+ if (!new)
+ return FSBadAlloc;
+ new->address = (pointer) fsalloc(addr->addr_len);
+ if (!new->address) {
+ fsfree((char *) addr);
+ return FSBadAlloc;
+ }
+ new->type = addr->type;
+ new->addr_len = addr->addr_len;
+ memmove( (char *) new->address, (char *) addr->address, new->addr_len);
+
+ new->next = *list;
+ *list = new;
+ return FSSuccess;
+}
+
+int
+RemoveHost(
+ HostList *list,
+ HostAddress *addr)
+{
+ HostAddress *t,
+ *last;
+
+ last = (HostAddress *) 0;
+ t = *list;
+ while (t) {
+ if (t->type == addr->type &&
+ t->addr_len == addr->addr_len &&
+ memcmp((char *) t->address, (char *) addr->address,
+ min(t->addr_len, addr->addr_len)) == 0) {
+ if (last) {
+ last->next = t->next;
+ } else {
+ *list = t->next;
+ }
+ fsfree((char *) t->address);
+ fsfree((char *) t);
+ return FSSuccess;
+ }
+ last = t;
+ t = t->next;
+ }
+ return FSBadName; /* bad host name */
+}
+
+Bool
+ValidHost(
+ HostList list,
+ HostAddress *addr)
+{
+ HostAddress *t;
+
+ t = list;
+ while (t) {
+ if (t->type == addr->type &&
+ t->addr_len == addr->addr_len &&
+ memcmp((char *) t->address, (char *) addr->address,
+ min(t->addr_len, addr->addr_len)) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* block & wakeup handlers */
+
+typedef struct _BlockHandler {
+ BlockHandlerProcPtr BlockHandler;
+ DifsWakeupFunc WakeupHandler;
+ pointer blockData;
+ Bool deleted;
+} BlockHandlerRec, *BlockHandlerPtr;
+
+static BlockHandlerPtr handlers;
+static int numHandlers;
+static int sizeHandlers;
+static Bool inHandler;
+static Bool handlerDeleted;
+
+/* called from the OS layer */
+void
+BlockHandler(
+ OSTimePtr pTimeout, /* DIX doesn't want to know how OS represents
+ * time */
+ pointer pReadmask) /* nor how it represents the set of
+ * descriptors */
+{
+ register int i,
+ j;
+
+ ++inHandler;
+ for (i = 0; i < numHandlers; i++)
+ (*handlers[i].BlockHandler) (handlers[i].blockData,
+ pTimeout, pReadmask);
+ if (handlerDeleted) {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted) {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j + 1];
+ numHandlers--;
+ } else
+ i++;
+ }
+ --inHandler;
+}
+
+
+void
+WakeupHandler(
+ int result, /* result from the wait */
+ unsigned long * pReadmask) /* the resulting descriptor mask */
+{
+ register int i,
+ j;
+
+ ++inHandler;
+ for (i = numHandlers - 1; i >= 0; i--)
+ (*handlers[i].WakeupHandler) (handlers[i].blockData,
+ result, pReadmask);
+ if (handlerDeleted) {
+ for (i = 0; i < numHandlers;)
+ if (handlers[i].deleted) {
+ for (j = i; j < numHandlers - 1; j++)
+ handlers[j] = handlers[j + 1];
+ numHandlers--;
+ } else
+ i++;
+ }
+ --inHandler;
+}
+
+/* Reentrant with BlockHandler and WakeupHandler, except wakeup won't
+ * get called until next time
+ */
+
+Bool
+RegisterBlockAndWakeupHandlers(
+ BlockHandlerProcPtr blockHandler,
+ DifsWakeupFunc wakeupHandler,
+ pointer blockData)
+{
+ BlockHandlerPtr new;
+
+ if (numHandlers >= sizeHandlers) {
+ new = (BlockHandlerPtr) fsrealloc(handlers, (numHandlers + 1) *
+ sizeof(BlockHandlerRec));
+ if (!new)
+ return FALSE;
+ handlers = new;
+ sizeHandlers = numHandlers + 1;
+ }
+ handlers[numHandlers].BlockHandler = blockHandler;
+ handlers[numHandlers].WakeupHandler = wakeupHandler;
+ handlers[numHandlers].blockData = blockData;
+ numHandlers = numHandlers + 1;
+ return TRUE;
+}
+
+void
+RemoveBlockAndWakeupHandlers(
+ BlockHandlerProcPtr blockHandler,
+ DifsWakeupFunc wakeupHandler,
+ pointer blockData)
+{
+ int i;
+
+ for (i = 0; i < numHandlers; i++)
+ if (handlers[i].BlockHandler == blockHandler &&
+ handlers[i].WakeupHandler == wakeupHandler &&
+ handlers[i].blockData == blockData) {
+ if (inHandler) {
+ handlerDeleted = TRUE;
+ handlers[i].deleted = TRUE;
+ } else {
+ for (; i < numHandlers - 1; i++)
+ handlers[i] = handlers[i + 1];
+ numHandlers--;
+ }
+ break;
+ }
+}
+
+void
+InitBlockAndWakeupHandlers(void)
+{
+ fsfree(handlers);
+ handlers = (BlockHandlerPtr) 0;
+ numHandlers = 0;
+ sizeHandlers = 0;
+}
+
+/*
+ * A general work queue. Perform some task before the server
+ * sleeps for input.
+ */
+
+WorkQueuePtr workQueue;
+static WorkQueuePtr *workQueueLast = &workQueue;
+
+/* ARGSUSED */
+void
+ProcessWorkQueue(void)
+{
+ WorkQueuePtr q,
+ n,
+ p;
+
+ p = NULL;
+ /*
+ * Scan the work queue once, calling each function. Those which return
+ * TRUE are removed from the queue, otherwise they will be called again.
+ * This must be reentrant with QueueWorkProc, hence the crufty usage of
+ * variables.
+ */
+ for (q = workQueue; q; q = n) {
+ if ((*q->function) (q->client, q->closure)) {
+ /* remove q from the list */
+ n = q->next; /* don't fetch until after func called */
+ if (p)
+ p->next = n;
+ else
+ workQueue = n;
+ fsfree(q);
+ } else {
+ n = q->next; /* don't fetch until after func called */
+ p = q;
+ }
+ }
+ if (p)
+ workQueueLast = &p->next;
+ else {
+ workQueueLast = &workQueue;
+ }
+}
+
+Bool
+QueueWorkProc(
+ Bool (*function) (ClientPtr, pointer),
+ ClientPtr client,
+ pointer data)
+{
+ WorkQueuePtr q;
+
+ q = (WorkQueuePtr) fsalloc(sizeof *q);
+ if (!q)
+ return FALSE;
+ q->function = function;
+ q->client = client;
+ q->closure = data;
+ q->next = NULL;
+ *workQueueLast = q;
+ workQueueLast = &q->next;
+ return TRUE;
+}
+
+/*
+ * Manage a queue of sleeping clients, awakening them
+ * when requested, by using the OS functions IgnoreClient
+ * and AttendClient. Note that this *ignores* the troubles
+ * with request data interleaving itself with events, but
+ * we'll leave that until a later time.
+ */
+
+typedef struct _SleepQueue {
+ struct _SleepQueue *next;
+ ClientPtr client;
+ Bool (*function) (ClientPtr, pointer);
+ pointer closure;
+} SleepQueueRec, *SleepQueuePtr;
+
+static SleepQueuePtr sleepQueue = NULL;
+
+Bool
+ClientSleep(
+ ClientPtr client,
+ Bool (*function) (ClientPtr, pointer),
+ pointer data)
+{
+ SleepQueuePtr q;
+
+ q = (SleepQueuePtr) fsalloc(sizeof *q);
+ if (!q)
+ return FALSE;
+
+ IgnoreClient(client);
+ q->next = sleepQueue;
+ q->client = client;
+ q->function = function;
+ q->closure = data;
+ sleepQueue = q;
+ return TRUE;
+}
+
+Bool
+ClientSignal(ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client) {
+ return QueueWorkProc(q->function, q->client, q->closure);
+ }
+ return FALSE;
+}
+
+void
+ClientWakeup(ClientPtr client)
+{
+ SleepQueuePtr q,
+ *prev;
+
+ prev = &sleepQueue;
+ while ((q = *prev) != (SleepQueuePtr) 0) {
+ if (q->client == client) {
+ *prev = q->next;
+ fsfree(q);
+ if (client->clientGone == CLIENT_GONE)
+ CloseDownClient(client);
+ else
+ AttendClient(client);
+ break;
+ }
+ prev = &q->next;
+ }
+}
+
+Bool
+ClientIsAsleep(ClientPtr client)
+{
+ SleepQueuePtr q;
+
+ for (q = sleepQueue; q; q = q->next)
+ if (q->client == client)
+ return TRUE;
+ return FALSE;
+}
+
+pointer
+Xalloc(unsigned long m)
+{
+ return fsalloc(m);
+}
+
+pointer
+Xrealloc(pointer n, unsigned long m)
+{
+ return fsrealloc(n, m);
+}
+
+void
+Xfree(unsigned long *n)
+{
+ fsfree(n);
+}
+
+pointer
+Xcalloc(unsigned long n)
+{
+ pointer ret;
+
+ ret = fsalloc(n);
+ if (ret && n)
+ bzero(ret, n);
+ return ret;
+}
+
+int
+set_font_authorizations(char **authorizations, int *authlen, ClientPtr client)
+{
+#define AUTH1_NAME "hp-hostname-1"
+#define AUTH2_NAME "hp-printername-1"
+ static char result[1024];
+ char *p;
+ AuthContextPtr acp = client->auth;
+ int len1, len2;
+
+ if (acp != NULL && acp->authname != NULL && acp->authdata != NULL &&
+ (!strcmp(AUTH1_NAME, acp->authname) ||
+ !strcmp(AUTH2_NAME, acp->authname)) &&
+ (len1 = strlen(acp->authname) + 1) +
+ (len2 = strlen(acp->authdata) + 1) + 2 * sizeof(short) <= 1024)
+ {
+ p = result;
+ *p++ = len1 >> 8;
+ *p++ = len1 &0xff;
+ *p++ = len2 >> 8;
+ *p++ = len2 & 0xff;
+ memmove( p, acp->authname, len1);
+ p += len1;
+ memmove( p, acp->authdata, len2);
+ p += len2;
+ *authlen = p - result;
+ *authorizations = result;
+ return 1;
+ }
+
+ *authlen = 0;
+ return 0;
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return client->auth_generation;
+}
diff --git a/app/xfs/difs/dispatch.c b/app/xfs/difs/dispatch.c
new file mode 100644
index 000000000..f1a0a859a
--- /dev/null
+++ b/app/xfs/difs/dispatch.c
@@ -0,0 +1,1138 @@
+/* $Xorg: dispatch.c,v 1.6 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * protocol dispatcher
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/dispatch.c,v 3.12 2001/12/14 20:01:33 dawes Exp $ */
+
+#include <stdlib.h>
+#include "dispatch.h"
+#include "swapreq.h"
+#include "swaprep.h"
+
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "authstr.h"
+#include "osstruct.h"
+#include "extentst.h"
+#include "globals.h"
+#include "fsresource.h"
+#include "difsfnst.h"
+#include <X11/fonts/fontstruct.h>
+#include "site.h"
+#include "fsevents.h"
+#include "cache.h"
+#include "globals.h"
+#include "difs.h"
+
+static void kill_all_clients(void);
+
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+ClientPtr currentClient;
+
+static int nClients = 0;
+static int nextFreeClientID;
+
+extern char *ConnectionInfo;
+extern int ConnInfoLen;
+
+extern char *configfilename;
+
+extern Bool drone_server;
+
+#define MAJOROP ((fsReq *)client->requestBuffer)->reqType
+
+#define ALL_FORMAT_BITS (BitmapFormatByteOrderMask | \
+ BitmapFormatBitOrderMask | \
+ BitmapFormatScanlineUnitMask | \
+ BitmapFormatScanlinePadMask | \
+ BitmapFormatImageRectMask)
+
+#define ALL_FORMAT_MASK_BITS (BitmapFormatMaskByte | \
+ BitmapFormatMaskBit | \
+ BitmapFormatMaskImageRectangle | \
+ BitmapFormatMaskScanLinePad | \
+ BitmapFormatMaskScanLineUnit)
+
+void
+Dispatch(void)
+{
+ int nready,
+ result;
+ int *clientReady;
+ ClientPtr client;
+ int op;
+
+ nextFreeClientID = MINCLIENT;
+ nClients = 0;
+
+ clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ while (1) {
+ /* wait for something */
+ nready = WaitForSomething(clientReady);
+
+ while (!dispatchException && (--nready >= 0)) {
+ client = currentClient = clients[clientReady[nready]];
+
+ /* Client can be NULL if CloseDownClient() is called during
+ this dispatchException loop. */
+ if (client == (ClientPtr)NULL) continue;
+
+ isItTimeToYield = FALSE;
+
+ while (!isItTimeToYield) {
+ result = ReadRequest(client);
+ if (result <= 0) {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+ client->sequence++;
+
+ if (result > (MAX_REQUEST_SIZE << 2))
+ result = FSBadLength;
+ else
+ {
+ op = MAJOROP;
+ if (op >= NUM_PROC_VECTORS)
+ result = ProcBadRequest (client);
+ else if (*client->requestVector[op] != NULL)
+ result = (*client->requestVector[op]) (client);
+ else
+ result = FSBadRequest;
+ }
+ if (result != FSSuccess) {
+ if (client->noClientException != FSSuccess)
+ CloseDownClient(client);
+ break;
+ }
+ }
+ FlushAllOutput ();
+ }
+ /* reset if server is a drone and has run out of clients */
+ if (drone_server && nClients == 0) {
+ dispatchException |= DE_RESET;
+ }
+ if (dispatchException) {
+ /* re-read the config file */
+ if (dispatchException & DE_RECONFIG) {
+ NoticeF("re-reading config file\n");
+ if (ReadConfigFile(configfilename) != FSSuccess)
+ ErrorF("couldn't parse config file\n");
+ SetConfigValues();
+ dispatchException &= ~DE_RECONFIG;
+ }
+ /* flush all the caches */
+ if (dispatchException & DE_FLUSH) {
+ NoticeF("flushing all caches\n");
+ CacheReset();
+ dispatchException &= ~DE_FLUSH;
+ }
+ /* reset */
+ if (dispatchException & DE_RESET) {
+ NoticeF("resetting\n");
+ break;
+ }
+ /* die *now* */
+ if (dispatchException & DE_TERMINATE) {
+ NoticeF("terminating\n");
+ kill_all_clients();
+ CloseSockets();
+ CloseErrors();
+ exit(0);
+ break;
+ }
+ }
+ }
+ kill_all_clients();
+ dispatchException = 0;
+}
+
+int
+ProcInitialConnection(ClientPtr client)
+{
+ REQUEST(fsFakeReq);
+ fsConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ nClients++;
+ prefix = (fsConnClientPrefix *) stuff+1;
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -2);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) {
+ int status;
+
+ client->swapped = TRUE;
+ status = SwapConnClientPrefix(client, prefix);
+ if (status != FSSuccess)
+ return (status);
+ }
+ client->major_version = prefix->major_version;
+ client->minor_version = prefix->minor_version;
+ stuff->reqType = 2;
+ stuff->length += prefix->auth_len;
+ if (client->swapped) {
+ stuff->length = lswaps(stuff->length);
+ }
+ ResetCurrentRequest(client);
+ return client->noClientException;
+}
+
+int
+ProcEstablishConnection(ClientPtr client)
+{
+ fsConnClientPrefix *prefix;
+ fsConnSetup csp;
+ int ret;
+ pointer auth_data;
+ char *ad;
+ char *server_auth_data;
+ AuthPtr client_auth;
+ int i,
+ num_alts,
+ altlen,
+ auth_accept,
+ auth_index,
+ auth_len;
+ AlternateServerPtr altservers;
+
+ REQUEST(fsFakeReq);
+
+ prefix = (fsConnClientPrefix *) stuff+1;
+ auth_data = prefix + sz_fsConnClientPrefix;
+ client_auth = (AuthPtr) ALLOCATE_LOCAL(prefix->num_auths * sizeof(AuthRec));
+ if (!client_auth) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+/* XXXX -- this needs work for multiple auth replies */
+
+ /* build up a list of the stuff */
+ for (i = 0, ad = auth_data; i < (int)prefix->num_auths; i++) {
+ if (ad - (char *)auth_data > (stuff->length << 2) - 4) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+ /* copy carefully in case wire data is not aligned */
+ client_auth[i].namelen = (((unsigned char *)ad)[0] << 8) +
+ ((unsigned char *)ad)[1];
+ ad += 2;
+ client_auth[i].datalen = (((unsigned char *)ad)[0] << 8) +
+ ((unsigned char *)ad)[1];
+ ad += 2;
+ client_auth[i].name = (char *) ad;
+ ad += client_auth[i].namelen;
+ client_auth[i].data = (char *) ad;
+ ad += client_auth[i].datalen;
+ }
+ if (!(int)prefix->num_auths)
+ ad += 4;
+ if (ad - (char *)auth_data > (stuff->length << 2)) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+
+ num_alts = ListAlternateServers(&altservers);
+ for (i = 0, altlen = 0; i < num_alts; i++) {
+ /* subset + len + namelen + pad */
+ altlen += (2 + altservers[i].namelen + 3) >> 2;
+ }
+
+ auth_index = prefix->num_auths;
+ client->auth_generation = 0;
+ ret = CheckClientAuthorization(client, client_auth,
+ &auth_accept, &auth_index, &auth_len, &server_auth_data);
+ if (auth_index > 0)
+ {
+ AuthContextPtr authp;
+ authp = (AuthContextPtr) fsalloc(sizeof(AuthContextRec));
+ if (!authp) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ authp->authname = 0;
+ authp->authdata = 0;
+ authp->authname =
+ (char *) fsalloc(client_auth[auth_index - 1].namelen + 1);
+ authp->authdata =
+ (char *) fsalloc(client_auth[auth_index - 1].datalen + 1);
+ if (!authp->authname || !authp->authdata) {
+ fsfree((char *) authp->authname);
+ fsfree((char *) authp->authdata);
+ fsfree((char *) authp);
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ memmove( authp->authname, client_auth[auth_index - 1].name,
+ client_auth[auth_index - 1].namelen);
+ memmove( authp->authdata, client_auth[auth_index - 1].data,
+ client_auth[auth_index - 1].datalen);
+ /* Save it with a zero resource id... subsequent
+ SetAuthorizations of None will find it. And it will be freed
+ by FreeClientResources when the connection closes. */
+ if (!AddResource(client->index, 0, RT_AUTHCONT,(pointer) authp))
+ {
+ fsfree((char *) authp->authname);
+ fsfree((char *) authp->authdata);
+ fsfree((char *) authp);
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ client->auth = client->default_auth = authp;
+ }
+ else
+ client->auth = client->default_auth = (AuthContextPtr)0;
+
+ DEALLOCATE_LOCAL(client_auth);
+
+ if (ret != FSSuccess) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ csp.status = auth_accept;
+ if (client->major_version == 1)
+ /* we implement backwards compatibility for version 1.0 */
+ csp.major_version = client->major_version;
+ else
+ csp.major_version = FS_PROTOCOL;
+ csp.minor_version = FS_PROTOCOL_MINOR;
+ csp.num_alternates = num_alts;
+ csp.alternate_len = altlen;
+ csp.auth_len = auth_len >> 2;
+ csp.auth_index = auth_index;
+ if (client->swapped) {
+ WriteSConnSetup(client, &csp);
+ } else {
+ (void) WriteToClient(client, SIZEOF(fsConnSetup), (char *) &csp);
+ }
+
+ /* send the alternates info */
+ for (i = 0; i < num_alts; i++) {
+ char tmp[258];
+
+ /* WriteToClient pads, so we have to fake some things */
+ tmp[0] = altservers[i].subset;
+ tmp[1] = altservers[i].namelen;
+ memmove( (char *) &tmp[2], altservers[i].name, altservers[i].namelen);
+ (void) WriteToClient(client, altservers[i].namelen + 2, tmp);
+ }
+
+ if (auth_len)
+ (void) WriteToClient(client, auth_len, (char *) server_auth_data);
+
+ if (auth_accept != AuthSuccess) {
+ nClients--;
+ return (client->noClientException = -2);
+ }
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+ if (client->swapped)
+ (void) WriteSConnectionInfo(client, ConnInfoLen, ConnectionInfo);
+ else
+ (void) WriteToClient(client, ConnInfoLen, ConnectionInfo);
+
+#ifdef DEBUG
+ fprintf(stderr, "Establishing new connection\n");
+#endif
+
+ return client->noClientException;
+}
+
+/*
+ * NOTE -- the incoming data may be mangled
+ */
+
+void
+DoSendErrToClient(
+ ClientPtr client,
+ int error,
+ pointer data) /* resource id, format, resolution, etc */
+{
+ fsError rep;
+ int extralen = 0;
+
+ switch (error) {
+ case FSBadFormat:
+ extralen = SIZEOF(fsBitmapFormat);
+ break;
+ case FSBadFont:
+ case FSBadAccessContext:
+ case FSBadIDChoice:
+ case FSBadEventMask:
+ if (data) {
+ if (client->swapped)
+ SwapLongs((long *) data, 1);
+ extralen = 4;
+ }
+ break;
+ case FSBadRange:
+ extralen = SIZEOF(fsRange);
+ break;
+ case FSBadResolution:
+ if (data) {
+ if (client->swapped)
+ SwapShorts((short *) data, 1);
+ /* note sneaky hack */
+ rep.pad = *(CARD16 *) data;
+ data = (char *)data + 2;
+ extralen = 4;
+ }
+ break;
+ case FSBadLength:
+ if (data) {
+ if (client->swapped)
+ SwapLongs((long *) data, 1);
+ extralen = 4;
+ }
+ break;
+ default:
+ /* nothing else to send */
+ break;
+ }
+
+ rep.type = FS_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.request = error;
+ rep.major_opcode = ((fsReq *) client->requestBuffer)->reqType;
+ rep.minor_opcode = MinorOpcodeOfRequest(client),
+ rep.timestamp = GetTimeInMillis();
+ rep.length = (SIZEOF(fsError) + extralen) >> 2;
+
+ WriteErrorToClient(client, &rep);
+
+ if (extralen)
+ WriteToClient(client, extralen, (char *) data);
+}
+
+/* ARGSUSED */
+int
+ProcBadRequest(ClientPtr client)
+{
+ SendErrToClient(client, FSBadRequest, NULL);
+ return FSBadRequest;
+}
+
+int
+ProcNoop(ClientPtr client)
+{
+ REQUEST(fsReq);
+ REQUEST_AT_LEAST_SIZE(fsReq);
+
+ return client->noClientException;
+}
+
+int
+ProcListCatalogues(ClientPtr client)
+{
+ int len,
+ num;
+ char *catalogues;
+ fsListCataloguesReply rep;
+
+ REQUEST(fsListCataloguesReq);
+ REQUEST_AT_LEAST_SIZE(fsListCataloguesReq);
+
+ num = ListCatalogues((char *)stuff + SIZEOF(fsListCataloguesReq),
+ stuff->nbytes, stuff->maxNames,
+ &catalogues, &len);
+ rep.type = FS_Reply;
+ rep.num_replies = 0;
+ rep.num_catalogues = num;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (SIZEOF(fsListCataloguesReply) + len + 3) >> 2;
+
+ WriteReplyToClient(client, SIZEOF(fsListCataloguesReply), &rep);
+ (void) WriteToClient(client, len, (char *) catalogues);
+ fsfree((char *) catalogues);
+ return client->noClientException;
+}
+
+int
+ProcSetCatalogues(ClientPtr client)
+{
+ char *new_cat;
+ int err,
+ len;
+ int num;
+
+ REQUEST(fsSetCataloguesReq);
+ REQUEST_AT_LEAST_SIZE(fsSetCataloguesReq);
+
+ if (stuff->num_catalogues == 0) {
+ /* use the default */
+ num = ListCatalogues("*", 1, 10000, &new_cat, &len);
+ } else {
+ num = stuff->num_catalogues;
+ err = ValidateCatalogues(&num, (char *)stuff + SIZEOF(fsSetCataloguesReq));
+ if (err == FSSuccess) {
+ len = (stuff->length << 2) - SIZEOF(fsSetCataloguesReq);
+ new_cat = (char *) fsalloc(len);
+ if (!new_cat)
+ return FSBadAlloc;
+ memmove( new_cat, (char *)stuff + SIZEOF(fsSetCataloguesReq), len);
+ } else {
+ SendErrToClient(client, err, (pointer) &num);
+ return err;
+ }
+ }
+ if (client->catalogues)
+ fsfree((char *) client->catalogues);
+ client->catalogues = new_cat;
+ client->num_catalogues = num;
+ return client->noClientException;
+}
+
+int
+ProcGetCatalogues(ClientPtr client)
+{
+ int len,
+ i,
+ size;
+ char *cp;
+ fsGetCataloguesReply rep;
+
+ REQUEST(fsGetCataloguesReq);
+ REQUEST_AT_LEAST_SIZE(fsGetCataloguesReq);
+
+ for (i = 0, len = 0, cp = client->catalogues;
+ i < client->num_catalogues; i++) {
+ size = *cp++;
+ len += size + 1; /* str length + size byte */
+ cp += size;
+ }
+
+ rep.type = FS_Reply;
+ rep.num_catalogues = client->num_catalogues;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (SIZEOF(fsGetCataloguesReply) + len + 3) >> 2;
+
+ WriteReplyToClient(client, SIZEOF(fsGetCataloguesReply), &rep);
+ (void) WriteToClient(client, len, client->catalogues);
+
+ return client->noClientException;
+}
+
+int
+ProcCreateAC(ClientPtr client)
+{
+ fsCreateACReply rep;
+ AuthPtr acp;
+ AuthContextPtr authp;
+ int accept,
+ i,
+ err,
+ index,
+ size;
+ char *ad;
+ char *auth_data;
+
+ REQUEST(fsCreateACReq);
+ REQUEST_AT_LEAST_SIZE(fsCreateACReq);
+
+ authp = (AuthContextPtr) LookupIDByType(client->index, stuff->acid,
+ RT_AUTHCONT);
+ if (authp) {
+ int aligned_acid = stuff->acid;
+ SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_acid);
+ return FSBadIDChoice;
+ }
+ acp = 0;
+ if (stuff->num_auths)
+ {
+ acp = (AuthPtr) ALLOCATE_LOCAL(stuff->num_auths * sizeof(AuthRec));
+ if (!acp) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ }
+ /* build up a list of the stuff */
+ for (i = 0, ad = (char *)stuff + SIZEOF(fsCreateACReq);
+ i < (int)stuff->num_auths; i++) {
+ if (ad - (char *)stuff + SIZEOF(fsCreateACReq) >
+ (stuff->length << 2) - 4) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+ /* copy carefully in case data is not aligned */
+ acp[i].namelen = (((unsigned char *)ad)[0] << 8) +
+ ((unsigned char *)ad)[1];
+ ad += 2;
+ acp[i].datalen = (((unsigned char *)ad)[0] << 8) +
+ ((unsigned char *)ad)[1];
+ ad += 2;
+ acp[i].name = (char *) ad;
+ ad += acp[i].namelen;
+ acp[i].data = (char *) ad;
+ ad += acp[i].datalen;
+ }
+ if (!(int)stuff->num_auths)
+ ad += 4;
+ if (ad - (char *)stuff > (stuff->length << 2)) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+
+/* XXX needs work for AuthContinue */
+ index = stuff->num_auths;
+ err = CheckClientAuthorization(client, acp, &accept, &index, &size,
+ &auth_data);
+
+ if (err != FSSuccess) {
+ SendErrToClient(client, err, (pointer) 0);
+ if (acp)
+ DEALLOCATE_LOCAL(acp);
+ return err;
+ }
+ authp = (AuthContextPtr) fsalloc(sizeof(AuthContextRec));
+ if (!authp) {
+ goto alloc_failure;
+ }
+ authp->authname = 0;
+ authp->authdata = 0;
+ if (index > 0)
+ {
+ authp->authname = (char *) fsalloc(acp[index - 1].namelen + 1);
+ authp->authdata = (char *) fsalloc(acp[index - 1].datalen + 1);
+ if (!authp->authname || !authp->authdata) {
+ fsfree((char *) authp->authname);
+ fsfree((char *) authp->authdata);
+ fsfree((char *) authp);
+ goto alloc_failure;
+ }
+ memmove( authp->authname, acp[index - 1].name, acp[index - 1].namelen);
+ memmove( authp->authdata, acp[index - 1].data, acp[index - 1].datalen);
+ }
+ else
+ size = 0;
+ authp->acid = stuff->acid;
+ if (!AddResource(client->index, stuff->acid, RT_AUTHCONT,(pointer) authp))
+ {
+alloc_failure:
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ if (acp)
+ DEALLOCATE_LOCAL(acp);
+ return FSBadAlloc;
+ }
+ DEALLOCATE_LOCAL(acp);
+ rep.type = FS_Reply;
+ rep.status = accept;
+ rep.auth_index = index;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (SIZEOF(fsCreateACReply) + size) >> 2;
+
+ WriteReplyToClient(client, SIZEOF(fsCreateACReply), &rep);
+ if (size)
+ (void) WriteToClient(client, size, auth_data);
+
+ return client->noClientException;
+}
+
+/* ARGSUSED */
+int
+DeleteAuthCont (pointer value, FSID id)
+{
+ AuthContextPtr authp = (AuthContextPtr) value;
+
+ if (authp->authname)
+ fsfree (authp->authname);
+ if (authp->authdata)
+ fsfree (authp->authdata);
+ fsfree (authp);
+ return 1;
+}
+
+int
+ProcFreeAC(ClientPtr client)
+{
+ AuthContextPtr authp;
+
+ REQUEST(fsFreeACReq);
+ REQUEST_AT_LEAST_SIZE(fsFreeACReq);
+ authp = (AuthContextPtr) LookupIDByType(client->index, stuff->id,
+ RT_AUTHCONT);
+ if (!authp) {
+ int aligned_id = stuff->id;
+ SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_id);
+ return FSBadIDChoice;
+ }
+ if (client->auth == authp)
+ client->auth = client->default_auth;
+ FreeResource(client->index, stuff->id, RT_NONE);
+ return client->noClientException;
+}
+
+int
+ProcSetAuthorization(ClientPtr client)
+{
+ AuthContextPtr acp;
+
+ REQUEST(fsSetAuthorizationReq);
+ REQUEST_AT_LEAST_SIZE(fsSetAuthorizationReq);
+ acp = (AuthContextPtr) LookupIDByType(client->index, stuff->id,
+ RT_AUTHCONT);
+ if (!acp) {
+ int aligned_id = stuff->id;
+ SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_id);
+ return FSBadIDChoice;
+ }
+ client->auth = acp; /* XXX does this need a refcount? */
+ return client->noClientException;
+}
+
+int
+ProcSetResolution(ClientPtr client)
+{
+ fsResolution *new_res;
+
+ REQUEST(fsSetResolutionReq);
+ REQUEST_AT_LEAST_SIZE(fsSetResolutionReq);
+
+ if ((stuff->length << 2) - SIZEOF(fsSetResolutionReq) <
+ stuff->num_resolutions * SIZEOF(fsResolution)) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, &lengthword);
+ return FSBadLength;
+ }
+ new_res = (fsResolution *)
+ fsalloc(SIZEOF(fsResolution) * stuff->num_resolutions);
+ if (!new_res) {
+ SendErrToClient(client, FSBadAlloc, NULL);
+ return FSBadAlloc;
+ }
+ fsfree((char *) client->resolutions);
+ memmove( (char *) new_res, (char *)stuff + SIZEOF(fsSetResolutionReq),
+ (stuff->num_resolutions * SIZEOF(fsResolution)));
+ client->resolutions = new_res;
+ client->num_resolutions = stuff->num_resolutions;
+
+ return client->noClientException;
+}
+
+int
+ProcGetResolution(ClientPtr client)
+{
+ fsGetResolutionReply reply;
+
+ REQUEST(fsReq);
+ REQUEST_AT_LEAST_SIZE(fsReq);
+
+ if ((stuff->length << 2) - SIZEOF(fsResolution) < client->num_resolutions *
+ sizeof(fsResolution)) {
+ int lengthword = stuff->length;
+
+ SendErrToClient(client, FSBadLength, &lengthword);
+ return FSBadLength;
+ }
+ reply.type = FS_Reply;
+ reply.num_resolutions = client->num_resolutions;
+ reply.sequenceNumber = client->sequence;
+ reply.length = (SIZEOF(fsGetResolutionReply) +
+ client->num_resolutions * SIZEOF(fsResolution)) >> 2;
+
+ WriteReplyToClient(client, SIZEOF(fsGetResolutionReply), &reply);
+ if (client->swapped)
+ client->pSwapReplyFunc = CopySwap16Write;
+
+ WriteSwappedDataToClient(client,
+ (client->num_resolutions * SIZEOF(fsResolution)), (short *)client->resolutions);
+
+ return client->noClientException;
+}
+
+int
+ProcListFonts(ClientPtr client)
+{
+ REQUEST(fsListFontsReq);
+ REQUEST_FIXED_SIZE(fsListFontsReq, stuff->nbytes);
+
+ return ListFonts(client, stuff->nbytes,
+ (unsigned char *)stuff + SIZEOF(fsListFontsReq),
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithXInfo(ClientPtr client)
+{
+ REQUEST(fsListFontsWithXInfoReq);
+ REQUEST_FIXED_SIZE(fsListFontsWithXInfoReq, stuff->nbytes);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *)stuff + SIZEOF(fsListFontsWithXInfoReq), stuff->maxNames);
+}
+
+int
+ProcOpenBitmapFont(ClientPtr client)
+{
+ FontPtr pfont;
+ int nbytes,
+ err;
+ unsigned char *fname;
+
+ REQUEST(fsOpenBitmapFontReq);
+ fname = (unsigned char *)stuff + SIZEOF(fsOpenBitmapFontReq);
+ nbytes = *fname++;
+
+ REQUEST_FIXED_SIZE(fsOpenBitmapFontReq, (nbytes + 1));
+
+ pfont = (FontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT);
+ if (pfont) {
+ int aligned_fid = stuff->fid;
+ SendErrToClient(client, FSBadIDChoice, (pointer) &aligned_fid);
+ return FSBadIDChoice;
+ }
+ if (stuff->format_hint != 0 &&
+ stuff->format_hint & ~ALL_FORMAT_BITS) {
+ int aligned_format_hint = stuff->format_hint;
+ SendErrToClient(client, FSBadFormat, (pointer) &aligned_format_hint);
+ return FSBadFormat;
+ }
+ if (stuff->format_mask & ~ALL_FORMAT_MASK_BITS) {
+ int aligned_format_mask = stuff->format_mask;
+ SendErrToClient(client, FSBadFormat, (pointer) &aligned_format_mask);
+ return FSBadFormat;
+ }
+ err = OpenFont(client, stuff->fid, stuff->format_hint, stuff->format_mask,
+ nbytes, (char *) fname);
+
+ if (err == FSSuccess) {
+ return client->noClientException;
+ } else {
+ return err;
+ }
+}
+
+int
+ProcQueryXInfo(ClientPtr client)
+{
+ ClientFontPtr cfp;
+ int err,
+ lendata;
+ fsQueryXInfoReply reply;
+ fsPropInfo *prop_info;
+
+ REQUEST(fsQueryXInfoReq);
+
+ REQUEST_AT_LEAST_SIZE(fsQueryXInfoReq);
+
+ cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT);
+ if (!cfp) {
+ int aligned_id = stuff->id;
+ SendErrToClient(client, FSBadFont, (pointer) &aligned_id);
+ return FSBadFont;
+ }
+ reply.type = FS_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ /* get the header */
+ fsPack_XFontInfoHeader(&cfp->font->info, &reply, client->major_version);
+ err = convert_props(&cfp->font->info, &prop_info);
+
+ switch (err)
+ {
+ case Successful:
+ break;
+ case AllocError:
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return err;
+ default:
+ ErrorF("ProcQueryXInfo: unexpected return val %d from convert_props\n",
+ err);
+ SendErrToClient(client, FSBadImplementation, (pointer) 0);
+ return err;
+ }
+ lendata = SIZEOF(fsPropInfo) +
+ prop_info->num_offsets * SIZEOF(fsPropOffset) +
+ prop_info->data_len;
+
+ reply.length = (SIZEOF(fsQueryXInfoReply) + lendata + 3) >> 2;
+ WriteReplyToClient(client, SIZEOF(fsQueryXInfoReply), &reply);
+
+ if (client->swapped)
+ SwapPropInfo(prop_info);
+ (void) WriteToClient(client, lendata, (char *) prop_info);
+
+ fsfree((char *) prop_info);
+ return client->noClientException;
+}
+
+int
+ProcQueryXExtents(ClientPtr client)
+{
+ ClientFontPtr cfp;
+ int err;
+ int item_size;
+
+ REQUEST(fsQueryXExtents8Req);
+
+ REQUEST_AT_LEAST_SIZE(fsQueryXExtents8Req);
+
+ cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT);
+ if (!cfp) {
+ int aligned_fid = stuff->fid;
+ SendErrToClient(client, FSBadFont, (pointer) &aligned_fid);
+ return FSBadFont;
+ }
+ item_size = (stuff->reqType == FS_QueryXExtents8) ? 1 : 2;
+
+ /* get the extents */
+ err = QueryExtents(client, cfp, item_size,
+ stuff->num_ranges, stuff->range,
+ (char *)stuff + SIZEOF(fsQueryXExtents8Req));
+
+ if (err != FSSuccess) {
+ return err;
+ } else
+ return client->noClientException;
+}
+
+int
+ProcQueryXBitmaps(ClientPtr client)
+{
+ ClientFontPtr cfp;
+ int err;
+ int item_size;
+
+ REQUEST(fsQueryXBitmaps8Req);
+
+ REQUEST_AT_LEAST_SIZE(fsQueryXBitmaps8Req);
+
+ cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->fid, RT_FONT);
+ if (!cfp) {
+ int aligned_fid = stuff->fid;
+ SendErrToClient(client, FSBadFont, (pointer) &aligned_fid);
+ return FSBadFont;
+ }
+ if (stuff->format & ~ALL_FORMAT_BITS) {
+ int aligned_format = stuff->format;
+ SendErrToClient(client, FSBadFormat, (pointer) &aligned_format);
+ return FSBadFormat;
+ }
+ assert((stuff->reqType == FS_QueryXBitmaps8) || (stuff->reqType == FS_QueryXBitmaps16));
+ item_size = (stuff->reqType == FS_QueryXBitmaps8) ? 1 : 2;
+
+ /* get the glyphs */
+ err = QueryBitmaps(client, cfp, item_size, stuff->format,
+ stuff->num_ranges, stuff->range,
+ (char *)stuff + SIZEOF(fsQueryXBitmaps8Req));
+
+ if (err != FSSuccess) {
+ return err;
+ } else {
+ return client->noClientException;
+ }
+}
+
+int
+ProcCloseFont(ClientPtr client)
+{
+ ClientFontPtr cfp;
+
+ REQUEST(fsResourceReq);
+
+ REQUEST_SIZE_MATCH(fsResourceReq);
+ cfp = (ClientFontPtr) LookupIDByType(client->index, stuff->id, RT_FONT);
+ if (cfp) {
+ FreeResource(client->index, stuff->id, RT_NONE);
+ return client->noClientException;
+ } else {
+ int aligned_id = stuff->id;
+ SendErrToClient(client, FSBadFont, (pointer) &aligned_id);
+ return FSBadFont;
+ }
+}
+
+void
+DoCloseDownClient(ClientPtr client)
+{
+ if (client->clientGone != CLIENT_GONE) {
+ DeleteClientFontStuff(client);
+ client->clientGone = CLIENT_GONE;
+ CloseDownConnection(client);
+ --nClients;
+ }
+
+ if (ClientIsAsleep(client))
+ ClientSignal((pointer)client);
+ else
+ {
+ FreeClientResources(client);
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+#ifdef DebugConnectionTranslation
+ CheckFileNumbers();
+#endif /* DebugConnectionTranslation */
+
+#ifdef NOTYET
+ /* reset server when last client goes away */
+ if (client->requestVector != InitialVector && nClients == 0)
+ dispatchException |= DE_RESET;
+#endif
+
+ if (currentClient == client)
+ currentClient = serverClient;
+ fsfree(client);
+
+#ifdef DEBUG
+ fprintf(stderr, "Shut down client\n");
+#endif
+
+ while (!clients[currentMaxClients - 1])
+ currentMaxClients--;
+ }
+}
+
+static void
+kill_all_clients(void)
+{
+ int i;
+
+ for (i = MINCLIENT; i < currentMaxClients; i++) {
+ if (clients[i])
+ CloseDownClient(clients[i]);
+ }
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_PROC_VECTORS; i++) {
+ if (!ProcVector[i]) {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = (ReplySwapFunc)NotImplemented;
+ }
+ }
+ for (i = FSLASTEvent; i < NUM_EVENT_VECTORS; i++) {
+ EventSwapVector[i] = (EventSwapFunc)NotImplemented;
+ }
+}
+
+void
+InitClient(
+ ClientPtr client,
+ int i,
+ pointer ospriv)
+{
+ client->index = i;
+ client->sequence = 0;
+ client->last_request_time = GetTimeInMillis();
+ client->clientGone = CLIENT_ALIVE;
+ client->noClientException = FSSuccess;
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ client->swapped = FALSE;
+
+ client->auth = (AuthContextPtr) 0;
+ client->catalogues = NULL;
+ client->num_catalogues = 0;
+ client->num_resolutions = 0;
+ client->resolutions = (fsResolution *) 0;
+ client->eventmask = (Mask) 0;
+}
+
+ClientPtr
+NextAvailableClient(pointer ospriv)
+{
+ int i;
+ ClientPtr client;
+ fsFakeReq data;
+
+ i = nextFreeClientID;
+ if (i == MaxClients)
+ return NullClient;
+
+ clients[i] = client = (ClientPtr) fsalloc(sizeof(ClientRec));
+ if (!client)
+ return NullClient;
+
+ InitClient(client, i, ospriv);
+
+ if (!InitClientResources(client)) {
+ fsfree(client);
+ return NullClient;
+ }
+ data.reqType = 1;
+ data.length = (sizeof(fsFakeReq) + SIZEOF(fsConnClientPrefix)) >> 2;
+ if (!InsertFakeRequest(client, (char *) &data, sizeof(fsFakeReq))) {
+ FreeClientResources(client);
+ fsfree(client);
+ return NullClient;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+
+ /* if we've maxed out, try to clone */
+ if (nextFreeClientID == MaxClients) {
+ CloneMyself();
+ }
+ return client;
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -2;
+}
diff --git a/app/xfs/difs/events.c b/app/xfs/difs/events.c
new file mode 100644
index 000000000..91ae7b92c
--- /dev/null
+++ b/app/xfs/difs/events.c
@@ -0,0 +1,134 @@
+/* $Xorg: events.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * event handling stuff
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/events.c,v 3.7tsi Exp $ */
+
+#include <swaprep.h>
+
+#include "clientstr.h"
+#include <X11/fonts/FSproto.h>
+#include "globals.h"
+#include "fsevents.h"
+#include "dispatch.h"
+#include "difs.h"
+
+
+static Mask lastEventMask = FontChangeNotifyMask;
+
+#define AllEventMasks (lastEventMask | (lastEventMask - 1))
+
+void
+WriteErrorToClient(ClientPtr client, fsError *error)
+{
+ if (client->swapped) {
+ fsError errorTo;
+
+ SErrorEvent(error, &errorTo);
+ (void) WriteToClient(client, SIZEOF(fsError), (char *) &errorTo);
+ } else {
+ (void) WriteToClient(client, SIZEOF(fsError),
+ (char *) error);
+ }
+}
+
+int
+ProcSetEventMask(ClientPtr client)
+{
+ REQUEST(fsSetEventMaskReq);
+ REQUEST_AT_LEAST_SIZE(fsSetEventMaskReq);
+
+ if (stuff->event_mask & ~AllEventMasks) {
+ SendErrToClient(client, FSBadEventMask, (pointer) &stuff->event_mask);
+ return FSBadEventMask;
+ }
+ client->eventmask = stuff->event_mask;
+ return client->noClientException;
+}
+
+int
+ProcGetEventMask(ClientPtr client)
+{
+ fsGetEventMaskReply rep;
+
+ REQUEST(fsGetEventMaskReq);
+ REQUEST_AT_LEAST_SIZE(fsGetEventMaskReq);
+
+ rep.type = FS_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = SIZEOF(fsGetEventMaskReply) >> 2;
+ rep.event_mask = client->eventmask;
+
+ WriteReplyToClient(client, SIZEOF(fsGetEventMaskReply), &rep);
+ return client->noClientException;
+}
+
+void
+SendKeepAliveEvent(ClientPtr client)
+{
+ fsKeepAliveEvent ev;
+
+ ev.type = FS_Event;
+ ev.event_code = KeepAlive;
+ ev.sequenceNumber = client->sequence;
+ ev.length = SIZEOF(fsKeepAliveEvent) >> 2;
+ ev.timestamp = GetTimeInMillis();
+
+#ifdef DEBUG
+ fprintf(stderr, "client #%d is getting a KeepAlive\n", client->index);
+#endif
+
+ if (client->swapped) {
+ /* SErrorEvent requires two fsError pointers */
+ fsError evTo;
+
+ SErrorEvent((fsError *) & ev, (fsError *) &evTo);
+ (void) WriteToClient(client, SIZEOF(fsKeepAliveEvent), (char *) &evTo);
+ } else {
+ (void) WriteToClient(client, SIZEOF(fsKeepAliveEvent), (char *) &ev);
+ }
+}
diff --git a/app/xfs/difs/extensions.c b/app/xfs/difs/extensions.c
new file mode 100644
index 000000000..fb1d227b3
--- /dev/null
+++ b/app/xfs/difs/extensions.c
@@ -0,0 +1,300 @@
+/* $Xorg: extensions.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * font server extensions
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/extensions.c,v 1.6 2001/08/01 00:45:04 tsi Exp $ */
+
+#include <X11/fonts/FSproto.h>
+#include "misc.h"
+#include "clientstr.h"
+#include "extentst.h"
+#include "difs.h"
+#include "dispatch.h"
+
+#define EXTENSION_BASE 128
+#define EXTENSION_EVENT_BASE 64
+#define LAST_EVENT 128
+#define LAST_ERROR 255
+
+static ExtensionEntry **extensions = (ExtensionEntry **) NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static int NumExtensions = 0;
+
+
+ExtensionEntry *
+AddExtension(
+ char *name,
+ int num_events,
+ int num_errors,
+ int (*main_proc) (ClientPtr),
+ int (*smain_proc) (ClientPtr),
+ void (*closedown_proc) (struct _ExtensionEntry *),
+ unsigned short (*minorop_proc) (ClientPtr))
+{
+ int i;
+ ExtensionEntry *ext,
+ **newexts;
+
+ if (!main_proc || !smain_proc || !closedown_proc || !minorop_proc)
+ return ((ExtensionEntry *) 0);
+ if ((lastEvent + num_events > LAST_EVENT) ||
+ (unsigned) (lastError + num_errors > LAST_ERROR))
+ return ((ExtensionEntry *) 0);
+ ext = (ExtensionEntry *) fsalloc(sizeof(ExtensionEntry));
+ if (!ext)
+ return ((ExtensionEntry *) 0);
+ ext->name = (char *) fsalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **) NULL;
+ if (!ext->name) {
+ fsfree(ext);
+ return ((ExtensionEntry *) 0);
+ }
+ strcpy(ext->name, name);
+ i = NumExtensions;
+ newexts = (ExtensionEntry **) fsrealloc(extensions,
+ (i + 1) * sizeof(ExtensionEntry *));
+ if (!newexts) {
+ fsfree(ext->name);
+ fsfree(ext);
+ return ((ExtensionEntry *) 0);
+ }
+ NumExtensions++;
+ extensions = newexts;
+ extensions[i] = ext;
+ ext->index = i;
+ ext->base = i + EXTENSION_BASE;
+ ext->CloseDown = closedown_proc;
+ ext->MinorOpcode = minorop_proc;
+ ProcVector[i + EXTENSION_BASE] = main_proc;
+ SwappedProcVector[i + EXTENSION_BASE] = smain_proc;
+ if (num_events) {
+ ext->eventBase = lastEvent;
+ ext->eventLast = lastEvent + num_events;
+ lastEvent += num_events;
+ } else {
+ ext->eventBase = 0;
+ ext->eventLast = 0;
+ }
+ if (num_errors) {
+ ext->errorBase = lastError;
+ ext->errorLast = lastError + num_errors;
+ lastError += num_errors;
+ } else {
+ ext->errorBase = 0;
+ ext->errorLast = 0;
+ }
+ return ext;
+}
+
+Bool
+AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+ char *name;
+ char **aliases;
+
+ aliases = (char **) fsrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *) fsalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases++] = name;
+ return TRUE;
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+ return ((fsReq *) client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+ unsigned char major;
+
+ major = ((fsReq *) client->requestBuffer)->reqType;
+ if (major < EXTENSION_BASE)
+ return 0;
+ major -= EXTENSION_BASE;
+ if (major >= NumExtensions)
+ return 0;
+ return (*extensions[major]->MinorOpcode) (client);
+}
+
+void
+CloseDownExtensions(void)
+{
+ int i,
+ j;
+
+ for (i = NumExtensions - 1; i >= 0; i--) {
+ (*extensions[i]->CloseDown) (extensions[i]);
+ NumExtensions = i;
+ fsfree(extensions[i]->name);
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ fsfree(extensions[i]->aliases[j]);
+ fsfree(extensions[i]->aliases);
+ fsfree(extensions[i]);
+ }
+ fsfree(extensions);
+ extensions = (ExtensionEntry **) NULL;
+ lastEvent = EXTENSION_EVENT_BASE;
+ lastError = FirstExtensionError;
+}
+
+void
+InitExtensions(void)
+{
+}
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+ fsQueryExtensionReply reply;
+ int i,
+ j;
+
+ REQUEST(fsQueryExtensionReq);
+
+ REQUEST_AT_LEAST_SIZE(fsQueryExtensionReq);
+
+ reply.type = FS_Reply;
+ reply.length = SIZEOF(fsQueryExtensionReply) >> 2;
+ reply.major_opcode = 0;
+ reply.sequenceNumber = client->sequence;
+
+ if (!NumExtensions) {
+ reply.present = fsFalse;
+ } else {
+ for (i = 0; i < NumExtensions; i++) {
+ if ((strlen(extensions[i]->name) == stuff->nbytes) &&
+ !strncmp((char *) &stuff[1], extensions[i]->name,
+ (int) stuff->nbytes))
+ break;
+ for (j = extensions[i]->num_aliases; --j >= 0;) {
+ if ((strlen(extensions[i]->aliases[j]) == stuff->nbytes) &&
+ !strncmp((char *) &stuff[1], extensions[i]->aliases[j],
+ (int) stuff->nbytes))
+ break;
+ }
+ if (j >= 0)
+ break;
+ }
+ if (i == NumExtensions) {
+ reply.present = fsFalse;
+ } else {
+ reply.present = fsTrue;
+ reply.major_opcode = extensions[i]->base;
+ reply.first_event = extensions[i]->eventBase;
+ reply.first_error = extensions[i]->errorBase;
+ }
+
+ }
+ WriteReplyToClient(client, SIZEOF(fsQueryExtensionReply), &reply);
+ return client->noClientException;
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+ fsListExtensionsReply reply;
+ char *bufptr,
+ *buffer;
+ int total_length = 0;
+
+ REQUEST(fsListExtensionsReq);
+ REQUEST_SIZE_MATCH(fsListExtensionsReq);
+
+ reply.type = FS_Reply;
+ reply.nExtensions = NumExtensions;
+ reply.length = SIZEOF(fsListExtensionsReply) >> 2;
+ reply.sequenceNumber = client->sequence;
+ buffer = NULL;
+
+ if (NumExtensions) {
+ int i,
+ j;
+
+ for (i = 0; i < NumExtensions; i++) {
+ total_length += strlen(extensions[i]->name) + 1;
+ reply.nExtensions += extensions[i]->num_aliases;
+ for (j = extensions[i]->num_aliases; --j >= 0;)
+ total_length += strlen(extensions[i]->aliases[j]) + 1;
+ }
+ reply.length += (total_length + 3) >> 2;
+ buffer = bufptr = (char *) ALLOCATE_LOCAL(total_length);
+ if (!buffer) {
+ SendErrToClient(client, FSBadAlloc, NULL);
+ return FSBadAlloc;
+ }
+ for (i = 0; i < NumExtensions; i++) {
+ int len;
+
+ *bufptr++ = len = strlen(extensions[i]->name);
+ memmove( bufptr, extensions[i]->name, len);
+ bufptr += len;
+ for (j = extensions[i]->num_aliases; --j >= 0;) {
+ *bufptr++ = len = strlen(extensions[i]->aliases[j]);
+ memmove( bufptr, extensions[i]->aliases[j], len);
+ bufptr += len;
+ }
+ }
+ }
+ WriteReplyToClient(client, SIZEOF(fsListExtensionsReply), &reply);
+ if (total_length) {
+ WriteToClient(client, total_length, buffer);
+ DEALLOCATE_LOCAL(buffer);
+ }
+ return client->noClientException;
+}
diff --git a/app/xfs/difs/fontinfo.c b/app/xfs/difs/fontinfo.c
new file mode 100644
index 000000000..23893e0af
--- /dev/null
+++ b/app/xfs/difs/fontinfo.c
@@ -0,0 +1,437 @@
+/* $Xorg: fontinfo.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * font data query
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/fontinfo.c,v 1.10 2001/12/14 20:01:34 dawes Exp $ */
+
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include <stdio.h>
+#include <X11/Xos.h>
+#include "clientstr.h"
+#include "difsfnst.h"
+#include <X11/fonts/fontstruct.h>
+#include "closestr.h"
+#include "globals.h"
+#include "difs.h"
+#include "dispatch.h"
+#include <swapreq.h>
+#include <swaprep.h>
+
+void
+CopyCharInfo(
+ CharInfoPtr ci,
+ fsXCharInfo *dst)
+{
+ xCharInfo *src = &ci->metrics;
+
+ dst->ascent = src->ascent;
+ dst->descent = src->descent;
+ dst->left = src->leftSideBearing;
+ dst->right = src->rightSideBearing;
+ dst->width = src->characterWidth;
+ dst->attributes = src->attributes;
+}
+
+
+int
+convert_props(
+ FontInfoPtr pinfo,
+ fsPropInfo **props)
+{
+ int i;
+ int data_len, cur_off;
+ char *str;
+ pointer ptr, off_ptr, string_base;
+ fsPropOffset local_offset;
+
+ /*
+ * compute the size of the property data
+ */
+ data_len = 0;
+ for (i = 0; i < pinfo->nprops; i++)
+ {
+ data_len += strlen(NameForAtom(pinfo->props[i].name));
+ if (NULL != pinfo->isStringProp && pinfo->isStringProp[i])
+ data_len += strlen(NameForAtom(pinfo->props[i].value));
+ }
+
+ /*
+ * allocate the single chunk that the difs layer requires
+ */
+ ptr = (pointer) fsalloc(SIZEOF(fsPropInfo)
+ + SIZEOF(fsPropOffset) * pinfo->nprops
+ + data_len);
+ if (!ptr)
+ return AllocError;
+ string_base = (char *)ptr + SIZEOF(fsPropInfo) + SIZEOF(fsPropOffset) * pinfo->nprops;
+
+ /*
+ * copy in the header
+ */
+ ((fsPropInfo *)ptr)->num_offsets = pinfo->nprops;
+ ((fsPropInfo *)ptr)->data_len = data_len;
+
+ /*
+ * compute the offsets and copy the string data
+ */
+ off_ptr = (char *)ptr + SIZEOF(fsPropInfo);
+ cur_off = 0;
+ for (i = 0; i < pinfo->nprops; i++)
+ {
+ local_offset.name.position = cur_off;
+ str = NameForAtom(pinfo->props[i].name);
+ local_offset.name.length = strlen(str);
+ memmove( (char *)string_base+cur_off, str, local_offset.name.length);
+ cur_off += local_offset.name.length;
+ if (NULL != pinfo->isStringProp && pinfo->isStringProp[i])
+ {
+ local_offset.value.position = cur_off;
+ str = NameForAtom(pinfo->props[i].value);
+ local_offset.value.length = strlen(str);
+ memmove( (char *)string_base+cur_off, str, local_offset.value.length);
+ cur_off += local_offset.value.length;
+ local_offset.type = PropTypeString;
+ } else {
+ local_offset.value.position = pinfo->props[i].value;
+ local_offset.value.length = 0; /* protocol says must be zero */
+ local_offset.type = PropTypeSigned;
+ }
+ memmove( off_ptr, &local_offset, SIZEOF(fsPropOffset));
+ off_ptr = (char *)off_ptr + SIZEOF(fsPropOffset);
+ }
+
+ assert(off_ptr == string_base);
+ assert(cur_off == data_len);
+
+ *props = (fsPropInfo *) ptr;
+ return Successful;
+}
+
+
+/*
+ * does the real work of turning a list of range (or chars) into
+ * a list of ranges
+ */
+static fsRange *
+build_range(
+ Bool type,
+ pointer src,
+ int item_size,
+ int *num,
+ Bool *all,
+ FontInfoPtr pfi)
+{
+ fsRange *new = (fsRange *) 0,
+ *np;
+ unsigned long src_num;
+ unsigned long i;
+
+ if (type) { /* range flag is set, deal with data as a list
+ * of char2bs */
+ char *rp = (char *) src;
+
+ src_num = *num;
+ if (src_num == 0) {
+ *all = TRUE;
+ return new;
+ }
+
+ np = new = (fsRange *) fsalloc(sizeof(fsRange) * (src_num + 1) / 2);
+ if (!np)
+ return np;
+ /* Build a new range */
+ for (i = 1; i < src_num; i += 2)
+ {
+ np->min_char_high = (item_size == 1) ? 0 : *rp++;
+ np->min_char_low = *rp++;
+ np->max_char_high = (item_size == 1) ? 0 : *rp++;
+ np->max_char_low = *rp++;
+ np++;
+ }
+
+ /* If src_num is odd, we need to determine the final range
+ by examining the fontinfo */
+ if (i == src_num)
+ {
+ np->min_char_high = (item_size == 1) ? 0 : *rp++;
+ np->min_char_low = *rp++;
+ np->max_char_high = pfi->lastRow;
+ np->max_char_low = pfi->lastCol;
+ np++;
+ }
+ *num = np - new;
+ return new;
+ } else { /* deal with data as a list of characters */
+ unsigned char *pp = src;
+
+ src_num = *num;
+ np = new = (fsRange *) fsalloc(SIZEOF(fsRange) * src_num);
+ if (!np)
+ return np;
+
+ /* Build a range, with coalescence, from the list of chars */
+
+ for (i = 0; i < src_num; i++) {
+ if (item_size == 1) {
+ np->min_char_low = *pp;
+ np->min_char_high = 0;
+ } else {
+ np->min_char_low = ((fsChar2b *) pp)->low;
+ np->min_char_high = ((fsChar2b *) pp)->high;
+ }
+ np->max_char_high = np->min_char_high;
+ np->max_char_low = np->min_char_low;
+ /* Can we coalesce? */
+ if (np > new &&
+ np->max_char_high == np[-1].max_char_high &&
+ np->max_char_low == np[-1].max_char_low + 1)
+ np[-1].max_char_low++; /* Yes */
+ else
+ np++; /* No */
+ pp += item_size;
+ }
+ *num = np - new;
+ return new;
+ }
+}
+
+/*
+ * provide backward compatibility with version 1, which had
+ * the bytes of char2b backwards
+ */
+static void
+swap_char2b (fsChar2b *values, int number)
+{
+ fsChar2b temp;
+ int i;
+
+ for (i = 0; i < number; i++) {
+ temp.low = ((fsChar2b_version1 *)values)->low;
+ temp.high = ((fsChar2b_version1 *)values)->high;
+ *values++ = temp;
+ }
+}
+
+#define pPtr ((QEclosurePtr) data)
+
+static Bool
+do_query_extents(ClientPtr client, pointer data)
+{
+ int err;
+ unsigned long lendata,
+ num_extents;
+ fsXCharInfo *extents;
+ fsQueryXExtents8Reply reply;
+
+ err = GetExtents (pPtr->client, pPtr->pfont,
+ pPtr->flags, pPtr->nranges, pPtr->range, &num_extents, &extents);
+ if (err == Suspended) {
+ if (!pPtr->slept) {
+ pPtr->pfont->unload_glyphs = 0; /* Not a safe call for this font */
+ pPtr->slept = TRUE;
+ ClientSleep(client, do_query_extents, (pointer) pPtr);
+ }
+ return TRUE;
+ }
+ if (err != Successful) {
+ SendErrToClient(pPtr->client, FontToFSError(err), (pointer) 0);
+ goto finish;
+ }
+ reply.type = FS_Reply;
+ reply.sequenceNumber = pPtr->client->sequence;
+ reply.num_extents = num_extents;
+ lendata = SIZEOF(fsXCharInfo) * num_extents;
+ reply.length = (SIZEOF(fsQueryXExtents8Reply) + lendata) >> 2;
+ if (client->swapped)
+ SwapExtents(extents, num_extents);
+ WriteReplyToClient(pPtr->client, SIZEOF(fsQueryXExtents8Reply), &reply);
+ (void) WriteToClient(pPtr->client, lendata, (char *) extents);
+ fsfree((char *) extents);
+finish:
+ if (pPtr->slept)
+ ClientWakeup(pPtr->client);
+ if (pPtr->pfont->unload_glyphs) /* For rasterizers that want to save memory */
+ (*pPtr->pfont->unload_glyphs)(pPtr->pfont);
+ fsfree(pPtr->range);
+ fsfree(pPtr);
+ return TRUE;
+}
+
+int
+QueryExtents(
+ ClientPtr client,
+ ClientFontPtr cfp,
+ int item_size,
+ int nranges,
+ Bool range_flag,
+ pointer range_data)
+{
+ QEclosurePtr c;
+ fsRange *fixed_range;
+ Bool all_glyphs = FALSE;
+
+ if (item_size == 2 && client->major_version == 1)
+ swap_char2b ((fsChar2b *)range_data, nranges);
+
+ fixed_range = build_range(range_flag, range_data, item_size,
+ &nranges, &all_glyphs, &cfp->font->info);
+
+ if (!fixed_range && !all_glyphs) {
+ SendErrToClient(client, FSBadRange, 0);
+ return FSBadRange;
+ }
+ c = (QEclosurePtr) fsalloc(sizeof(QEclosureRec));
+ if (!c)
+ return FSBadAlloc;
+ c->client = client;
+ c->slept = FALSE;
+ c->pfont = cfp->font;
+ c->flags = (all_glyphs) ? LoadAll : 0;
+ c->flags |= (item_size == 1) ? EightBitFont : SixteenBitFont;
+ c->nranges = nranges;
+ c->range = fixed_range;
+
+ (void) do_query_extents(client, (pointer) c);
+ return FSSuccess;
+}
+
+#undef pPtr
+#define pPtr ((QBclosurePtr) data)
+
+static Bool
+do_query_bitmaps(ClientPtr client, pointer data)
+{
+ int err;
+ unsigned long num_glyphs;
+ int data_size;
+ fsOffset32 *offsets;
+ pointer glyph_data;
+ fsQueryXBitmaps8Reply reply;
+ int freedata;
+
+ err = GetBitmaps (pPtr->client, pPtr->pfont, pPtr->format,
+ pPtr->flags, pPtr->nranges, pPtr->range,
+ &data_size, &num_glyphs, &offsets, &glyph_data, &freedata);
+
+ if (err == Suspended) {
+ if (!pPtr->slept) {
+ pPtr->pfont->unload_glyphs = 0; /* Not a safe call for this font */
+ pPtr->slept = TRUE;
+ ClientSleep(client, do_query_bitmaps, (pointer) pPtr);
+ }
+ return TRUE;
+ }
+ if (err != Successful) {
+ SendErrToClient(pPtr->client, FontToFSError(err), (pointer) 0);
+ goto finish;
+ }
+ reply.type = FS_Reply;
+ reply.sequenceNumber = pPtr->client->sequence;
+ reply.replies_hint = 0;
+ reply.num_chars = num_glyphs;
+ reply.nbytes = data_size;
+ reply.length = (SIZEOF(fsQueryXBitmaps8Reply) + data_size +
+ (SIZEOF(fsOffset32) * num_glyphs) + 3) >> 2;
+
+ WriteReplyToClient(pPtr->client, SIZEOF(fsQueryXBitmaps8Reply), &reply);
+ if (client->swapped)
+ SwapLongs((long *)offsets, num_glyphs * 2);
+ (void) WriteToClient(pPtr->client, (num_glyphs * SIZEOF(fsOffset32)),
+ (char *) offsets);
+ (void) WriteToClient(pPtr->client, data_size, (char *) glyph_data);
+ fsfree((char *) offsets);
+ if (freedata)
+ fsfree((char *) glyph_data);
+finish:
+ if (pPtr->slept)
+ ClientWakeup(pPtr->client);
+ if (pPtr->pfont->unload_glyphs) /* For rasterizers that want to save memory */
+ (*pPtr->pfont->unload_glyphs)(pPtr->pfont);
+ fsfree(pPtr->range);
+ fsfree(pPtr);
+ return TRUE;
+}
+
+int
+QueryBitmaps(
+ ClientPtr client,
+ ClientFontPtr cfp,
+ int item_size,
+ fsBitmapFormat format,
+ int nranges,
+ Bool range_flag,
+ pointer range_data)
+{
+ QBclosurePtr c;
+ fsRange *fixed_range;
+ Bool all_glyphs = FALSE;
+
+ if (item_size == 2 && client->major_version == 1)
+ swap_char2b ((fsChar2b *)range_data, nranges);
+
+ fixed_range = build_range(range_flag, range_data, item_size,
+ &nranges, &all_glyphs, &cfp->font->info);
+
+ if (!fixed_range && !all_glyphs) {
+ SendErrToClient(client, FSBadRange, 0);
+ return FSBadRange;
+ }
+ c = (QBclosurePtr) fsalloc(sizeof(QBclosureRec));
+ if (!c)
+ return FSBadAlloc;
+ c->client = client;
+ c->slept = FALSE;
+ c->pfont = cfp->font;
+ c->flags = (all_glyphs) ? LoadAll : 0;
+ c->nranges = nranges;
+ c->range = fixed_range;
+ c->format = format;
+
+ (void) do_query_bitmaps(client, (pointer) c);
+ return FSSuccess;
+}
diff --git a/app/xfs/difs/fonts.c b/app/xfs/difs/fonts.c
new file mode 100644
index 000000000..2ba7c4276
--- /dev/null
+++ b/app/xfs/difs/fonts.c
@@ -0,0 +1,1554 @@
+/* $Xorg: fonts.c,v 1.5 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * font control
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/*#define DEBUG*/
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xos.h>
+#include "clientstr.h"
+#include "fsresource.h"
+#include "difsfnst.h"
+#include <X11/fonts/fontstruct.h>
+#include "closestr.h"
+#include "globals.h"
+#include "difs.h"
+#include "dispatch.h"
+#include "swaprep.h"
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+static FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+
+extern FontPatternCachePtr fontPatternCache;
+
+#define NUM_IDS_PER_CLIENT 5
+
+int
+FontToFSError(int err)
+{
+ switch (err) {
+ case Successful:
+ return FSSuccess;
+ case AllocError:
+ return FSBadAlloc;
+ case BadFontName:
+ case BadFontPath:
+ return FSBadName;
+ case BadFontFormat:
+ return FSBadFormat;
+ case BadCharRange:
+ return FSBadRange;
+ default:
+ return err;
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+void
+FreeFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ fsfree(fpe->name);
+ fsfree(fpe);
+ }
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+ fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ fsrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+/* ARGSUSED */
+void
+FontWakeup(pointer data, int count, unsigned long *LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return; /* ignore -1 return from select XXX */
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+static Bool
+add_id_to_list(FontIDListPtr ids, Font fid)
+{
+ Font *newlist;
+
+ /*
+ * assumes the list is packed tightly
+ */
+ if (ids->num == ids->size) {
+ /* increase size of array */
+ newlist = (Font *) fsrealloc(ids->client_list,
+ sizeof(Font) * (ids->size + NUM_IDS_PER_CLIENT));
+ if (!newlist)
+ return FALSE;
+ ids->client_list = newlist;
+ ids->size += NUM_IDS_PER_CLIENT;
+ }
+ ids->client_list[ids->num++] = fid;
+ return TRUE;
+}
+
+static void
+remove_id_from_list(FontIDListPtr ids, Font fid)
+{
+ int i;
+
+ for (i = 0; i < ids->num; i++) {
+ if (ids->client_list[i] == fid) {
+ /* a memmove() might be better here */
+ while (i < ids->num) {
+ ids->client_list[i] = ids->client_list[i + 1];
+ i++;
+ }
+ ids->num--;
+ return;
+ }
+ }
+ assert(0);
+}
+
+static FontIDListPtr
+make_clients_id_list(void)
+{
+ FontIDListPtr ids;
+ Font *fids;
+
+ ids = (FontIDListPtr) fsalloc(sizeof(FontIDListRec));
+ fids = (Font *) fsalloc(sizeof(Font) * NUM_IDS_PER_CLIENT);
+ if (!ids || !fids) {
+ fsfree(ids);
+ fsfree(fids);
+ return (FontIDListPtr) 0;
+ }
+ bzero((char *) fids, sizeof(Font) * NUM_IDS_PER_CLIENT);
+ ids->client_list = fids;
+ ids->size = NUM_IDS_PER_CLIENT;
+ ids->num = 0;
+ return ids;
+}
+
+static void
+free_svrPrivate(pointer svrPrivate)
+{
+ int i;
+ FontIDListPtr *idlist, ids;
+
+ idlist = (FontIDListPtr *) svrPrivate;
+ if (idlist) {
+ for (i = 0; i < MAXCLIENTS; i++) {
+ ids = idlist[i];
+ if (ids) {
+ fsfree((char *) ids->client_list);
+ fsfree((char *) ids);
+ }
+ }
+ fsfree((char *) idlist);
+ }
+}
+
+#undef cPtr
+#define cPtr ((OFclosurePtr )data)
+
+static Bool
+do_open_font(ClientPtr client, pointer data)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ int err = 0;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ ClientFontPtr cfp;
+ fsOpenBitmapFontReply rep;
+ Font orig;
+ FontIDListPtr *idlist,
+ ids;
+ int aliascount = 20;
+
+ if (client->clientGone == CLIENT_GONE) {
+ if (cPtr->current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto dropout;
+ }
+ while (cPtr->current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) cPtr->client, fpe, cPtr->flags,
+ cPtr->fontname, cPtr->fnamelen, cPtr->format, cPtr->format_mask,
+ cPtr->fontid, &pfont, &alias,
+ cPtr->non_cachable_font && cPtr->non_cachable_font->fpe == fpe ?
+ cPtr->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) fsrealloc(cPtr->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove( newname, alias, newlen);
+ cPtr->fontname = newname;
+ cPtr->fnamelen = newlen;
+ cPtr->current_fpe = 0;
+ if (--aliascount <= 0) break;
+ continue;
+ }
+ if (err == BadFontName) {
+ cPtr->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ cPtr->slept = TRUE;
+ ClientSleep(client, do_open_font, (pointer) cPtr);
+ }
+ return TRUE;
+ }
+ break;
+ }
+ if (err != Successful) {
+ goto dropout;
+ }
+ if (!pfont) {
+ err = BadFontName;
+ goto dropout;
+ }
+ cfp = (ClientFontPtr) fsalloc(sizeof(ClientFontRec));
+ if (!cfp) {
+ err = AllocError;
+ goto dropout;
+ }
+ cfp->font = pfont;
+ cfp->clientindex = cPtr->client->index;
+
+ if (fontPatternCache && pfont != cPtr->non_cachable_font)
+ CacheFontPattern(fontPatternCache, cPtr->orig_name, cPtr->orig_len, pfont);
+
+ /* either pull out the other id or make the array */
+ if (pfont->refcnt != 0) {
+ idlist = (FontIDListPtr *) pfont->svrPrivate;
+ ids = idlist[cPtr->client->index];
+ if (!ids) {
+ ids = make_clients_id_list();
+ if (!ids) {
+ err = AllocError;
+ fsfree(cfp);
+ goto dropout;
+ }
+ idlist[cPtr->client->index] = ids;
+ }
+ orig = (ids->num > 0) ? ids->client_list[0] : (Font)0;
+ } else {
+ idlist = (FontIDListPtr *) fsalloc(sizeof(FontIDListPtr) * MAXCLIENTS);
+ if (!idlist) {
+ err = AllocError;
+ fsfree(cfp);
+ goto dropout;
+ }
+ ids = make_clients_id_list();
+ if (!ids) {
+ err = AllocError;
+ fsfree(idlist);
+ fsfree(cfp);
+ goto dropout;
+ }
+ bzero((char *) idlist, (sizeof(FontIDListPtr) * MAXCLIENTS));
+ idlist[cPtr->client->index] = ids;
+ orig = (Font) 0;
+ pfont->svrPrivate = (pointer) idlist;
+ }
+ if (!AddResource(cPtr->client->index, cPtr->fontid, RT_FONT, (pointer) cfp)) {
+ fsfree(cfp);
+ free_svrPrivate(pfont->svrPrivate);
+ pfont->svrPrivate = (pointer) 0;
+ err = AllocError;
+ goto dropout;
+ }
+ add_id_to_list(ids, cPtr->fontid);
+ /* send the reply */
+ rep.type = FS_Reply;
+ rep.otherid = orig;
+ if (orig)
+ rep.otherid_valid = TRUE;
+ else
+ rep.otherid_valid = FALSE;
+ rep.cachable = pfont->info.cachable;
+ rep.sequenceNumber = client->sequence;
+ rep.length = SIZEOF(fsOpenBitmapFontReply) >> 2;
+ WriteReplyToClient(client,
+ SIZEOF(fsOpenBitmapFontReply), &rep);
+ if (pfont->refcnt == 0) {
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ UseFPE(pfont->fpe);
+ }
+ pfont->refcnt++;
+dropout:
+ if (err != Successful) {
+ SendErrToClient(cPtr->client, FontToFSError(err), (pointer) &(cPtr->fontid));
+ }
+ if (cPtr->slept)
+ ClientWakeup(cPtr->client);
+ for (i = 0; i < cPtr->num_fpes; i++) {
+ FreeFPE(cPtr->fpe_list[i]);
+ }
+ fsfree(cPtr->fpe_list);
+ fsfree(cPtr->fontname);
+ fsfree(cPtr);
+ return TRUE;
+}
+
+int
+OpenFont(
+ ClientPtr client,
+ Font fid,
+ fsBitmapFormat format,
+ fsBitmapFormatMask format_mask,
+ int namelen,
+ char *name)
+{
+ FontPtr pfont = (FontPtr)0;
+ fsOpenBitmapFontReply rep;
+ OFclosurePtr c;
+ FontIDListPtr *idlist,
+ ids;
+ int i;
+
+ if (namelen == 0 || namelen > XLFDMAXFONTNAMELEN) {
+ SendErrToClient(client, FSBadName, (pointer) 0);
+ return FSBadName;
+ }
+#ifdef DEBUG
+ fprintf(stderr,"OpenFont: %sn",name);
+#endif
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ if (fontPatternCache &&
+ (pfont = FindCachedFontPattern(fontPatternCache, name, namelen)) &&
+ pfont->info.cachable) {
+ ClientFontPtr cfp;
+
+ idlist = (FontIDListPtr *) pfont->svrPrivate;
+ ids = idlist[client->index];
+ if (!ids) {
+ ids = make_clients_id_list();
+ if (!ids) {
+ goto lowmem;
+ }
+ idlist[client->index] = ids;
+ }
+ cfp = (ClientFontPtr) fsalloc(sizeof(ClientFontRec));
+ if (!cfp) {
+ lowmem:
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return FSBadAlloc;
+ }
+ cfp->font = pfont;
+ cfp->clientindex = client->index;
+ if (!AddResource(client->index, fid, RT_FONT, (pointer) cfp)) {
+ goto lowmem;
+ }
+ if (!add_id_to_list(ids, fid)) {
+ goto lowmem;
+ }
+ pfont->refcnt++;
+ rep.type = FS_Reply;
+ if (ids->num > 1)
+ {
+ rep.otherid = ids->client_list[0];
+ rep.otherid_valid = TRUE;
+ }
+ else
+ {
+ rep.otherid = 0;
+ rep.otherid_valid = FALSE;
+ }
+ rep.cachable = TRUE; /* XXX */
+ rep.sequenceNumber = client->sequence;
+ rep.length = SIZEOF(fsOpenBitmapFontReply) >> 2;
+ WriteReplyToClient(client,
+ SIZEOF(fsOpenBitmapFontReply), &rep);
+ return FSSuccess;
+ }
+ c = (OFclosurePtr) fsalloc(sizeof(OFclosureRec));
+ if (!c)
+ goto lowmem;
+ c->fontname = (char *) fsalloc(namelen);
+ if (!c->fontname) {
+ fsfree(c);
+ goto lowmem;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = (FontPathElementPtr *)
+ fsalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ fsfree(c->fontname);
+ fsfree(c);
+ goto lowmem;
+ }
+ memmove( c->fontname, name, namelen);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = namelen;
+ c->orig_name = name;
+ c->orig_len = namelen;
+ c->slept = FALSE;
+ c->flags = (FontLoadInfo | FontLoadProps);
+ c->format = format;
+ c->format_mask = format_mask;
+ c->non_cachable_font = pfont;
+
+ (void) do_open_font(client, (pointer) c);
+ return FSSuccess;
+}
+
+static int
+close_font(FontPtr pfont)
+{
+ FontPathElementPtr fpe;
+
+ assert(pfont);
+ if (--pfont->refcnt == 0) {
+ if (fontPatternCache)
+ RemoveCachedFontPattern(fontPatternCache, pfont);
+ fpe = pfont->fpe;
+ free_svrPrivate(pfont->svrPrivate);
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return FSSuccess;
+}
+
+int
+CloseClientFont(
+ ClientFontPtr cfp,
+ FSID fid)
+{
+ FontIDListPtr *idlist;
+ FontIDListPtr ids;
+ int ret;
+
+ assert(cfp);
+ /* clear otherid id */
+ idlist = (FontIDListPtr *) cfp->font->svrPrivate;
+ ids = idlist[cfp->clientindex];
+ remove_id_from_list(ids, fid);
+ ret = close_font(cfp->font);
+ fsfree((char *) cfp);
+ return ret;
+}
+
+/*
+ * search all the known FPE prefixes looking for one to match the given
+ * FPE name
+ */
+static int
+determine_fpe_type(char *name)
+{
+ int i;
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (name))
+ return i;
+ }
+ return -1;
+}
+
+static void
+free_font_path(FontPathElementPtr *list, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ FreeFPE(list[i]);
+ }
+ fsfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(
+ FontPathElementPtr *list,
+ int num,
+ char *name,
+ int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+/*
+ * does the work of setting up the fpe list
+ *
+ * paths should be a counted string
+ */
+static int
+set_font_path_elements(
+ int npaths,
+ char *paths,
+ int *bad)
+{
+ int i, validpaths, err = 0;
+ int len;
+ int type;
+ char *cp = paths;
+ char *name;
+ FontPathElementPtr fpe, *fplist;
+
+ fplist = (FontPathElementPtr *)
+ fsalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return FSBadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0, validpaths = 0; i < npaths; i++) {
+ len = *cp++;
+ if (len) {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe) {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful) {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ fplist[validpaths++] = fpe;
+ cp += len;
+ continue;
+ }
+ /* can't do it, so act like it's a new one */
+ }
+ name = (char *) fsalloc(len + 1);
+ if (!name) {
+ err = FSBadAlloc;
+ goto bail;
+ }
+ strncpy(name, (char *) cp, len);
+ name[len] = '\0';
+ type = determine_fpe_type(name);
+ if (type == -1)
+ {
+ NoticeF("ignoring font path element %s (bad font path descriptor)\n", name);
+ fsfree(name);
+ continue;
+ }
+ /* must be new -- make it */
+ fpe = (FontPathElementPtr) fsalloc(sizeof(FontPathElementRec));
+ if (!fpe) {
+ fsfree(name);
+ err = FSBadAlloc;
+ goto bail;
+ }
+ fpe->type = type;
+ fpe->name = name;
+ fpe->refcount = 1;
+
+ cp += len;
+ fpe->name_length = len;
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful) {
+ NoticeF("ignoring font path element %s (unreadable)\n", fpe->name);
+ fsfree(fpe->name);
+ fsfree(fpe);
+ continue;
+ }
+ fplist[validpaths++] = fpe;
+ }
+ }
+ if (validpaths < npaths) {
+ FontPathElementPtr *ftmp = (FontPathElementPtr *)
+ fsrealloc(fplist, sizeof(FontPathElementPtr) * validpaths);
+
+ if (!ftmp && validpaths)
+ goto bail;
+
+ fplist = ftmp;
+ npaths = validpaths;
+ }
+ if (validpaths == 0) {
+ err = FontToFSError(err);
+ goto bail;
+ }
+ free_font_path(font_path_elements, num_fpes);
+ font_path_elements = fplist;
+ num_fpes = npaths;
+ if (fontPatternCache)
+ EmptyFontPatternCache(fontPatternCache);
+ return FSSuccess;
+bail:
+ *bad = validpaths;
+ while (--validpaths >= 0)
+ FreeFPE(fplist[i]);
+ fsfree(fplist);
+ return err;
+}
+
+/*
+ * expects comma seperated string
+ */
+int
+SetFontCatalogue(
+ char *str,
+ int *badpath)
+{
+ int len,
+ npaths;
+ char *paths,
+ *end,
+ *p;
+ int err;
+
+ len = strlen(str) + 1;
+ paths = p = (char *) ALLOCATE_LOCAL(len);
+ npaths = 0;
+
+ while (*str) {
+ end = index(str, ',');
+ if (!end) {
+ end = str + strlen(str);
+ }
+ *p++ = len = end - str;
+ memmove( p, str, len);
+ npaths++;
+ str += len; /* skip entry */
+ if (*str == ',')
+ str++; /* skip any comma */
+ p += len;
+ }
+
+ err = set_font_path_elements(npaths, paths, badpath);
+
+ DEALLOCATE_LOCAL(paths);
+
+ return err;
+}
+
+#undef cPtr
+#define cPtr ((LFclosurePtr)data)
+
+static Bool
+do_list_fonts_and_aliases(ClientPtr client, pointer data)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ fsListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone == CLIENT_GONE) {
+ if (cPtr->current.current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!cPtr->current.patlen)
+ goto finish;
+
+ while (cPtr->current.current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) cPtr->client, fpe, cPtr->current.pattern,
+ cPtr->current.patlen, cPtr->current.max_names - cPtr->names->nnames,
+ cPtr->names);
+
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ cPtr->slept = TRUE;
+ ClientSleep(client, do_list_fonts_and_aliases, (pointer) cPtr);
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!cPtr->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) cPtr->client, fpe, cPtr->current.pattern,
+ cPtr->current.patlen, cPtr->current.max_names - cPtr->names->nnames,
+ &cPtr->current.private);
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ ClientSleep(client, do_list_fonts_and_aliases,
+ (pointer) cPtr);
+ cPtr->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ cPtr->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) cPtr->client, fpe, &name, &namelen, &resolved,
+ &resolvedlen, cPtr->current.private);
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ ClientSleep(client, do_list_fonts_and_aliases,
+ (pointer) cPtr);
+ cPtr->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (cPtr->haveSaved)
+ {
+ if (cPtr->savedName)
+ (void)AddFontNamesName(cPtr->names, cPtr->savedName,
+ cPtr->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(cPtr->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (cPtr->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) cPtr->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, cPtr->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ cPtr->saved = cPtr->current;
+ cPtr->haveSaved = TRUE;
+ if (cPtr->savedName)
+ fsfree(cPtr->savedName);
+ cPtr->savedName = (char *)fsalloc(namelen + 1);
+ if (cPtr->savedName)
+ memmove(cPtr->savedName, name, namelen + 1);
+ cPtr->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(cPtr->current.pattern, tmp_pattern, resolvedlen);
+ cPtr->current.patlen = resolvedlen;
+ cPtr->current.max_names = cPtr->names->nnames + 1;
+ cPtr->current.current_fpe = -1;
+ cPtr->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ cPtr->current.list_started = FALSE;
+ cPtr->current.current_fpe++;
+ err = Successful;
+ if (cPtr->haveSaved)
+ {
+ /* If we're searching for an alias, limit the search to
+ FPE's of the same type as the one the alias came
+ from. This is unnecessarily restrictive, but if we
+ have both fontfile and fs FPE's, this restriction can
+ drastically reduce network traffic to the fs -- else
+ we could poll the fs for *every* local alias found;
+ on a typical system enabling FILE_NAMES_ALIASES, this
+ is significant. */
+
+ while (cPtr->current.current_fpe < cPtr->num_fpes &&
+ cPtr->fpe_list[cPtr->current.current_fpe]->type !=
+ cPtr->fpe_list[cPtr->saved.current_fpe]->type)
+ cPtr->current.current_fpe++;
+
+ if (cPtr->names->nnames == cPtr->current.max_names ||
+ cPtr->current.current_fpe == cPtr->num_fpes) {
+ cPtr->haveSaved = FALSE;
+ cPtr->current = cPtr->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (cPtr->names->nnames == cPtr->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrToClient(client, FontToFSError(err), (pointer) 0);
+ goto bail;
+ }
+
+finish:
+
+ names = cPtr->names;
+ nnames = names->nnames;
+ client = cPtr->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ reply.type = FS_Reply;
+ reply.length = (SIZEOF(fsListFontsReply) + stringLens + nnames + 3) >> 2;
+ reply.following = 0;
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = (SIZEOF(fsListFontsReply) + stringLens + nnames + 3) >> 2;
+ WriteReplyToClient(client, SIZEOF(fsListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+ if (cPtr->slept)
+ ClientWakeup(client);
+ for (i = 0; i < cPtr->num_fpes; i++)
+ FreeFPE(cPtr->fpe_list[i]);
+ fsfree(cPtr->fpe_list);
+ if (cPtr->savedName) fsfree(cPtr->savedName);
+ FreeFontNames(names);
+ fsfree(cPtr);
+ return TRUE;
+}
+
+int
+ListFonts(
+ ClientPtr client,
+ int length,
+ unsigned char *pattern,
+ int maxNames)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return TRUE;
+ }
+
+ if (!(c = (LFclosurePtr) fsalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ fsalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ fsfree(c);
+ goto badAlloc;
+ }
+ c->names = MakeFontNamesRecord(maxNames < 100 ? maxNames : 100);
+ if (!c->names)
+ {
+ fsfree(c->fpe_list);
+ fsfree(c);
+ goto badAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = maxNames;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ do_list_fonts_and_aliases(client, (pointer) c);
+ return TRUE;
+badAlloc:
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return TRUE;
+}
+
+static int padlength[4] = {0, 3, 2, 1};
+static char padding[3];
+
+#undef cPtr
+#define cPtr ((LFWXIclosurePtr)data)
+
+static Bool
+do_list_fonts_with_info(ClientPtr client, pointer data)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ fsListFontsWithXInfoReply *reply;
+ int length;
+ fsPropInfo *prop_info;
+ int lenpropdata;
+ int i;
+ int aliascount = 0;
+
+ if (client->clientGone == CLIENT_GONE) {
+ if (cPtr->current.current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (cPtr->current.current_fpe < cPtr->num_fpes) {
+ fpe = cPtr->fpe_list[cPtr->current.current_fpe];
+ err = Successful;
+ if (!cPtr->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ ((pointer) cPtr->client, fpe, cPtr->current.pattern,
+ cPtr->current.patlen, cPtr->current.max_names,
+ &cPtr->current.private);
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ ClientSleep(client, do_list_fonts_with_info,
+ (pointer) cPtr);
+ cPtr->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ cPtr->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ ((pointer) cPtr->client, fpe, &name, &namelen,
+ &pFontInfo, &numFonts, cPtr->current.private);
+ if (err == Suspended) {
+ if (!cPtr->slept) {
+ ClientSleep(client, do_list_fonts_with_info,
+ (pointer) cPtr);
+ cPtr->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias) {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (cPtr->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ ((pointer) client, fpe, &tmpname, &tmpnamelen,
+ &tmpFontInfo, &numFonts, cPtr->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ cPtr->saved = cPtr->current;
+ cPtr->haveSaved = TRUE;
+ cPtr->savedNumFonts = numFonts;
+ if (cPtr->savedName)
+ fsfree(cPtr->savedName);
+ cPtr->savedName = (char *)fsalloc(namelen + 1);
+ if (cPtr->savedName)
+ memmove(cPtr->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(cPtr->current.pattern, name, namelen);
+ cPtr->current.patlen = namelen;
+ cPtr->current.max_names = 1;
+ cPtr->current.current_fpe = 0;
+ cPtr->current.private = 0;
+ cPtr->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit.
+ */
+ else if (err == BadFontName) {
+ ContBadFontName: ;
+ cPtr->current.list_started = FALSE;
+ cPtr->current.current_fpe++;
+ err = Successful;
+ if (cPtr->haveSaved) {
+ if (cPtr->current.max_names == 0 ||
+ cPtr->current.current_fpe == cPtr->num_fpes) {
+ cPtr->haveSaved = FALSE;
+ cPtr->saved.max_names -= (1 - cPtr->current.max_names);
+ cPtr->current = cPtr->saved;
+ }
+ }
+ else if (cPtr->current.max_names == 0)
+ break;
+ } else if (err == Successful) {
+/* XXX why is it xFontProp ? */
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = cPtr->reply;
+ if (cPtr->length < length) {
+ reply = (fsListFontsWithXInfoReply *) fsrealloc(cPtr->reply, length);
+ if (!reply) {
+ err = AllocError;
+ break;
+ }
+ cPtr->reply = reply;
+ cPtr->length = length;
+ }
+ if (cPtr->haveSaved) {
+ numFonts = cPtr->savedNumFonts;
+ name = cPtr->savedName;
+ namelen = strlen(name);
+ }
+ fsPack_XFontInfoHeader(pFontInfo, reply, client->major_version);
+ err = convert_props(pFontInfo, &prop_info);
+ if (err != Successful)
+ break;
+ lenpropdata = SIZEOF(fsPropInfo) +
+ prop_info->num_offsets * SIZEOF(fsPropOffset) +
+ prop_info->data_len;
+
+ reply->type = FS_Reply;
+ reply->length =
+ (SIZEOF(fsListFontsWithXInfoReply) +
+ lenpropdata + namelen + 3) >> 2;
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->nReplies = numFonts;
+ WriteReplyToClient(client, SIZEOF(fsListFontsWithXInfoReply), reply);
+ if (client->swapped)
+ SwapPropInfo(prop_info);
+ if (client->major_version > 1)
+ {
+ (void)WriteToClientUnpadded(client, lenpropdata, (char *) prop_info);
+ (void)WriteToClientUnpadded(client, namelen, name);
+ (void)WriteToClientUnpadded(client,
+ padlength[(lenpropdata+namelen)&3],
+ padding);
+ } else {
+ (void) WriteToClient(client, namelen, name);
+ (void) WriteToClient(client, lenpropdata, (char *) prop_info);
+ }
+ if (pFontInfo == &fontInfo) {
+ fsfree(fontInfo.props);
+ fsfree(fontInfo.isStringProp);
+ }
+ fsfree(prop_info);
+
+ --cPtr->current.max_names;
+ if (cPtr->current.max_names < 0)
+ abort();
+ }
+ }
+
+ /*
+ * send the final reply
+ */
+ if (err == Successful) {
+ fsGenericReply *final_reply;
+
+ final_reply = (fsGenericReply *)cPtr->reply;
+ if (client->major_version > 1)
+ length = SIZEOF(fsGenericReply);
+ else
+ length = SIZEOF(fsListFontsWithXInfoReply);
+ if (cPtr->length < length) {
+ final_reply = (fsGenericReply *) fsrealloc(cPtr->reply, length);
+ if (final_reply) {
+ cPtr->reply = (fsListFontsWithXInfoReply *)final_reply;
+ cPtr->length = length;
+ } else
+ err = AllocError;
+ }
+ if (err == Successful) {
+ final_reply->type = FS_Reply;
+ final_reply->data1 = 0; /* notes that this is final */
+ final_reply->sequenceNumber = client->sequence;
+ final_reply->length = length >> 2;
+ WriteReplyToClient(client, length, final_reply);
+ }
+ }
+ if (err != Successful)
+ SendErrToClient(client, FontToFSError(err), (pointer) 0);
+bail:
+ if (cPtr->slept)
+ ClientWakeup(client);
+ for (i = 0; i < cPtr->num_fpes; i++)
+ FreeFPE(cPtr->fpe_list[i]);
+ fsfree(cPtr->fpe_list);
+ if (cPtr->savedName) fsfree(cPtr->savedName);
+ fsfree(cPtr->reply);
+ fsfree(cPtr);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(
+ ClientPtr client,
+ int length,
+ unsigned char *pattern,
+ int maxNames)
+{
+ int i;
+ LFWXIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN) {
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return TRUE;
+ }
+
+ if (!(c = (LFWXIclosurePtr) fsalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = (FontPathElementPtr *)
+ fsalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ fsfree(c);
+ goto badAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = maxNames;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ do_list_fonts_with_info(client, (pointer) c);
+ return TRUE;
+badAlloc:
+ SendErrToClient(client, FSBadAlloc, (pointer) 0);
+ return TRUE;
+}
+
+int
+LoadGlyphRanges(
+ ClientPtr client,
+ FontPtr pfont,
+ Bool range_flag,
+ int num_ranges,
+ int item_size,
+ fsChar2b *data)
+{
+ /* either returns Successful, Suspended, or some nasty error */
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)(
+ (pointer)client, pfont, range_flag, num_ranges, item_size,
+ (unsigned char *)data);
+ else
+ return Successful;
+}
+
+
+int
+RegisterFPEFunctions(
+ Bool (*name_func) (char *name),
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ void (*set_path_func) (void))
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) fsrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts(void)
+{
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(FSID id)
+{
+ return (FontPtr) LookupIDByType(SERVER_CLIENT, id, RT_NONE);
+}
+
+Font
+GetNewFontClientID(void)
+{
+ return (Font) FakeClientID(SERVER_CLIENT);
+}
+
+int
+StoreFontClientFont(
+ FontPtr pfont,
+ Font id)
+{
+ return AddResource(SERVER_CLIENT, id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(SERVER_CLIENT, id, RT_NONE);
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(
+ FontPathElementPtr fpe,
+ BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(
+ FontPathElementPtr fpe,
+ BlockHandlerProcPtr block_handler,
+ Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+ fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
diff --git a/app/xfs/difs/globals.c b/app/xfs/difs/globals.c
new file mode 100644
index 000000000..2ad924da7
--- /dev/null
+++ b/app/xfs/difs/globals.c
@@ -0,0 +1,67 @@
+/* $Xorg: globals.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * various font server globals
+ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * @(#)globals.c 4.3 5/3/91
+ *
+ */
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "misc.h"
+#include "site.h"
+
+ClientPtr *clients;
+ClientPtr serverClient;
+int currentMaxClients;
+char *server;
+int serverGeneration = 0;
+int argcGlobal;
+char **argvGlobal;
+
+long TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
+long ReapClientTime = CLIENT_TIMEOUT * MILLI_PER_SECOND;
diff --git a/app/xfs/difs/initfonts.c b/app/xfs/difs/initfonts.c
new file mode 100644
index 000000000..54dca7259
--- /dev/null
+++ b/app/xfs/difs/initfonts.c
@@ -0,0 +1,133 @@
+/* $Xorg: initfonts.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * %W% %E%
+ *
+ */
+/* $XFree86: xc/programs/xfs/difs/initfonts.c,v 1.6 2001/08/01 00:45:04 tsi Exp $ */
+
+#include <X11/fonts/font.h>
+#include "difs.h"
+#ifdef FONTCACHE
+#include "misc.h"
+#include <X11/extensions/fontcacheP.h>
+
+#define CACHE_HI_MARK (2048 * 1024)
+#define CACHE_LOW_MARK (((2048 * 1024) / 4) * 3)
+#define CACHE_BALANCE 70
+#endif
+
+FontPatternCachePtr fontPatternCache;
+#ifdef FONTCACHE
+FontCacheSettings cacheSettings = { -1, -1, -1 };
+#endif
+
+void
+InitFonts(void)
+{
+#ifdef FONTCACHE
+ long himark, lowmark;
+ long balance;
+ FontCacheSettings cs;
+#endif
+
+ if (fontPatternCache)
+ FreeFontPatternCache(fontPatternCache);
+ fontPatternCache = MakeFontPatternCache();
+
+ ResetFontPrivateIndex();
+
+#ifdef FONTCACHE
+ /* check cache control parameters */
+ if (cacheSettings.himark == -1) {
+ himark = CACHE_HI_MARK;
+ if (cacheSettings.lowmark == -1) {
+ lowmark = CACHE_LOW_MARK;
+ } else {
+ lowmark = cacheSettings.lowmark;
+ }
+ } else {
+ himark = cacheSettings.himark;
+ if (cacheSettings.lowmark == -1) {
+ lowmark = (himark / 4) * 3;
+ } else {
+ lowmark = cacheSettings.lowmark;
+ }
+ }
+ if (cacheSettings.balance == -1) {
+ balance = CACHE_BALANCE;
+ } else {
+ balance = cacheSettings.balance;
+ }
+
+ if (himark <= 0 || lowmark <= 0) {
+ FatalError("illegal cache parameter setting\n");
+ }
+ if (himark <= lowmark) {
+ FatalError("illegal cache parameter setting\n");
+ }
+ if (!(10 <= balance && balance <= 90)) {
+ FatalError("illegal cache parameter setting\n");
+ }
+
+ /* set cache control parameters */
+ cs.himark = himark;
+ cs.lowmark = lowmark;
+ cs.balance = balance;
+ if (FontCacheChangeSettings(&cs) == 0) {
+ FatalError("couldn't init renderer font cache\n");
+ }
+#endif
+
+#ifdef FONT_PCF
+ FontFileRegisterFpeFunctions();
+
+#endif
+
+#ifdef FONT_FS
+ fs_register_fpe_functions();
+#endif
+}
diff --git a/app/xfs/difs/main.c b/app/xfs/difs/main.c
new file mode 100644
index 000000000..4e6272c2b
--- /dev/null
+++ b/app/xfs/difs/main.c
@@ -0,0 +1,209 @@
+/* $Xorg: main.c,v 1.5 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+ * Font server main routine
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/main.c,v 3.11 2001/12/14 20:01:35 dawes Exp $ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "fsresource.h"
+#include "misc.h"
+#include "globals.h"
+#include "servermd.h"
+#include "cache.h"
+#include "site.h"
+#include "dispatch.h"
+#include "extentst.h"
+#include "difs.h"
+
+char *ConnectionInfo;
+int ConnInfoLen;
+
+Cache serverCache;
+
+#ifndef DEFAULT_CONFIG_FILE
+#define DEFAULT_CONFIG_FILE "/usr/lib/X11/fs/config"
+#endif
+
+#define SERVER_CACHE_SIZE 10000 /* for random server cacheables */
+
+static Bool create_connection_block(void);
+
+char *configfilename;
+extern Bool drone_server;
+
+extern OldListenRec *OldListen;
+extern int OldListenCount;
+
+int
+main(int argc, char *argv[])
+{
+ int i, oldumask;
+
+ argcGlobal = argc;
+ argvGlobal = argv;
+
+ configfilename = DEFAULT_CONFIG_FILE;
+
+ /* init stuff */
+ ProcessCmdLine(argc, argv);
+
+ /*
+ * Do this first thing, to get any options that only take effect at
+ * startup time. It is read again each time the server resets.
+ */
+ if (ReadConfigFile(configfilename) != FSSuccess) {
+ FatalError("couldn't read config file\n");
+ }
+ InitErrors();
+
+ /* make sure at least world write access is disabled */
+ if (((oldumask = umask(022)) & 002) == 002)
+ (void)umask(oldumask);
+
+ SetDaemonState();
+ SetUserId();
+
+ while (1) {
+ serverGeneration++;
+ OsInit();
+ if (serverGeneration == 1) {
+ /* do first time init */
+ serverCache = CacheInit(SERVER_CACHE_SIZE);
+ CreateSockets(OldListenCount, OldListen);
+ InitProcVectors();
+ clients = (ClientPtr *) fsalloc(MAXCLIENTS * sizeof(ClientPtr));
+ if (!clients)
+ FatalError("couldn't create client array\n");
+ for (i = MINCLIENT; i < MAXCLIENTS; i++)
+ clients[i] = NullClient;
+ /* make serverClient */
+ serverClient = (ClientPtr) fsalloc(sizeof(ClientRec));
+ if (!serverClient)
+ FatalError("couldn't create server client\n");
+ }
+ ResetSockets();
+
+ /* init per-cycle stuff */
+ InitClient(serverClient, SERVER_CLIENT, (pointer) 0);
+
+ clients[SERVER_CLIENT] = serverClient;
+ currentMaxClients = MINCLIENT;
+ currentClient = serverClient;
+
+ if (!InitClientResources(serverClient))
+ FatalError("couldn't init server resources\n");
+
+ InitExtensions();
+ InitAtoms();
+ InitFonts();
+ SetConfigValues();
+ if (!create_connection_block())
+ FatalError("couldn't create connection block\n");
+
+#ifdef DEBUG
+ fprintf(stderr, "Entering Dispatch loop\n");
+#endif
+
+ Dispatch();
+
+#ifdef DEBUG
+ fprintf(stderr, "Leaving Dispatch loop\n");
+#endif
+
+ /* clean up per-cycle stuff */
+ CacheReset();
+ CloseDownExtensions();
+ if ((dispatchException & DE_TERMINATE) || drone_server)
+ break;
+ fsfree(ConnectionInfo);
+ /* note that we're parsing it again, for each time the server resets */
+ if (ReadConfigFile(configfilename) != FSSuccess)
+ FatalError("couldn't read config file\n");
+ }
+
+ CloseSockets();
+ CloseErrors();
+ exit(0);
+}
+
+int
+NotImplemented(void)
+{
+ NoopDDA(); /* dummy to get difsutils.o to link */
+ /* Getting here can become the next xfs exploit... so don't exit */
+ ErrorF("not implemented\n");
+
+ return (FSBadImplementation);
+}
+
+static Bool
+create_connection_block(void)
+{
+ fsConnSetupAccept setup;
+ char *pBuf;
+
+ setup.release_number = VENDOR_RELEASE;
+ setup.vendor_len = strlen(VENDOR_STRING);
+ setup.max_request_len = MAX_REQUEST_SIZE;
+ setup.length = (SIZEOF(fsConnSetupAccept) + setup.vendor_len + 3) >> 2;
+
+ ConnInfoLen = SIZEOF(fsConnSetupAccept) + ((setup.vendor_len + 3) & ~3);
+ ConnectionInfo = (char *) fsalloc(ConnInfoLen);
+ if (!ConnectionInfo)
+ return FALSE;
+
+ memmove( ConnectionInfo, (char *) &setup, SIZEOF(fsConnSetupAccept));
+ pBuf = ConnectionInfo + SIZEOF(fsConnSetupAccept);
+ memmove( pBuf, VENDOR_STRING, (int) setup.vendor_len);
+
+ return TRUE;
+}
diff --git a/app/xfs/difs/resource.c b/app/xfs/difs/resource.c
new file mode 100644
index 000000000..42227fea8
--- /dev/null
+++ b/app/xfs/difs/resource.c
@@ -0,0 +1,571 @@
+/* $Xorg: resource.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * %W% %G%
+ *
+ */
+/* $XFree86: xc/programs/xfs/difs/resource.c,v 3.8tsi Exp $ */
+/*
+ * a resource is a 32 bit quantity. the upper 12 bits are client id.
+ * client provides a 19 bit resource id. this is "hashed" by me by
+ * taking the 10 lower bits and xor'ing with the mid 10 bits.
+ *
+ * It is sometimes necessary for the server to create an ID that looks
+ * like it belongs to a client. This ID, however, must not be one
+ * the client actually can create, or we have the potential for conflict.
+ * The 20th bit of the ID is resevered for the server's use for this
+ * purpose. By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ * 1, and an otherwise unused ID in the low 19 bits, we can create a
+ * resource "owned" by the client.
+ *
+ * The following IDs are currently reserved for siccing on the client:
+ * 1 - allocated color to be freed when the client dies
+ */
+
+#include <X11/fonts/FS.h>
+#include "misc.h"
+#include "os.h"
+#include "fsresource.h"
+#include "clientstr.h"
+#include "dispatch.h"
+#include "globals.h"
+
+static void rebuild_table(int client);
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+ struct _Resource *next;
+ FSID id;
+ RESTYPE type;
+ pointer value;
+} ResourceRec, *ResourcePtr;
+
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+ ResourcePtr *resources;
+ int elements;
+ int buckets;
+ int hashsize; /* log(2)(buckets) */
+ FSID fakeID;
+ FSID endFakeID;
+ FSID expectID;
+} ClientResourceRec;
+
+static RESTYPE lastResourceType;
+#ifdef NOTYET
+static RESTYPE lastResourceClass;
+#endif
+static RESTYPE TypeMask;
+
+typedef int (*DeleteType) (void *, FSID);
+
+extern int CloseClientFont(ClientPtr, FSID);
+
+static DeleteType *DeleteFuncs = (DeleteType *) NULL;
+
+#ifdef NOTYET
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+ RESTYPE next = lastResourceType + 1;
+ DeleteType *funcs;
+
+ if (next & lastResourceClass)
+ return 0;
+ funcs = (DeleteType *) fsrealloc(DeleteFuncs,
+ (next + 1) * sizeof(DeleteType));
+ if (!funcs)
+ return 0;
+ lastResourceType = next;
+ DeleteFuncs = funcs;
+ DeleteFuncs[next] = deleteFunc;
+ return next;
+}
+
+RESTYPE
+CreateNewResourceClass(void)
+{
+ RESTYPE next = lastResourceClass >> 1;
+
+ if (next & lastResourceType)
+ return 0;
+ lastResourceClass = next;
+ TypeMask = next - 1;
+ return next;
+}
+
+#endif /* NOTYET */
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ * When a new client is created, call this to allocate space
+ * in resource table
+ *****************/
+
+int
+NoneDeleteFunc (void *ptr, FSID id)
+{
+ return FSSuccess;
+}
+
+Bool
+InitClientResources(ClientPtr client)
+{
+ register int i,
+ j;
+
+ if (client == serverClient) {
+ lastResourceType = RT_LASTPREDEF;
+#ifdef NOTYET
+ lastResourceClass = RC_LASTPREDEF;
+#endif
+ TypeMask = RC_LASTPREDEF - 1;
+ if (DeleteFuncs)
+ fsfree(DeleteFuncs);
+ DeleteFuncs = (DeleteType *) fsalloc((lastResourceType + 1) *
+ sizeof(DeleteType));
+ if (!DeleteFuncs)
+ return FALSE;
+ DeleteFuncs[RT_NONE & TypeMask] = NoneDeleteFunc;
+ DeleteFuncs[RT_FONT & TypeMask] = (DeleteType)CloseClientFont;
+ DeleteFuncs[RT_AUTHCONT & TypeMask] = (DeleteType)DeleteAuthCont;
+ }
+ clientTable[i = client->index].resources =
+ (ResourcePtr *) fsalloc(INITBUCKETS * sizeof(ResourcePtr));
+ if (!clientTable[i].resources)
+ return FALSE;
+ clientTable[i].buckets = INITBUCKETS;
+ clientTable[i].elements = 0;
+ clientTable[i].hashsize = INITHASHSIZE;
+ clientTable[i].fakeID = SERVER_BIT;
+ clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+ for (j = 0; j < INITBUCKETS; j++) {
+ clientTable[i].resources[j] = NullResource;
+ }
+ return TRUE;
+}
+
+static int
+hash(int client, FSID id)
+{
+ id &= RESOURCE_ID_MASK;
+ switch (clientTable[client].hashsize) {
+ case 6:
+ return ((int) (0x03F & (id ^ (id >> 6) ^ (id >> 12))));
+ case 7:
+ return ((int) (0x07F & (id ^ (id >> 7) ^ (id >> 13))));
+ case 8:
+ return ((int) (0x0FF & (id ^ (id >> 8) ^ (id >> 16))));
+ case 9:
+ return ((int) (0x1FF & (id ^ (id >> 9))));
+ case 10:
+ return ((int) (0x3FF & (id ^ (id >> 10))));
+ case 11:
+ return ((int) (0x7FF & (id ^ (id >> 11))));
+ }
+ return -1;
+}
+
+
+static Font
+AvailableID(
+ register int client,
+ register FSID id,
+ register FSID maxid,
+ register FSID goodid)
+{
+ register ResourcePtr res;
+
+ if ((goodid >= id) && (goodid <= maxid))
+ return goodid;
+ for (; id <= maxid; id++)
+ {
+ res = clientTable[client].resources[hash(client, id)];
+ while (res && (res->id != id))
+ res = res->next;
+ if (!res)
+ return id;
+ }
+ return 0;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+FSID
+FakeClientID(int client)
+{
+ register FSID id, maxid;
+ register ResourcePtr *resp;
+ register ResourcePtr res;
+ register int i;
+ FSID goodid;
+
+ id = clientTable[client].fakeID++;
+ if (id != clientTable[client].endFakeID)
+ return id;
+ id = ((Mask)client << CLIENTOFFSET) | SERVER_BIT;
+ maxid = id | RESOURCE_ID_MASK;
+ goodid = 0;
+ for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+ --i >= 0;)
+ {
+ for (res = *resp++; res; res = res->next)
+ {
+ if ((res->id < id) || (res->id > maxid))
+ continue;
+ if (((res->id - id) >= (maxid - res->id)) ?
+ (goodid = AvailableID(client, id, res->id - 1, goodid)) :
+ !(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+ maxid = res->id - 1;
+ else
+ id = res->id + 1;
+ }
+ }
+ if (id > maxid) {
+ if (!client)
+ FatalError("FakeClientID: server internal ids exhausted\n");
+ MarkClientException(clients[client]);
+ id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+ maxid = id | RESOURCE_ID_MASK;
+ }
+ clientTable[client].fakeID = id + 1;
+ clientTable[client].endFakeID = maxid + 1;
+ return id;
+}
+
+Bool
+AddResource(
+ int cid,
+ FSID id,
+ RESTYPE type,
+ pointer value)
+{
+ register ClientResourceRec *rrec;
+ register ResourcePtr res,
+ *head;
+
+ rrec = &clientTable[cid];
+ if (!rrec->buckets) {
+ ErrorF("AddResource(%x, %x, %x), client=%d \n",
+ id, type, value, cid);
+ FatalError("client not in use\n");
+ }
+ if ((rrec->elements >= 4 * rrec->buckets) &&
+ (rrec->hashsize < MAXHASHSIZE))
+ rebuild_table(cid);
+ head = &rrec->resources[hash(cid, id)];
+ res = (ResourcePtr) fsalloc(sizeof(ResourceRec));
+ if (!res) {
+ (*DeleteFuncs[type & TypeMask]) (value, id);
+ return FALSE;
+ }
+ res->next = *head;
+ res->id = id;
+ res->type = type;
+ res->value = value;
+ *head = res;
+ rrec->elements++;
+ if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ rrec->expectID = id + 1;
+ return TRUE;
+}
+
+static void
+rebuild_table(int client)
+{
+ register int j;
+ register ResourcePtr res,
+ next;
+ ResourcePtr **tails,
+ *resources;
+ register ResourcePtr **tptr,
+ *rptr;
+
+ /*
+ * For now, preserve insertion order, since some ddx layers depend on
+ * resources being free in the opposite order they are added.
+ */
+
+ j = 2 * clientTable[client].buckets;
+ tails = (ResourcePtr **) ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+ if (!tails)
+ return;
+ resources = (ResourcePtr *) fsalloc(j * sizeof(ResourcePtr));
+ if (!resources) {
+ DEALLOCATE_LOCAL(tails);
+ return;
+ }
+ for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++) {
+ *rptr = NullResource;
+ *tptr = rptr;
+ }
+ clientTable[client].hashsize++;
+ for (j = clientTable[client].buckets,
+ rptr = clientTable[client].resources;
+ --j >= 0;
+ rptr++) {
+ for (res = *rptr; res; res = next) {
+ next = res->next;
+ res->next = NullResource;
+ tptr = &tails[hash(client, res->id)];
+ **tptr = res;
+ *tptr = &res->next;
+ }
+ }
+ DEALLOCATE_LOCAL(tails);
+ clientTable[client].buckets *= 2;
+ fsfree(clientTable[client].resources);
+ clientTable[client].resources = resources;
+}
+
+void
+FreeResource(
+ int cid,
+ FSID id,
+ RESTYPE skipDeleteFuncType)
+{
+ register ResourcePtr res;
+ register ResourcePtr *prev,
+ *head;
+ register int *eltptr;
+ int elements;
+ Bool gotOne = FALSE;
+
+ if (clientTable[cid].buckets) {
+ head = &clientTable[cid].resources[hash(cid, id)];
+ eltptr = &clientTable[cid].elements;
+
+ prev = head;
+ while ((res = *prev) != (ResourcePtr) 0) {
+ if (res->id == id) {
+ RESTYPE rtype = res->type;
+
+ *prev = res->next;
+ elements = --*eltptr;
+ if (rtype != skipDeleteFuncType)
+ (*DeleteFuncs[rtype & TypeMask]) (res->value, res->id);
+ fsfree(res);
+ if (*eltptr != elements)
+ prev = head;/* prev may no longer be valid */
+ gotOne = TRUE;
+ } else
+ prev = &res->next;
+ }
+ }
+ if (!gotOne)
+ FatalError("freeing resource id=%X which isn't there\n", id);
+}
+
+#ifdef NOTYET
+void
+FreeResourceByType(
+ int cid,
+ FSID id,
+ RESTYPE type,
+ Bool skipFree)
+{
+ register ResourcePtr res;
+ register ResourcePtr *prev,
+ *head;
+
+ if (clientTable[cid].buckets) {
+ head = &clientTable[cid].resources[hash(cid, id)];
+
+ prev = head;
+ while (res = *prev) {
+ if (res->id == id && res->type == type) {
+ *prev = res->next;
+ if (!skipFree)
+ (*DeleteFuncs[type & TypeMask]) (res->value, res->id);
+ fsfree(res);
+ break;
+ } else
+ prev = &res->next;
+ }
+ }
+}
+
+/*
+ * Change the value associated with a resource id. Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue(
+ int cid,
+ FSID id,
+ RESTYPE rtype,
+ pointer value)
+{
+ register ResourcePtr res;
+
+ if (clientTable[cid].buckets) {
+ res = clientTable[cid].resources[hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype)) {
+ res->value = value;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#endif /* NOTYET */
+
+void
+FreeClientResources(ClientPtr client)
+{
+ register ResourcePtr *resources;
+ register ResourcePtr this;
+ int j;
+
+ /*
+ * This routine shouldn't be called with a null client, but just in case
+ * ...
+ */
+
+ if (!client)
+ return;
+
+ resources = clientTable[client->index].resources;
+ for (j = 0; j < clientTable[client->index].buckets; j++) {
+ /*
+ * It may seem silly to update the head of this resource list as we
+ * delete the members, since the entire list will be deleted any way,
+ * but there are some resource deletion functions "FreeClientPixels"
+ * for one which do a LookupID on another resource id (a Colormap id
+ * in this case), so the resource list must be kept valid up to the
+ * point that it is deleted, so every time we delete a resource, we
+ * must update the head, just like in free_resource. I hope that this
+ * doesn't slow down mass deletion appreciably. PRH
+ */
+
+ ResourcePtr *head;
+
+ head = &resources[j];
+
+ for (this = *head; this; this = *head) {
+ RESTYPE rtype = this->type;
+
+ *head = this->next;
+ (*DeleteFuncs[rtype & TypeMask]) (this->value, this->id);
+ fsfree(this);
+ }
+ }
+ fsfree(clientTable[client->index].resources);
+ clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources(void)
+{
+ int i;
+
+ for (i = 0; i < currentMaxClients; i++) {
+ if (clientTable[i].buckets)
+ FreeClientResources(clients[i]);
+ }
+}
+
+/*
+ * lookup_id_by_type returns the object with the given id and type, else NULL.
+ */
+pointer
+LookupIDByType(
+ int cid,
+ FSID id,
+ RESTYPE rtype)
+{
+ register ResourcePtr res;
+
+ if (clientTable[cid].buckets) {
+ res = clientTable[cid].resources[hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type == rtype))
+ return res->value;
+ }
+ return (pointer) NULL;
+}
+
+#ifdef NOTYET
+/*
+ * lookup_ID_by_class returns the object with the given id and any one of the
+ * given classes, else NULL.
+ */
+pointer
+LookupIDByClass(
+ FSID id,
+ RESTYPE classes)
+{
+ int cid;
+ register ResourcePtr res;
+
+ if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) {
+ res = clientTable[cid].resources[hash(cid, id)];
+
+ for (; res; res = res->next)
+ if ((res->id == id) && (res->type & classes))
+ return res->value;
+ }
+ return (pointer) NULL;
+}
+
+#endif /* NOTYET */
diff --git a/app/xfs/difs/swaprep.c b/app/xfs/difs/swaprep.c
new file mode 100644
index 000000000..b7cb2b2ef
--- /dev/null
+++ b/app/xfs/difs/swaprep.c
@@ -0,0 +1,507 @@
+/* $Xorg: swaprep.c,v 1.4 2001/02/09 02:05:43 xorgcvs Exp $ */
+/*
+ * font server reply swapping
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/swaprep.c,v 1.4 2001/01/17 23:45:29 dawes Exp $ */
+
+#include <swaprep.h>
+#include <swapreq.h>
+
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+
+static void SwapConnSetupAccept(fsConnSetupAccept *pConnSetup, fsConnSetupAccept *pConnSetupT);
+
+void
+Swap32Write(
+ ClientPtr client,
+ int size,
+ long *pbuf)
+{
+ int n,
+ i;
+
+ size >>= 2;
+ for (i = 0; i < size; i++) {
+ swapl(&pbuf[i], n);
+ }
+ (void) WriteToClient(client, size << 2, (char *) pbuf);
+}
+
+void
+Swap16Write(
+ ClientPtr client,
+ int size,
+ short *pbuf)
+{
+ int n,
+ i;
+
+ size >>= 1;
+ for (i = 0; i < size; i++) {
+ swaps(&pbuf[i], n);
+ }
+ (void) WriteToClient(client, size << 1, (char *) pbuf);
+}
+
+void
+CopySwap32Write(
+ ClientPtr client,
+ int size,
+ long *pbuf)
+{
+ int bufsize = size;
+ long *pbufT;
+ long *from,
+ *to,
+ *fromLast,
+ *toLast;
+ long tmpbuf[1];
+
+ while (!(pbufT = (long *) ALLOCATE_LOCAL(bufsize))) {
+ bufsize >>= 1;
+ if (bufsize == 4) {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+ /* convert lengths from # of bytes to # of longs */
+ size >>= 2;
+ bufsize >>= 2;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+
+ to = pbufT;
+ toLast = to + min(bufsize, fromLast - from);
+ nbytes = (toLast - to) << 2;
+ while (to < toLast) {
+ /*
+ * can't write "cpswapl(*from++, *to++)" because cpswapl is a
+ * macro that evaulates its args more than once
+ */
+ cpswapl(*from, *to);
+ from++;
+ to++;
+ }
+ (void) WriteToClient(client, nbytes, (char *) pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ DEALLOCATE_LOCAL((char *) pbufT);
+}
+
+void
+CopySwap16Write(
+ ClientPtr client,
+ int size,
+ short *pbuf)
+{
+ int bufsize = size;
+ short *pbufT;
+ register short *from,
+ *to,
+ *fromLast,
+ *toLast;
+ short tmpbuf[2];
+
+ /* Allocate as big a buffer as we can... */
+ while (!(pbufT = (short *) ALLOCATE_LOCAL(bufsize))) {
+ bufsize >>= 1;
+ if (bufsize == 4) {
+ pbufT = tmpbuf;
+ break;
+ }
+ }
+
+ /* convert lengths from # of bytes to # of shorts */
+ size >>= 1;
+ bufsize >>= 1;
+
+ from = pbuf;
+ fromLast = from + size;
+ while (from < fromLast) {
+ int nbytes;
+
+ to = pbufT;
+ toLast = to + min(bufsize, fromLast - from);
+ nbytes = (toLast - to) << 1;
+ while (to < toLast) {
+ /*
+ * can't write "cpswaps(*from++, *to++)" because cpswaps is a
+ * macro that evaulates its args more than once
+ */
+ cpswaps(*from, *to);
+ from++;
+ to++;
+ }
+ (void) WriteToClient(client, nbytes, (char *) pbufT);
+ }
+
+ if (pbufT != tmpbuf)
+ DEALLOCATE_LOCAL((char *) pbufT);
+}
+
+
+#undef pRep
+#define pRep ((fsGenericReply *)data)
+
+void
+SGenericReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+
+#undef pRep
+#define pRep ((fsListExtensionsReply *)data)
+
+void
+SListExtensionsReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsQueryExtensionReply *)data)
+
+void
+SQueryExtensionReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->major_version = lswaps(pRep->major_version);
+ pRep->minor_version = lswaps(pRep->minor_version);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsListCataloguesReply *)data)
+
+void
+SListCataloguesReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->num_replies = lswapl(pRep->num_replies);
+ pRep->num_catalogues = lswapl(pRep->num_catalogues);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsCreateACReply *)data)
+
+void
+SCreateACReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->status = lswaps(pRep->status);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsGetEventMaskReply *)data)
+
+void
+SGetEventMaskReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->event_mask = lswapl(pRep->event_mask);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsGetResolutionReply *)data)
+
+void
+SGetResolutionReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsListFontsReply *)data)
+
+void
+SListFontsReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->following = lswapl(pRep->following);
+ pRep->nFonts = lswapl(pRep->nFonts);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#define SwapXFontInfoHeader(reply) \
+ reply->font_header_flags = lswapl(reply->font_header_flags); \
+ \
+ reply->font_header_min_bounds_left = lswaps(reply->font_header_min_bounds_left); \
+ reply->font_header_min_bounds_right = lswaps(reply->font_header_min_bounds_right); \
+ reply->font_header_min_bounds_width = lswaps(reply->font_header_min_bounds_width); \
+ reply->font_header_min_bounds_ascent = lswaps(reply->font_header_min_bounds_ascent); \
+ reply->font_header_min_bounds_descent = lswaps(reply->font_header_min_bounds_descent); \
+ reply->font_header_min_bounds_attributes = lswaps(reply->font_header_min_bounds_attributes); \
+ \
+ reply->font_header_max_bounds_left = lswaps(reply->font_header_max_bounds_left); \
+ reply->font_header_max_bounds_right = lswaps(reply->font_header_max_bounds_right); \
+ reply->font_header_max_bounds_width = lswaps(reply->font_header_max_bounds_width); \
+ reply->font_header_max_bounds_ascent = lswaps(reply->font_header_max_bounds_ascent); \
+ reply->font_header_max_bounds_descent = lswaps(reply->font_header_max_bounds_descent); \
+ reply->font_header_max_bounds_attributes = lswaps(reply->font_header_max_bounds_attributes); \
+ \
+ reply->font_header_font_ascent = lswaps(reply->font_header_font_ascent); \
+ reply->font_header_font_descent = lswaps(reply->font_header_font_descent)
+
+#undef pRep
+#define pRep ((fsListFontsWithXInfoReply *)data)
+
+void
+SListFontsWithXInfoReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ if (size > SIZEOF(fsGenericReply)) { /* not last in series? */
+ pRep->nReplies = lswapl(pRep->nReplies);
+ SwapXFontInfoHeader(pRep);
+ }
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsOpenBitmapFontReply *)data)
+
+void
+SOpenBitmapFontReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->otherid = lswapl(pRep->otherid);
+
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsQueryXInfoReply *)data)
+
+void
+SQueryXInfoReply(
+ ClientPtr client,
+ int size,
+ void * data)
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ SwapXFontInfoHeader(pRep);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsQueryXExtents8Reply *)data)
+
+void
+SQueryXExtentsReply(
+ ClientPtr client,
+ int size,
+ void * data) /* QueryXExtents16Reply is the same */
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->num_extents = lswapl(pRep->num_extents);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+#undef pRep
+#define pRep ((fsQueryXBitmaps8Reply *)data)
+
+void
+SQueryXBitmapsReply(
+ ClientPtr client,
+ int size,
+ void * data) /* QueryXBitmaps16Reply is the same */
+{
+ pRep->sequenceNumber = lswaps(pRep->sequenceNumber);
+ pRep->length = lswapl(pRep->length);
+ pRep->replies_hint = lswapl(pRep->replies_hint);
+ pRep->num_chars = lswapl(pRep->num_chars);
+ pRep->nbytes = lswapl(pRep->nbytes);
+ (void) WriteToClient(client, size, (char *) pRep);
+}
+
+void
+SErrorEvent(fsError *error, fsError *perror)
+{
+ *perror = *error;
+ perror->sequenceNumber = lswaps(perror->sequenceNumber);
+ perror->length = lswapl(perror->length);
+ perror->timestamp = lswapl(perror->timestamp);
+}
+
+void
+WriteSConnectionInfo(
+ ClientPtr client,
+ unsigned long size,
+ char *pInfo)
+{
+ char *pInfoT,
+ *pInfoTBase;
+ fsConnSetupAccept *pConnSetup = (fsConnSetupAccept *) pInfo;
+ int i;
+
+ pInfoT = pInfoTBase = (char *) ALLOCATE_LOCAL(size);
+ if (!pInfoT) {
+ client->noClientException = -2;
+ return;
+ }
+ SwapConnSetupAccept(pConnSetup, (fsConnSetupAccept *) pInfoT);
+ pInfoT += SIZEOF(fsConnSetup);
+ pInfo += SIZEOF(fsConnSetup);
+
+ i = (pConnSetup->vendor_len + 3) & ~3;
+ memmove( pInfoT, pInfo, i);
+
+ (void) WriteToClient(client, (int) size, (char *) pInfoTBase);
+ DEALLOCATE_LOCAL(pInfoTBase);
+}
+
+static void
+SwapConnSetupAccept(fsConnSetupAccept *pConnSetup, fsConnSetupAccept *pConnSetupT)
+{
+ pConnSetupT->length = lswapl(pConnSetup->length);
+ pConnSetupT->max_request_len = lswaps(pConnSetup->max_request_len);
+ pConnSetupT->vendor_len = lswaps(pConnSetup->vendor_len);
+ pConnSetupT->release_number = lswapl(pConnSetup->release_number);
+}
+
+void
+WriteSConnSetup(ClientPtr client, fsConnSetup *pcsp)
+{
+ fsConnSetup cspT;
+
+ cspT.status = lswaps(pcsp->status);
+ cspT.major_version = lswaps(pcsp->major_version);
+ cspT.minor_version = lswaps(pcsp->minor_version);
+ cspT.num_alternates = pcsp->num_alternates;
+ cspT.auth_index = pcsp->auth_index;
+ cspT.alternate_len = lswaps(pcsp->alternate_len);
+ cspT.auth_len = lswaps(pcsp->auth_len);
+ (void) WriteToClient(client, SIZEOF(fsConnSetup), (char *) &cspT);
+}
+
+static void
+SwapPropOffset(char *po)
+{
+ int i, n;
+
+ for (i=0; i<4; i++)
+ {
+ swapl(po, n);
+ po += 4;
+ }
+}
+
+void
+SwapPropInfo(fsPropInfo *pi)
+{
+ int i;
+ char *po;
+
+ po = (char *) pi + SIZEOF(fsPropInfo);
+ for (i = 0; i < pi->num_offsets; i++)
+ {
+ SwapPropOffset(po);
+ po += SIZEOF(fsPropOffset);
+ }
+
+ pi->num_offsets = lswapl(pi->num_offsets);
+ pi->data_len = lswapl(pi->data_len);
+}
+
+void
+SwapExtents(fsXCharInfo *extents, int num)
+{
+ SwapShorts((short *)extents, num * (SIZEOF(fsXCharInfo) / 2));
+}
diff --git a/app/xfs/difs/swapreq.c b/app/xfs/difs/swapreq.c
new file mode 100644
index 000000000..f4741587a
--- /dev/null
+++ b/app/xfs/difs/swapreq.c
@@ -0,0 +1,297 @@
+/* $Xorg: swapreq.c,v 1.4 2001/02/09 02:05:43 xorgcvs Exp $ */
+/*
+ * swapped requests
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/swapreq.c,v 1.6 2001/06/25 20:40:17 paulo Exp $ */
+
+#include <swapreq.h>
+
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "globals.h"
+#include "dispatch.h"
+
+void
+SwapLongs(long *list, unsigned long count)
+{
+ int n;
+ register char *longs = (char *)list;
+
+ while (count >= 8) {
+ swapl(longs + 0, n);
+ swapl(longs + 4, n);
+ swapl(longs + 8, n);
+ swapl(longs + 12, n);
+ swapl(longs + 16, n);
+ swapl(longs + 20, n);
+ swapl(longs + 24, n);
+ swapl(longs + 28, n);
+ longs += 32;
+ count -= 8;
+ }
+ if (count != 0) {
+ do {
+ swapl(longs, n);
+ longs += 4;
+ } while (--count != 0);
+ }
+}
+
+/* Byte swap a list of shorts */
+
+void
+SwapShorts(short *list, unsigned long count)
+{
+ register char *shorts = (char *)list;
+ register int n;
+
+ while (count >= 16) {
+ swaps(shorts + 0, n);
+ swaps(shorts + 2, n);
+ swaps(shorts + 4, n);
+ swaps(shorts + 6, n);
+ swaps(shorts + 8, n);
+ swaps(shorts + 10, n);
+ swaps(shorts + 12, n);
+ swaps(shorts + 14, n);
+ swaps(shorts + 16, n);
+ swaps(shorts + 18, n);
+ swaps(shorts + 20, n);
+ swaps(shorts + 22, n);
+ swaps(shorts + 24, n);
+ swaps(shorts + 26, n);
+ swaps(shorts + 28, n);
+ swaps(shorts + 30, n);
+ shorts += 32;
+ count -= 16;
+ }
+ if (count != 0) {
+ do {
+ swaps(shorts, n);
+ shorts += 2;
+ } while (--count != 0);
+ }
+}
+
+/*
+ * used for all requests that have nothing but 'length' swapped
+ */
+int
+SProcSimpleRequest(ClientPtr client)
+{
+ REQUEST(fsReq);
+ stuff->length = lswaps(stuff->length);
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+/*
+ * used for all requests that have nothing but 'length' & a resource id swapped
+ */
+int
+SProcResourceRequest(ClientPtr client)
+{
+ REQUEST(fsResourceReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->id = lswapl(stuff->id);
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+static int
+swap_auth(ClientPtr client, pointer data, int num, int length)
+{
+ unsigned char *p;
+ unsigned char t;
+ CARD16 namelen,
+ datalen;
+ int i;
+
+ p = data;
+ for (i = 0; i < num; i++) {
+ if (p - (unsigned char *)data > length - 4) {
+ int lengthword = length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+ namelen = *(CARD16 *) p;
+ t = p[0];
+ p[0] = p[1];
+ p[1] = t;
+ p += 2;
+ datalen = *(CARD16 *) p;
+ t = p[0];
+ p[0] = p[1];
+ p[1] = t;
+ p += 2;
+ p += (namelen + 3) & ~3;
+ p += (datalen + 3) & ~3;
+ }
+ if (!num)
+ p += 4;
+ if (p - (unsigned char *)data != length) {
+ int lengthword = length;
+
+ SendErrToClient(client, FSBadLength, (pointer)&lengthword);
+ return (FSBadLength);
+ }
+
+ return (FSSuccess);
+}
+
+int
+SProcCreateAC(ClientPtr client)
+{
+ int status;
+
+ REQUEST(fsCreateACReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->acid = lswapl(stuff->acid);
+ status = swap_auth(client, (pointer) &stuff[1],
+ stuff->num_auths, stuff->length);
+ if (status != FSSuccess)
+ return (status);
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+int
+SProcSetResolution(ClientPtr client)
+{
+ REQUEST(fsSetResolutionReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->num_resolutions = lswaps(stuff->num_resolutions);
+ if ((int)stuff->length - (&stuff[1] - &stuff[0]) !=
+ stuff->num_resolutions * sizeof(fsResolution))
+ return (FSBadLength);
+ SwapShorts((short *) &stuff[1], stuff->num_resolutions);
+
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+
+int
+SProcQueryExtension(ClientPtr client)
+{
+ REQUEST(fsQueryExtensionReq);
+ stuff->length = lswaps(stuff->length);
+ return ((*ProcVector[FS_QueryExtension]) (client));
+}
+
+int
+SProcListCatalogues(ClientPtr client)
+{
+ REQUEST(fsListCataloguesReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->maxNames = lswapl(stuff->maxNames);
+ stuff->nbytes = lswaps(stuff->nbytes);
+ return ((*ProcVector[FS_ListCatalogues]) (client));
+}
+
+int
+SProcListFonts(ClientPtr client)
+{
+ REQUEST(fsListFontsReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->maxNames = lswapl(stuff->maxNames);
+ stuff->nbytes = lswaps(stuff->nbytes);
+ return ((*ProcVector[FS_ListFonts]) (client));
+}
+
+int
+SProcListFontsWithXInfo(ClientPtr client)
+{
+ REQUEST(fsListFontsWithXInfoReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->maxNames = lswapl(stuff->maxNames);
+ stuff->nbytes = lswaps(stuff->nbytes);
+ return ((*ProcVector[FS_ListFontsWithXInfo]) (client));
+}
+
+int
+SProcOpenBitmapFont(ClientPtr client)
+{
+ REQUEST(fsOpenBitmapFontReq);
+ stuff->length = lswaps(stuff->length);
+ stuff->fid = lswapl(stuff->fid);
+ stuff->format_hint = lswapl(stuff->format_hint);
+ stuff->format_mask = lswapl(stuff->format_mask);
+ return ((*ProcVector[FS_OpenBitmapFont]) (client));
+}
+
+int
+SProcQueryXExtents(ClientPtr client)
+{
+ REQUEST(fsQueryXExtents8Req); /* 8 and 16 are the same here */
+ stuff->length = lswaps(stuff->length);
+ stuff->fid = lswapl(stuff->fid);
+ stuff->num_ranges = lswapl(stuff->num_ranges);
+
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+int
+SProcQueryXBitmaps(ClientPtr client)
+{
+ REQUEST(fsQueryXBitmaps8Req); /* 8 and 16 are the same here */
+ stuff->length = lswaps(stuff->length);
+ stuff->fid = lswapl(stuff->fid);
+ stuff->format = lswapl(stuff->format);
+ stuff->num_ranges = lswapl(stuff->num_ranges);
+
+ return ((*ProcVector[stuff->reqType]) (client));
+}
+
+int
+SwapConnClientPrefix(ClientPtr client, fsConnClientPrefix *pCCP)
+{
+ REQUEST(fsFakeReq);
+
+ pCCP->major_version = lswaps(pCCP->major_version);
+ pCCP->minor_version = lswaps(pCCP->minor_version);
+ pCCP->auth_len = lswaps(pCCP->auth_len);
+ return (swap_auth(client, (pointer) &pCCP[1],
+ pCCP->num_auths, stuff->length));
+}
diff --git a/app/xfs/difs/tables.c b/app/xfs/difs/tables.c
new file mode 100644
index 000000000..3a2ab3c9f
--- /dev/null
+++ b/app/xfs/difs/tables.c
@@ -0,0 +1,164 @@
+/* $Xorg: tables.c,v 1.4 2001/02/09 02:05:43 xorgcvs Exp $ */
+/*
+ * all the dispatch, error, event and reply vectors
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/xfs/difs/tables.c,v 1.5 2001/01/17 23:45:29 dawes Exp $ */
+
+#include <dispatch.h>
+#include <swaprep.h>
+#include <swapreq.h>
+#include <fsevents.h>
+
+#include "globals.h"
+#include "client.h"
+#include "extentst.h"
+#include "difs.h"
+
+InitialFunc InitialVector[3] =
+{
+ 0,
+ ProcInitialConnection,
+ ProcEstablishConnection
+};
+
+ProcFunc ProcVector[NUM_PROC_VECTORS] =
+{
+ ProcNoop, /* 0 */
+ ProcListExtensions,
+ ProcQueryExtension,
+ ProcListCatalogues,
+ ProcSetCatalogues,
+ ProcGetCatalogues, /* 5 */
+ ProcSetEventMask,
+ ProcGetEventMask,
+ ProcCreateAC,
+ ProcFreeAC,
+ ProcSetAuthorization, /* 10 */
+ ProcSetResolution,
+ ProcGetResolution,
+ ProcListFonts,
+ ProcListFontsWithXInfo,
+ ProcOpenBitmapFont, /* 15 */
+ ProcQueryXInfo,
+ ProcQueryXExtents,
+ ProcQueryXExtents,
+ ProcQueryXBitmaps,
+ ProcQueryXBitmaps, /* 20 */
+ ProcCloseFont,
+ 0,
+ 0,
+ 0
+};
+
+SwappedProcFunc SwappedProcVector[NUM_PROC_VECTORS] =
+{
+ SProcSimpleRequest, /* 0 */
+ SProcSimpleRequest,
+ SProcQueryExtension,
+ SProcListCatalogues,
+ SProcSimpleRequest, /* SetCatalogues */
+ SProcSimpleRequest, /* 5 */
+ SProcResourceRequest, /* SetEventMask */
+ SProcSimpleRequest,
+ SProcCreateAC,
+ SProcResourceRequest,
+ SProcResourceRequest, /* 10 */
+ SProcSetResolution,
+ SProcSimpleRequest,
+ SProcListFonts,
+ SProcListFontsWithXInfo,
+ SProcOpenBitmapFont, /* 15 */
+ SProcResourceRequest,
+ SProcQueryXExtents,
+ SProcQueryXExtents,
+ SProcQueryXBitmaps,
+ SProcQueryXBitmaps, /* 20 */
+ SProcResourceRequest,
+ 0,
+ 0,
+ 0
+};
+
+EventSwapFunc EventSwapVector[NUM_EVENT_VECTORS] =
+{
+ SErrorEvent,
+ (EventSwapFunc)NotImplemented,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+ReplySwapFunc ReplySwapVector[NUM_PROC_VECTORS] =
+{
+ (ReplySwapFunc)NotImplemented, /* NoOp */
+ SListExtensionsReply,
+ SQueryExtensionReply, /* SQueryExtensionReply */
+ SListCataloguesReply,
+ (ReplySwapFunc)NotImplemented, /* SetCatalogues */
+ SGenericReply, /* GetCatalogues */
+ (ReplySwapFunc)NotImplemented, /* SetEventMask */
+ SGetEventMaskReply,
+ SCreateACReply,
+ (ReplySwapFunc)NotImplemented, /* FreeAC */
+ (ReplySwapFunc)NotImplemented, /* SetAuthorization - 10 */
+ (ReplySwapFunc)NotImplemented, /* SetResolution */
+ SGetResolutionReply,
+ SListFontsReply,
+ SListFontsWithXInfoReply,
+ SOpenBitmapFontReply, /* 15 */
+ SQueryXInfoReply,
+ SQueryXExtentsReply,
+ SQueryXExtentsReply,
+ SQueryXBitmapsReply,
+ SQueryXBitmapsReply, /* 20 */
+ (ReplySwapFunc)NotImplemented, /* Close */
+ (ReplySwapFunc)NotImplemented,
+ (ReplySwapFunc)NotImplemented
+};