diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:53 +0000 |
commit | db757f1d2a5a951ec26aa4ed64134d8113089fd0 (patch) | |
tree | ef126a8a6974ad41b7f9a2a46f2c2b3449cdcde7 |
R6.6 is the Xorg base-lineXORG-MAIN
50 files changed, 12771 insertions, 0 deletions
diff --git a/config.cpp b/config.cpp new file mode 100644 index 0000000..73f049f --- /dev/null +++ b/config.cpp @@ -0,0 +1,10 @@ +XCOMM font server configuration file +XCOMM $Xorg: config.cpp,v 1.3 2000/08/17 19:54:19 cpqbld Exp $ + +clone-self = on +use-syslog = off +catalogue = DEFAULTFONTPATH +error-file = FSERRORS +XCOMM in decipoints +default-point-size = 120 +default-resolutions = 75,75,100,100 diff --git a/difs/atom.c b/difs/atom.c new file mode 100644 index 0000000..40ead2b --- /dev/null +++ b/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 + * + */ + +#include "misc.h" +#include "resource.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(string, len, makeit) + char *string; + unsigned 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 (lastAtom < FSA_LAST_PREDEFINED) { + nd->string = string; + } else { + 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; +} + +ValidAtom(atom) + Atom atom; +{ + return (atom != None) && (atom <= lastAtom); +} + +char * +NameForAtom(atom) + Atom atom; +{ + NodePtr node; + + if (atom > lastAtom) + return 0; + if ((node = nodeTable[atom]) == (NodePtr) NULL) + return 0; + return node->string; +} + +static void +atom_error() +{ + FatalError("initializing atoms\n"); +} + +static void +free_atom(patom) + 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() +{ + if (atomRoot == (NodePtr) NULL) + return; + free_atom(atomRoot); + atomRoot = (NodePtr) NULL; + fsfree(nodeTable); + nodeTable = (NodePtr *) NULL; + lastAtom = None; +} + +void +InitAtoms() +{ + 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/difs/cache.c b/difs/cache.c new file mode 100644 index 0000000..e8b6280 --- /dev/null +++ b/difs/cache.c @@ -0,0 +1,388 @@ +/* $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 + * + */ +#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(maxsize) + 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(cid) + 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(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() +{ + 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(cache, needed) + CachePtr cache; + unsigned long needed; +{ +/* XXX -- try to set oldprev properly inside search loop */ + CacheEntryPtr cp, + oldest, + *oldprev; + int oldbucket, + 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; 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(cid, newsize) + Cache cid; +{ + 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(cid, data, size, free_func) + 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(cid, update) + 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; +} + +int +CacheFreeMemory(cid, notify) + 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(cid, data, reason) + CacheID cid; + pointer data; + int reason; +{ + fsfree(data); +} diff --git a/difs/charinfo.c b/difs/charinfo.c new file mode 100644 index 0000000..f664311 --- /dev/null +++ b/difs/charinfo.c @@ -0,0 +1,631 @@ +/* $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. + */ + +#include <X11/Xos.h> +#include "misc.h" +#include "fontstruct.h" +#include "clientstr.h" +#define FSMD_H +#include "FSproto.h" + +extern void TwoByteSwap(); +extern void FourByteSwap(); + +#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)) + +static CharInfoRec junkDefault; + +static int +getCharInfos (pfont, num_ranges, range, ink_metrics, nump, retp) + 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; + int minCol, maxCol; + int num_cols = lastCol - firstCol + 1; + fsRange local_range, *rp; + int i; + FontEncoding encoding; + int err; + unsigned long glyphCount; + unsigned short defaultCh; + CharInfoPtr defaultPtr; + int (*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; + + if (ink_metrics) + metrics_func = 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 (glyphCount != 1 || + *xci == defaultPtr && defaultCh != ((r<<8)+c)) + *xci = &junkDefault; + xci++; + } + } + } + *retp = xchars; + *nump = nchars; + return Successful; +} + +int +GetExtents(client, pfont, flags, num_ranges, range, num_extents, data) + 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 (client, pfont, format, flags, num_ranges, range, tsize, num_glyphs, + offsets, data, freeData) + 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, + gd; + int bitorder, byteorder, scanlinepad, scanlineunit, mappad; + int height, dstbpr, charsize; + int dst_off, src_off; + Bool contiguous, reformat; + long nchars; + int src_glyph_pad = pfont->glyph; + int src_bit_order = pfont->bit; + int src_byte_order = pfont->byte; + int err; + int max_ascent, max_descent; + int min_left, 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(client, pfont, format, flags, num_ranges, range, + size, num_glyphs, offsets, data, freeData) + 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, range); + + if (err != Successful) + return err; + + return packGlyphs (client, pfont, format, flags, + num_ranges, range, size, num_glyphs, + offsets, data, freeData); +} diff --git a/difs/difsutils.c b/difs/difsutils.c new file mode 100644 index 0000000..cbe1b2a --- /dev/null +++ b/difs/difsutils.c @@ -0,0 +1,673 @@ +/* $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. + */ + +#define XK_LATIN1 +#include <stdio.h> +#include <ctype.h> +#include "misc.h" +#include "globals.h" +#include "clientstr.h" +#include "accstr.h" +#include "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() +{ + return currentClient->auth; +} + +void +SetDefaultPointSize(ps) + int ps; +{ + int i; + + default_point_size = ps; + for (i = 0; i < num_resolutions; i++) + default_resolutions[i].point_size = ps; +} + +int +SetDefaultResolutions(str) + 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(num) + 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() +{ + FontResolutionPtr res; + int num; + + res = GetClientResolutions(&num); + if (res) + return res->point_size; + else + return default_point_size; +} + +Bool +XpClientIsBitmapClient(client) + ClientPtr client; +{ + return TRUE; +} + +Bool +XpClientIsPrintClient(client, fpe) + ClientPtr client; + FontPathElementPtr fpe; +{ + return FALSE; +} + +void +CopyISOLatin1Lowered(dest, source, length) + register unsigned char *dest, + *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(first, second, n) + char *first, + *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() +{ +} + +/* host list manipulation */ +int +AddHost(list, addr) + 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(list, addr) + 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(list, addr) + 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 { + void (*BlockHandler) (); + void (*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 */ +BlockHandler(pTimeout, pReadmask) + pointer 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; +} + + +WakeupHandler(result, pReadmask) + int result; /* result from the wait */ + pointer 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(blockHandler, wakeupHandler, blockData) + void (*blockHandler) (); + void (*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(blockHandler, wakeupHandler, blockData) + void (*blockHandler) (); + void (*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; + } +} + +InitBlockAndWakeupHandlers() +{ + 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() +{ + 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(function, client, data) + Bool (*function) (); + 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) (); + pointer closure; +} SleepQueueRec, *SleepQueuePtr; + +static SleepQueuePtr sleepQueue = NULL; + +Bool +ClientSleep(client, function, data) + ClientPtr client; + Bool (*function) (); + 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(client) + 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; +} + +ClientWakeup(client) + 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(client) + ClientPtr client; +{ + SleepQueuePtr q; + + for (q = sleepQueue; q; q = q->next) + if (q->client == client) + return TRUE; + return FALSE; +} + +unsigned long * +Xalloc(m) + unsigned long m; +{ + return fsalloc(m); +} + +unsigned long * +Xrealloc(n, m) + unsigned long *n, + m; +{ + return fsrealloc(n, m); +} + +void +Xfree(n) + unsigned long *n; +{ + fsfree(n); +} + +int +set_font_authorizations(authorizations, authlen, client) +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(client) +ClientPtr client; +{ + return client->auth_generation; +} diff --git a/difs/dispatch.c b/difs/dispatch.c new file mode 100644 index 0000000..ae0a563 --- /dev/null +++ b/difs/dispatch.c @@ -0,0 +1,1109 @@ +/* $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. + */ + +#include "FS.h" +#include "FSproto.h" +#include "clientstr.h" +#include "authstr.h" +#include "misc.h" +#include "osstruct.h" +#include "extentst.h" +#include "globals.h" +#include "resource.h" +#include "difsfnst.h" +#include "fontstruct.h" +#include "site.h" +#include "events.h" +#include "cache.h" + +static void kill_all_clients(); + +char dispatchException = 0; +char isItTimeToYield; + +ClientPtr currentClient; + +static int nClients = 0; +static int nextFreeClientID; + +extern char *ConnectionInfo; +extern int ConnInfoLen; + +extern char *configfilename; + +extern Bool drone_server; + +extern void NotImplemented(); + +extern int (*InitialVector[3]) (); +extern int (*ProcVector[NUM_PROC_VECTORS]) (); +extern int (*SwappedProcVector[NUM_PROC_VECTORS]) (); +extern void (*EventSwapVector[NUM_EVENT_VECTORS]) (); +extern void (*ReplySwapVector[NUM_PROC_VECTORS]) (); + +extern void Swap32Write(), Swap16Write(), CopySwap16Write(); + +#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) + +Dispatch() +{ + 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 + result = (*client->requestVector[op]) (client); + } + 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(); + exit(0); + break; + } + } + } + kill_all_clients(); + dispatchException = 0; +} + +int +ProcInitialConnection(client) + 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'))) { + client->swapped = TRUE; + SwapConnClientPrefix(prefix); + } + 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(client) + ClientPtr client; +{ + fsConnClientPrefix *prefix; + fsConnSetup csp; + int ret; + pointer auth_data, + 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 = (pointer) 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++) { + /* 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; + } + 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 +SendErrToClient(client, error, data) + 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 += 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(client) + ClientPtr client; +{ + SendErrToClient(client, FSBadRequest, NULL); + return FSBadRequest; +} + +int +ProcNoop(client) + ClientPtr client; +{ + REQUEST(fsReq); + REQUEST_AT_LEAST_SIZE(fsReq); + + return client->noClientException; +} + +int +ProcListCatalogues(client) + 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(client) + 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(client) + 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(client) + ClientPtr client; +{ + fsCreateACReply rep; + AuthPtr acp; + AuthContextPtr authp; + int accept, + i, + err, + index, + size; + pointer 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 = (pointer)stuff + SIZEOF(fsCreateACReq); i < (int)stuff->num_auths; i++) { + /* 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; + } + +/* 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 (value, id) + 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(client) + 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(client) + 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(client) + ClientPtr client; +{ + fsResolution *new_res; + + REQUEST(fsSetResolutionReq); + REQUEST_AT_LEAST_SIZE(fsSetResolutionReq); + + 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(client) + ClientPtr client; +{ + fsGetResolutionReply reply; + + REQUEST(fsReq); + REQUEST_AT_LEAST_SIZE(fsReq); + + 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)), client->resolutions); + + return client->noClientException; +} + +int +ProcListFonts(client) + ClientPtr client; +{ + REQUEST(fsListFontsReq); + REQUEST_FIXED_SIZE(fsListFontsReq, stuff->nbytes); + + return ListFonts(client, stuff->nbytes, + (unsigned char *)stuff + SIZEOF(fsListFontsReq), + stuff->maxNames); +} + +int +ProcListFontsWithXInfo(client) + ClientPtr client; +{ + REQUEST(fsListFontsWithXInfoReq); + REQUEST_FIXED_SIZE(fsListFontsWithXInfoReq, stuff->nbytes); + + return StartListFontsWithInfo(client, stuff->nbytes, + (unsigned char *)stuff + SIZEOF(fsListFontsWithXInfoReq), stuff->maxNames); +} + +int +ProcOpenBitmapFont(client) + 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(client) + 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(client) + 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, + (pointer)stuff + SIZEOF(fsQueryXExtents8Req)); + + if (err != FSSuccess) { + return err; + } else + return client->noClientException; +} + +int +ProcQueryXBitmaps(client) + 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, + (pointer)stuff + SIZEOF(fsQueryXBitmaps8Req)); + + if (err != FSSuccess) { + return err; + } else { + return client->noClientException; + } +} + +int +ProcCloseFont(client) + 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 +CloseDownClient(client) + ClientPtr client; +{ + if (client->clientGone != CLIENT_GONE) { + DeleteClientFontStuff(client); + client->clientGone = CLIENT_GONE; + CloseDownConnection(client); + --nClients; + } + + if (ClientIsAsleep(client)) + ClientSignal(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() +{ + int i; + + for (i = MINCLIENT; i < currentMaxClients; i++) { + if (clients[i]) + CloseDownClient(clients[i]); + } +} + +void +InitProcVectors() +{ + int i; + + for (i = 0; i < NUM_PROC_VECTORS; i++) { + if (!ProcVector[i]) { + ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; + ReplySwapVector[i] = NotImplemented; + } + } + for (i = FSLASTEvent; i < NUM_EVENT_VECTORS; i++) { + EventSwapVector[i] = NotImplemented; + } +} + +InitClient(client, i, ospriv) + 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(ospriv) + pointer ospriv; +{ + int i; + ClientPtr client; + fsFakeReq data; + extern long MaxClients; + + 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; +} + +MarkClientException(client) + ClientPtr client; +{ + client->noClientException = -2; +} diff --git a/difs/events.c b/difs/events.c new file mode 100644 index 0000000..cd75ad4 --- /dev/null +++ b/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. + */ + +#include "clientstr.h" +#include "FSproto.h" +#include "globals.h" +#include "events.h" + +extern void (*EventSwapVector[NUM_EVENT_VECTORS]) (); + +static Mask lastEventMask = FontChangeNotifyMask; + +#define AllEventMasks (lastEventMask | (lastEventMask - 1)) + +void +WriteErrorToClient(client, error) + 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(client) + 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(client) + 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; + + return client->noClientException; +} + +void +SendKeepAliveEvent(client) + 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/difs/extensions.c b/difs/extensions.c new file mode 100644 index 0000000..5c1f8b0 --- /dev/null +++ b/difs/extensions.c @@ -0,0 +1,306 @@ +/* $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. + */ + +#include "FSproto.h" +#include "misc.h" +#include "clientstr.h" +#include "extentst.h" + +#define EXTENSION_BASE 128 +#define EXTENSION_EVENT_BASE 64 +#define LAST_EVENT 128 +#define LAST_ERROR 255 + +static ExtensionEntry **extensions = (ExtensionEntry **) NULL; +extern int (*ProcVector[]) (); +extern int (*SwappedProcVector[]) (); +extern void (*ReplySwapVector[]) (); + +int lastEvent = EXTENSION_EVENT_BASE; +static int lastError = FirstExtensionError; +static int NumExtensions = 0; + + +ExtensionEntry * +AddExtension(name, num_events, num_errors, main_proc, smain_proc, + closedown_proc, minorop_proc) + char *name; + int num_events; + int num_errors; + int (*main_proc) (); + int (*smain_proc) (); + void (*closedown_proc) (); + unsigned short (*minorop_proc) (); +{ + 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(alias, ext) + 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(client) + ClientPtr client; +{ + return ((fsReq *) client->requestBuffer)->data; +} + +unsigned short +MinorOpcodeOfRequest(client) + 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); +} + +CloseDownExtensions() +{ + 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() +{ +} + +int +ProcQueryExtension(client) + 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(client) + 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/difs/fontinfo.c b/difs/fontinfo.c new file mode 100644 index 0000000..50ee743 --- /dev/null +++ b/difs/fontinfo.c @@ -0,0 +1,435 @@ +/* $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. + */ + +#include "FS.h" +#include "FSproto.h" +#include <stdio.h> +#include <X11/Xos.h> +#include "clientstr.h" +#include "difsfnst.h" +#include "fontstruct.h" +#include "closestr.h" +#include "globals.h" + +extern void (*ReplySwapVector[NUM_PROC_VECTORS]) (); + +void +CopyCharInfo(ci, dst) + 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(pinfo, 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 (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 = 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 = 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( string_base+cur_off, str, local_offset.name.length); + cur_off += local_offset.name.length; + if (pinfo->isStringProp[i]) + { + local_offset.value.position = cur_off; + str = NameForAtom(pinfo->props[i].value); + local_offset.value.length = strlen(str); + memmove( 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 += 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(type, src, item_size, num, all, pfi) + Bool type; + pointer src; + int item_size; + int *num; + Bool *all; + FontInfoPtr pfi; +{ + fsRange *new = (fsRange *) 0, + *np; + unsigned long src_num; + int 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 */ + pointer 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 (values, number) + 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; + } +} + + +static Bool +do_query_extents(client, c) + ClientPtr client; + QEclosurePtr c; +{ + int err; + unsigned long lendata, + num_extents; + fsXCharInfo *extents; + fsQueryXExtents8Reply reply; + + err = GetExtents (c->client, c->pfont, + c->flags, c->nranges, c->range, &num_extents, &extents); + if (err == Suspended) { + if (!c->slept) { + c->pfont->unload_glyphs = 0; /* Not a safe call for this font */ + c->slept = TRUE; + ClientSleep(client, do_query_extents, (pointer) c); + } + return TRUE; + } + if (err != Successful) { + SendErrToClient(c->client, FontToFSError(err), (pointer) 0); + goto finish; + } + reply.type = FS_Reply; + reply.sequenceNumber = c->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(c->client, SIZEOF(fsQueryXExtents8Reply), &reply); + (void) WriteToClient(c->client, lendata, (char *) extents); + fsfree((char *) extents); +finish: + if (c->slept) + ClientWakeup(c->client); + if (c->pfont->unload_glyphs) /* For rasterizers that want to save memory */ + (*c->pfont->unload_glyphs)(c->pfont); + fsfree(c->range); + fsfree(c); + return TRUE; +} + +int +QueryExtents(client, cfp, item_size, nranges, range_flag, range_data) + 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 (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, c); + return FSSuccess; +} + +static Bool +do_query_bitmaps(client, c) + ClientPtr client; + QBclosurePtr c; +{ + int err; + unsigned long num_glyphs, data_size; + fsOffset32 *offsets; + pointer glyph_data; + fsQueryXBitmaps8Reply reply; + int freedata; + + err = GetBitmaps (c->client, c->pfont, c->format, + c->flags, c->nranges, c->range, + &data_size, &num_glyphs, &offsets, &glyph_data, &freedata); + + if (err == Suspended) { + if (!c->slept) { + c->pfont->unload_glyphs = 0; /* Not a safe call for this font */ + c->slept = TRUE; + ClientSleep(client, do_query_bitmaps, (pointer) c); + } + return TRUE; + } + if (err != Successful) { + SendErrToClient(c->client, FontToFSError(err), (pointer) 0); + goto finish; + } + reply.type = FS_Reply; + reply.sequenceNumber = c->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(c->client, SIZEOF(fsQueryXBitmaps8Reply), &reply); + if (client->swapped) + SwapLongs((long *)offsets, num_glyphs * 2); + (void) WriteToClient(c->client, (num_glyphs * SIZEOF(fsOffset32)), + (char *) offsets); + (void) WriteToClient(c->client, data_size, (char *) glyph_data); + fsfree((char *) offsets); + if (freedata) + fsfree((char *) glyph_data); +finish: + if (c->slept) + ClientWakeup(c->client); + if (c->pfont->unload_glyphs) /* For rasterizers that want to save memory */ + (*c->pfont->unload_glyphs)(c->pfont); + fsfree(c->range); + fsfree(c); + return TRUE; +} + +int +QueryBitmaps(client, cfp, item_size, format, nranges, range_flag, range_data) + 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 (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, c); + return FSSuccess; +} diff --git a/difs/fonts.c b/difs/fonts.c new file mode 100644 index 0000000..a3f6a9f --- /dev/null +++ b/difs/fonts.c @@ -0,0 +1,1552 @@ +/* $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. + */ + +#include "FS.h" +#include "FSproto.h" +#include <stdio.h> +#include <X11/Xos.h> +#include "clientstr.h" +#include "resource.h" +#include "difsfnst.h" +#include "fontstruct.h" +#include "closestr.h" +#include "globals.h" + +extern void (*ReplySwapVector[NUM_PROC_VECTORS]) (); +extern FSID FakeClientID(); + +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(err) + 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(fpe) + FontPathElementPtr fpe; +{ + fpe->refcount++; +} + +void +FreeFPE(fpe) + 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(fpe) + 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(fpe) + 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(data, count, LastSelectMask) + 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(ids, fid) + 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(ids, fid) + 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() +{ + 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(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); + } +} + +static Bool +do_open_font(client, c) + ClientPtr client; + OFclosurePtr c; +{ + FontPtr pfont = NullFont; + FontPathElementPtr fpe; + int err; + 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 (c->current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current_fpe]; + (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); + } + err = Successful; + goto dropout; + } + while (c->current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current_fpe]; + err = (*fpe_functions[fpe->type].open_font) + ((pointer) c->client, fpe, c->flags, + c->fontname, c->fnamelen, c->format, c->format_mask, + c->fontid, &pfont, &alias, + c->non_cachable_font && c->non_cachable_font->fpe == fpe ? + c->non_cachable_font : + (FontPtr)0); + + if (err == FontNameAlias && alias) { + newlen = strlen(alias); + newname = (char *) fsrealloc(c->fontname, newlen); + if (!newname) { + err = AllocError; + break; + } + memmove( newname, alias, newlen); + c->fontname = newname; + c->fnamelen = newlen; + c->current_fpe = 0; + if (--aliascount <= 0) break; + continue; + } + if (err == BadFontName) { + c->current_fpe++; + continue; + } + if (err == Suspended) { + if (!c->slept) { + c->slept = TRUE; + ClientSleep(client, do_open_font, (pointer) c); + } + 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 = c->client->index; + + if (fontPatternCache && pfont != c->non_cachable_font) + CacheFontPattern(fontPatternCache, c->orig_name, c->orig_len, pfont); + + /* either pull out the other id or make the array */ + if (pfont->refcnt != 0) { + idlist = (FontIDListPtr *) pfont->svrPrivate; + ids = idlist[c->client->index]; + if (!ids) { + ids = make_clients_id_list(); + if (!ids) { + err = AllocError; + fsfree(cfp); + goto dropout; + } + idlist[c->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[c->client->index] = ids; + orig = (Font) 0; + pfont->svrPrivate = (pointer) idlist; + } + if (!AddResource(c->client->index, c->fontid, RT_FONT, (pointer) cfp)) { + fsfree(cfp); + free_svrPrivate(pfont->svrPrivate); + pfont->svrPrivate = (pointer) 0; + err = AllocError; + goto dropout; + } + add_id_to_list(ids, c->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(c->client, FontToFSError(err), (pointer) &(c->fontid)); + } + if (c->slept) + ClientWakeup(c->client); + for (i = 0; i < c->num_fpes; i++) { + FreeFPE(c->fpe_list[i]); + } + fsfree(c->fpe_list); + fsfree(c->fontname); + fsfree(c); + return TRUE; +} + +int +OpenFont(client, fid, format, format_mask, namelen, name) + 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; + } + /* + ** 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, c); + return FSSuccess; +} + +static int +close_font(pfont) + 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(cfp, fid) + 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 knwon FPE prefixes looking for one to match the given + * FPE name + */ +static int +determine_fpe_type(name) + 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(list, n) + FontPathElementPtr *list; + int n; +{ + int i; + + for (i = 0; i < n; i++) { + FreeFPE(list[i]); + } + fsfree((char *) list); +} + +static FontPathElementPtr +find_existing_fpe(list, num, name, len) + 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(npaths, paths, bad) + int npaths; + char *paths; + int *bad; +{ + int i, + err; + int len; + int type; + char *cp = paths; + 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; i < npaths; i++) { + len = *cp++; + if (len) { + char *name; + /* 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[i] = 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) + { + fsfree(name); + err = FSBadName; + goto bail; + } + /* 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; + fplist[i] = fpe; + + cp += len; + fpe->name_length = len; + err = (*fpe_functions[fpe->type].init_fpe) (fpe); + if (err != Successful) { + fsfree(fpe->name); + fsfree(fpe); + 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 = i; + while (--i >= 0) + FreeFPE(fplist[i]); + fsfree(fplist); + return err; +} + +/* + * expects comma seperated string + */ +int +SetFontCatalogue(str, badpath) + 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; +} + +Bool +do_list_fonts_and_aliases(client, c) + ClientPtr client; + LFclosurePtr c; +{ + 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 (c->current.current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current.current_fpe]; + (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); + } + err = Successful; + goto bail; + } + + if (!c->current.patlen) + goto finish; + + while (c->current.current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current.current_fpe]; + err = Successful; + + if (!fpe_functions[fpe->type].start_list_fonts_and_aliases) + { + /* This FPE doesn't support/require list_fonts_and_aliases */ + + err = (*fpe_functions[fpe->type].list_fonts) + ((pointer) c->client, fpe, c->current.pattern, + c->current.patlen, c->current.max_names - c->names->nnames, + c->names); + + if (err == Suspended) { + if (!c->slept) { + c->slept = TRUE; + ClientSleep(client, do_list_fonts_and_aliases, (pointer) c); + } + return TRUE; + } + + err = BadFontName; + } + else + { + /* Start of list_fonts_and_aliases functionality. Modeled + after list_fonts_with_info in that it resolves aliases, + except that the information collected from FPEs is just + names, not font info. Each list_next_font_or_alias() + returns either a name into name/namelen or an alias into + name/namelen and its target name into resolved/resolvedlen. + The code at this level then resolves the alias by polling + the FPEs. */ + + if (!c->current.list_started) { + err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases) + ((pointer) c->client, fpe, c->current.pattern, + c->current.patlen, c->current.max_names - c->names->nnames, + &c->current.private); + if (err == Suspended) { + if (!c->slept) { + ClientSleep(client, do_list_fonts_and_aliases, + (pointer) c); + c->slept = TRUE; + } + return TRUE; + } + if (err == Successful) + c->current.list_started = TRUE; + } + if (err == Successful) { + name = 0; + err = (*fpe_functions[fpe->type].list_next_font_or_alias) + ((pointer) c->client, fpe, &name, &namelen, &resolved, + &resolvedlen, c->current.private); + if (err == Suspended) { + if (!c->slept) { + ClientSleep(client, do_list_fonts_and_aliases, + (pointer) c); + c->slept = TRUE; + } + return TRUE; + } + } + + if (err == Successful) + { + if (c->haveSaved) + { + if (c->savedName) + (void)AddFontNamesName(c->names, c->savedName, + c->savedNameLen); + } + else + (void)AddFontNamesName(c->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 (c->haveSaved) + { + char *tmpname; + int tmpnamelen; + + tmpname = 0; + (void) (*fpe_functions[fpe->type].list_next_font_or_alias) + ((pointer) c->client, fpe, &tmpname, &tmpnamelen, + &tmpname, &tmpnamelen, c->current.private); + if (--aliascount <= 0) + { + err = BadFontName; + goto ContBadFontName; + } + } + else + { + c->saved = c->current; + c->haveSaved = TRUE; + if (c->savedName) + fsfree(c->savedName); + c->savedName = (char *)fsalloc(namelen + 1); + if (c->savedName) + memmove(c->savedName, name, namelen + 1); + c->savedNameLen = namelen; + aliascount = 20; + } + memmove(c->current.pattern, tmp_pattern, resolvedlen); + c->current.patlen = resolvedlen; + c->current.max_names = c->names->nnames + 1; + c->current.current_fpe = -1; + c->current.private = 0; + err = BadFontName; + } + } + /* + * At the end of this FPE, step to the next. If we've finished + * processing an alias, pop state back. If we've collected enough + * font names, quit. + */ + if (err == BadFontName) { + ContBadFontName: ; + c->current.list_started = FALSE; + c->current.current_fpe++; + err = Successful; + if (c->haveSaved) + { + /* If 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 (c->current.current_fpe < c->num_fpes && + c->fpe_list[c->current.current_fpe]->type != + c->fpe_list[c->saved.current_fpe]->type) + c->current.current_fpe++; + + if (c->names->nnames == c->current.max_names || + c->current.current_fpe == c->num_fpes) { + c->haveSaved = FALSE; + c->current = c->saved; + /* Give the saved namelist a chance to clean itself up */ + continue; + } + } + if (c->names->nnames == c->current.max_names) + break; + } + } + + /* + * send the reply + */ + if (err != Successful) { + SendErrToClient(client, FontToFSError(err), (pointer) 0); + goto bail; + } + +finish: + + names = c->names; + nnames = names->nnames; + client = c->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 (c->slept) + ClientWakeup(client); + for (i = 0; i < c->num_fpes; i++) + FreeFPE(c->fpe_list[i]); + fsfree(c->fpe_list); + if (c->savedName) fsfree(c->savedName); + FreeFontNames(names); + fsfree(c); + return TRUE; +} + +int +ListFonts(client, length, pattern, maxNames) + 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, c); + return TRUE; +badAlloc: + SendErrToClient(client, FSBadAlloc, (pointer) 0); + return TRUE; +} + +static int padlength[4] = {0, 3, 2, 1}; +static char padding[3]; + +Bool +do_list_fonts_with_info(client, c) + ClientPtr client; + LFWXIclosurePtr c; +{ + 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 (c->current.current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current.current_fpe]; + (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); + } + err = Successful; + goto bail; + } + while (c->current.current_fpe < c->num_fpes) { + fpe = c->fpe_list[c->current.current_fpe]; + err = Successful; + if (!c->current.list_started) { + err = (*fpe_functions[fpe->type].start_list_fonts_with_info) + ((pointer) c->client, fpe, c->current.pattern, + c->current.patlen, c->current.max_names, + &c->current.private); + if (err == Suspended) { + if (!c->slept) { + ClientSleep(client, do_list_fonts_with_info, + (pointer) c); + c->slept = TRUE; + } + return TRUE; + } + if (err == Successful) + c->current.list_started = TRUE; + } + if (err == Successful) { + name = 0; + pFontInfo = &fontInfo; + err = (*fpe_functions[fpe->type].list_next_font_with_info) + ((pointer) c->client, fpe, &name, &namelen, + &pFontInfo, &numFonts, c->current.private); + if (err == Suspended) { + if (!c->slept) { + ClientSleep(client, do_list_fonts_with_info, + (pointer) c); + c->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 (c->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, c->current.private); + if (--aliascount <= 0) + { + err = BadFontName; + goto ContBadFontName; + } + } + else + { + c->saved = c->current; + c->haveSaved = TRUE; + c->savedNumFonts = numFonts; + c->savedName = (char *) pFontInfo; + aliascount = 20; + } + memmove(c->current.pattern, name, namelen); + c->current.patlen = namelen; + c->current.max_names = 1; + c->current.current_fpe = 0; + c->current.private = 0; + c->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: ; + c->current.list_started = FALSE; + c->current.current_fpe++; + err = Successful; + if (c->haveSaved) { + if (c->current.max_names == 0 || + c->current.current_fpe == c->num_fpes) { + c->haveSaved = FALSE; + c->saved.max_names -= (1 - c->current.max_names); + c->current = c->saved; + } + } + else if (c->current.max_names == 0) + break; + } else if (err == Successful) { +/* XXX why is it xFontProp ? */ + length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp); + reply = c->reply; + if (c->length < length) { + reply = (fsListFontsWithXInfoReply *) fsrealloc(c->reply, length); + if (!reply) { + err = AllocError; + break; + } + c->reply = reply; + c->length = length; + } + if (c->haveSaved) { + numFonts = c->savedNumFonts; + name = c->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); + + --c->current.max_names; + if (c->current.max_names < 0) + abort(); + } + } + + /* + * send the final reply + */ + if (err == Successful) { + fsGenericReply *final_reply; + + final_reply = (fsGenericReply *)c->reply; + if (client->major_version > 1) + length = SIZEOF(fsGenericReply); + else + length = SIZEOF(fsListFontsWithXInfoReply); + if (c->length < length) { + final_reply = (fsGenericReply *) fsrealloc(c->reply, length); + if (final_reply) { + c->reply = (fsListFontsWithXInfoReply *)final_reply; + c->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 (c->slept) + ClientWakeup(client); + for (i = 0; i < c->num_fpes; i++) + FreeFPE(c->fpe_list[i]); + fsfree(c->fpe_list); + fsfree(c->reply); + fsfree(c); + return TRUE; +} + +int +StartListFontsWithInfo(client, length, pattern, maxNames) + 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; + do_list_fonts_with_info(client, c); + return TRUE; +badAlloc: + SendErrToClient(client, FSBadAlloc, (pointer) 0); + return TRUE; +} + +int +LoadGlyphRanges(client, pfont, range_flag, num_ranges, item_size, data) + 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(name_func, init_func, free_func, reset_func, + open_func, close_func, list_func, start_lfwi_func, next_lfwi_func, + wakeup_func, client_died, load_glyphs, + start_list_alias_func, next_list_alias_func, + set_path_func) + Bool (*name_func) (); + int (*init_func) (); + int (*free_func) (); + int (*reset_func) (); + int (*open_func) (); + int (*close_func) (); + int (*list_func) (); + int (*start_lfwi_func) (); + int (*next_lfwi_func) (); + int (*wakeup_func) (); + int (*client_died) (); + int (*load_glyphs) (); + int (*start_list_alias_func) (); + int (*next_list_alias_func) (); + void (*set_path_func) (); +{ + 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() +{ +} + +/* convenience functions for FS interface */ + +FontPtr +find_old_font(id) + FSID id; +{ + return (FontPtr) LookupIDByType(SERVER_CLIENT, id, RT_NONE); +} + +Font +GetNewFontClientID() +{ + return (Font) FakeClientID(SERVER_CLIENT); +} + +int +StoreFontClientFont(pfont, id) + FontPtr pfont; + Font id; +{ + return AddResource(SERVER_CLIENT, id, RT_NONE, (pointer) pfont); +} + +void +DeleteFontClientID(id) + Font id; +{ + FreeResource(SERVER_CLIENT, id, RT_NONE); +} + +static int fs_handlers_installed = 0; +static unsigned int last_server_gen; + +int +init_fs_handlers(fpe, block_handler) + FontPathElementPtr fpe; + void (*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(fpe, block_handler, all) + FontPathElementPtr fpe; + void (*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(client) + 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/difs/globals.c b/difs/globals.c new file mode 100644 index 0000000..aac2517 --- /dev/null +++ b/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 "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/difs/initfonts.c b/difs/initfonts.c new file mode 100644 index 0000000..ea6c95a --- /dev/null +++ b/difs/initfonts.c @@ -0,0 +1,80 @@ +/* $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% + * + */ + +#include "font.h" + +FontPatternCachePtr fontPatternCache; + +void +InitFonts() +{ + if (fontPatternCache) + FreeFontPatternCache(fontPatternCache); + fontPatternCache = MakeFontPatternCache(); + + ResetFontPrivateIndex(); + +#ifdef FONT_PCF + FontFileRegisterFpeFunctions(); +#ifdef LOWMEMFTPT + +#ifndef CRAY + SpeedoRegisterFontFileFunctions (); + Type1RegisterFontFileFunctions(); +#endif + +#endif /* ifdef LOWMEMFTPT */ + +#endif + +#ifdef FONT_FS + fs_register_fpe_functions(); +#endif +} diff --git a/difs/main.c b/difs/main.c new file mode 100644 index 0000000..dc43512 --- /dev/null +++ b/difs/main.c @@ -0,0 +1,200 @@ +/* $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. + */ + +#include "FS.h" +#include "FSproto.h" +#include "clientstr.h" +#include "resource.h" +#include "misc.h" +#include "globals.h" +#include "servermd.h" +#include "cache.h" +#include "site.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 */ + +extern void InitProcVectors(); +extern void InitFonts(); +extern void InitAtoms(); +extern void InitExtensions(); +extern void ProcessCmdLine(); +static Bool create_connection_block(); + +extern ClientPtr currentClient; +char *configfilename; +extern Bool drone_server; + +extern OldListenRec *OldListen; +extern int OldListenCount; + + +main(argc, argv) + int argc; + char **argv; +{ + int i; + + argcGlobal = argc; + argvGlobal = argv; + + configfilename = DEFAULT_CONFIG_FILE; + + /* init stuff */ + ProcessCmdLine(argc, argv); + InitErrors(); + /* + * do this first thing, to get any options that only take effect at + * startup time. it is erad again each time the server resets + */ + if (ReadConfigFile(configfilename) != FSSuccess) { + ErrorF("fatal: couldn't read config file\n"); + exit(1); + } + + 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); +} + +void +NotImplemented() +{ + NoopDDA(); /* dummy to get difsutils.o to link */ + FatalError("Not implemented\n"); +} + +static Bool +create_connection_block() +{ + 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/difs/resource.c b/difs/resource.c new file mode 100644 index 0000000..037b97f --- /dev/null +++ b/difs/resource.c @@ -0,0 +1,569 @@ +/* $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% + * + */ +/* + * 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 "FS.h" +#include "misc.h" +#include "os.h" +#include "resource.h" +#include "clientstr.h" +#include "globals.h" + +static void rebuild_table(); + +#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; +static RESTYPE lastResourceClass; +static RESTYPE TypeMask; + +typedef int (*DeleteType) (); + +static DeleteType *DeleteFuncs = (DeleteType *) NULL; + +#ifdef NOTYET +RESTYPE +CreateNewResourceType(deleteFunc) + 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() +{ + 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 () +{ +} + +Bool +InitClientResources(client) + ClientPtr client; +{ + register int i, + j; + + if (client == serverClient) { + extern int CloseClientFont(); + extern int DeleteAuthCont (); + + lastResourceType = RT_LASTPREDEF; + lastResourceClass = RC_LASTPREDEF; + 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] = CloseClientFont; + DeleteFuncs[RT_AUTHCONT & TypeMask] = 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(client, id) + int client; + register 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(client, id, maxid, goodid) + register int client; + register FSID id, maxid, 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(client) + 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(cid, id, type, value) + 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(client) + 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(cid, id, skipDeleteFuncType) + 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(cid, id, type, skipFree) + 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(cid, id, rtype, value) + 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(client) + 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; +} + +FreeAllResources() +{ + 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(cid, id, rtype) + 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(id, classes) + 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/difs/swaprep.c b/difs/swaprep.c new file mode 100644 index 0000000..b5ed328 --- /dev/null +++ b/difs/swaprep.c @@ -0,0 +1,472 @@ +/* $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. + */ + +#include "FSproto.h" +#include "clientstr.h" +#include "misc.h" + +static void SwapConnSetupAccept(); + +void +Swap32Write(client, size, pbuf) + 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(client, size, pbuf) + 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); +} + +CopySwap32Write(client, size, pbuf) + 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(client, size, pbuf) + 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); +} + +void +SGenericReply(client, size, pRep) + ClientPtr client; + int size; + fsGenericReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SListExtensionsReply(client, size, pRep) + ClientPtr client; + int size; + fsListExtensionsReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SQueryExtensionReply(client, size, pRep) + ClientPtr client; + int size; + fsQueryExtensionReply *pRep; +{ + 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); +} + +void +SListCataloguesReply(client, size, pRep) + ClientPtr client; + int size; + fsListCataloguesReply *pRep; +{ + 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); +} + +void +SCreateACReply(client, size, pRep) + ClientPtr client; + int size; + fsCreateACReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + pRep->status = lswaps(pRep->status); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SGetEventMaskReply(client, size, pRep) + ClientPtr client; + int size; + fsGetEventMaskReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + pRep->event_mask = lswapl(pRep->event_mask); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SGetResolutionReply(client, size, pRep) + ClientPtr client; + int size; + fsGetResolutionReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SListFontsReply(client, size, pRep) + ClientPtr client; + int size; + fsListFontsReply *pRep; +{ + 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) + +void +SListFontsWithXInfoReply(client, size, pRep) + ClientPtr client; + int size; + fsListFontsWithXInfoReply *pRep; +{ + 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); +} + +void +SOpenBitmapFontReply(client, size, pRep) + ClientPtr client; + int size; + fsOpenBitmapFontReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + pRep->otherid = lswapl(pRep->otherid); + + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SQueryXInfoReply(client, size, pRep) + ClientPtr client; + int size; + fsQueryXInfoReply *pRep; +{ + pRep->sequenceNumber = lswaps(pRep->sequenceNumber); + pRep->length = lswapl(pRep->length); + SwapXFontInfoHeader(pRep); + (void) WriteToClient(client, size, (char *) pRep); +} + +void +SQueryXExtentsReply(client, size, pRep) + ClientPtr client; + int size; + fsQueryXExtents8Reply *pRep; /* 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); +} + +void +SQueryXBitmapsReply(client, size, pRep) + ClientPtr client; + int size; + fsQueryXBitmaps8Reply *pRep; /* 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(error, perror) + fsError *error, + *perror; +{ + *perror = *error; + perror->sequenceNumber = lswaps(perror->sequenceNumber); + perror->length = lswapl(perror->length); + perror->timestamp = lswapl(perror->timestamp); +} + +void +WriteSConnectionInfo(client, size, pInfo) + 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(pConnSetup, pConnSetupT) + fsConnSetupAccept *pConnSetup, + *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(client, pcsp) + 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(po) + char *po; +{ + int i, n; + + for (i=0; i<4; i++) + { + swapl(po, n); + po += 4; + } +} + +void +SwapPropInfo(pi) + 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(extents, num) + fsXCharInfo *extents; + int num; +{ + SwapShorts((short *)extents, num * (SIZEOF(fsXCharInfo) / 2)); +} diff --git a/difs/swapreq.c b/difs/swapreq.c new file mode 100644 index 0000000..9767bec --- /dev/null +++ b/difs/swapreq.c @@ -0,0 +1,286 @@ +/* $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. + */ + +#include "misc.h" +#include "FSproto.h" +#include "clientstr.h" +#include "globals.h" + +extern int (*ProcVector[NUM_PROC_VECTORS]) (); + +void +SwapLongs(list, count) + 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(list, count) + short *list; + register 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(client) + 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(client) + ClientPtr client; +{ + REQUEST(fsResourceReq); + stuff->length = lswaps(stuff->length); + stuff->id = lswapl(stuff->id); + return ((*ProcVector[stuff->reqType]) (client)); +} + +static void +swap_auth(data, num) + pointer data; + int num; +{ + pointer p; + unsigned char t; + CARD16 namelen, + datalen; + int i; + + p = data; + for (i = 0; i < num; i++) { + 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; + } +} + +int +SProcCreateAC(client) + ClientPtr client; +{ + REQUEST(fsCreateACReq); + stuff->length = lswaps(stuff->length); + stuff->acid = lswapl(stuff->acid); + swap_auth((pointer) &stuff[1], stuff->num_auths); + return ((*ProcVector[stuff->reqType]) (client)); +} + +int +SProcSetResolution(client) + ClientPtr client; +{ + REQUEST(fsSetResolutionReq); + stuff->length = lswaps(stuff->length); + stuff->num_resolutions = lswaps(stuff->num_resolutions); + SwapShorts((short *) &stuff[1], stuff->num_resolutions); + + return ((*ProcVector[stuff->reqType]) (client)); +} + + +int +SProcQueryExtension(client) + ClientPtr client; +{ + REQUEST(fsQueryExtensionReq); + stuff->length = lswaps(stuff->length); + return ((*ProcVector[FS_QueryExtension]) (client)); +} + +int +SProcListCatalogues(client) + 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(client) + 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(client) + 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(client) + 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(client) + 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(client) + 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)); +} + +SwapConnClientPrefix(pCCP) + fsConnClientPrefix *pCCP; +{ + pCCP->major_version = lswaps(pCCP->major_version); + pCCP->minor_version = lswaps(pCCP->minor_version); + pCCP->auth_len = lswaps(pCCP->auth_len); + swap_auth((pointer) &pCCP[1], pCCP->num_auths); +} diff --git a/difs/tables.c b/difs/tables.c new file mode 100644 index 0000000..29ba6b7 --- /dev/null +++ b/difs/tables.c @@ -0,0 +1,190 @@ +/* $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. + */ + +#include "globals.h" + +extern int ProcInitialConnection(), ProcEstablishConnection(); + +extern int ProcSetAuthorization(), + ProcSetResolution(), ProcGetResolution(), ProcNoop(), + ProcListExtensions(), ProcQueryExtension(), + ProcListFonts(), ProcListFontsWithXInfo(), + ProcOpenBitmapFont(), ProcQueryXInfo(), ProcQueryXExtents(), + ProcQueryXBitmaps(), ProcCloseFont(), + ProcListCatalogues(), ProcSetCatalogues(), ProcGetCatalogues(), + ProcSetEventMask(), ProcGetEventMask(), + ProcCreateAC(), ProcFreeAC(); + +extern int SProcSimpleRequest(), SProcResourceRequest(), + SProcListCatalogues(), + SProcSetResolution(), + SProcQueryExtension(), + SProcListFonts(), SProcListFontsWithXInfo(), + SProcOpenBitmapFont(), SProcQueryXExtents(), + SProcQueryXBitmaps(), + SProcCreateAC(); + +extern void SErrorEvent(); + +extern void NotImplemented(), SGenericReply(), + SListExtensionsReply(), + SListCataloguesReply(), + SQueryExtensionReply(), + SListFontsReply(), SListFontsWithXInfoReply(), + SOpenBitmapFontReply(), + SQueryXInfoReply(), SQueryXExtentsReply(), + SQueryXBitmapsReply(), + SGetEventMaskReply(), SCreateACReply(), SGetResolutionReply(), + SOpenBitmapFontReply(); + + +int (*InitialVector[3]) () = +{ + 0, + ProcInitialConnection, + ProcEstablishConnection +}; + +int (*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 +}; + +int (*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 +}; + +void (*EventSwapVector[NUM_EVENT_VECTORS]) () = +{ + SErrorEvent, + NotImplemented, + 0, + 0, + 0, + 0, + 0, + 0 +}; + +void (*ReplySwapVector[NUM_PROC_VECTORS]) () = +{ + NotImplemented, /* NoOp */ + SListExtensionsReply, + SQueryExtensionReply, /* SQueryExtensionReply */ + SListCataloguesReply, + NotImplemented, /* SetCatalogues */ + SGenericReply, /* GetCatalogues */ + NotImplemented, /* SetEventMask */ + SGetEventMaskReply, + SCreateACReply, + NotImplemented, /* FreeAC */ + NotImplemented, /* SetAuthorization - 10 */ + NotImplemented, /* SetResolution */ + SGetResolutionReply, + SListFontsReply, + SListFontsWithXInfoReply, + SOpenBitmapFontReply, /* 15 */ + SQueryXInfoReply, + SQueryXExtentsReply, + SQueryXExtentsReply, + SQueryXBitmapsReply, + SQueryXBitmapsReply, /* 20 */ + NotImplemented, /* Close */ + NotImplemented, + NotImplemented +}; diff --git a/include/access.h b/include/access.h new file mode 100644 index 0000000..21957c3 --- /dev/null +++ b/include/access.h @@ -0,0 +1,66 @@ +/* $Xorg: access.h,v 1.4 2001/02/09 02:05:43 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, DIGITAL OR MIT 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. + * + * @(#)access.h 4.1 91/05/02 + * + */ + +#ifndef _ACCESS_H_ +#define _ACCESS_H_ + +typedef struct _hostaddress *HostList; + +#define HOST_AF_INET 1 +#define HOST_AF_DECnet 2 + +extern int AddHost(); +extern int RemoveHost(); +extern int ValidHost(); +extern int GetHostAddress(); +extern int CheckClientAuthorization(); +extern void AccessSetConnectionLimit(); + +#endif /* _ACCESS_H_ */ diff --git a/include/accstr.h b/include/accstr.h new file mode 100644 index 0000000..55ce4f3 --- /dev/null +++ b/include/accstr.h @@ -0,0 +1,64 @@ +/* $Xorg: accstr.h,v 1.4 2001/02/09 02:05:43 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, DIGITAL OR MIT 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. + * + * @(#)accstr.h 4.1 91/05/02 + * + */ + +#ifndef _ACCSTR_H_ +#define _ACCSTR_H_ +#include "misc.h" +#include "access.h" + +typedef struct _hostaddress { + int type; + pointer address; + int addr_len; + struct _hostaddress *next; +} HostAddress; + +#endif /* _ACCSTR_H_ */ diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..aa95a69 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,59 @@ +/* $Xorg: assert.h,v 1.4 2001/02/09 02:05:43 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, DIGITAL OR MIT 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. + * + * @(#)assert.h 4.1 91/05/02 + * + */ +#ifdef DEBUG +#include <stdio.h> +#ifdef SABER +#define assert(ex) {if (!(ex)){(void)fprintf(stderr,"Assertion \"ex\" failed: file \"%s\", line %d\n", __FILE__, __LINE__);saber_stop();}} +#else +#define assert(ex) {if (!(ex)){(void)fprintf(stderr,"Assertion \"ex\" failed: file \"%s\", line %d\n", __FILE__, __LINE__);abort();}} +#endif +#else +#define assert(ex) +#endif diff --git a/include/auth.h b/include/auth.h new file mode 100644 index 0000000..79fbbfb --- /dev/null +++ b/include/auth.h @@ -0,0 +1,58 @@ +/* $Xorg: auth.h,v 1.4 2001/02/09 02:05:43 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. + * + * @(#)auth.h 4.1 91/05/02 + * + */ + +#ifndef _AUTH_H_ +#define _AUTH_H_ + +typedef struct _authcontext *AuthContextPtr; + +extern AuthContextPtr GetClientAuthorization(); + +#endif /* _AUTH_H_ */ diff --git a/include/authstr.h b/include/authstr.h new file mode 100644 index 0000000..de01f42 --- /dev/null +++ b/include/authstr.h @@ -0,0 +1,61 @@ +/* $Xorg: authstr.h,v 1.4 2001/02/09 02:05:43 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. + * + * @(#)authstr.h 4.1 91/05/02 + * + */ + +#ifndef _AUTHSTR_H_ +#define _AUTHSTR_H_ +#include "auth.h" + +typedef struct _authcontext { + char *authname; + char *authdata; + FSID acid; +} AuthContextRec; + +#endif /* _AUTHSTR_H_ */ diff --git a/include/cache.h b/include/cache.h new file mode 100644 index 0000000..e752055 --- /dev/null +++ b/include/cache.h @@ -0,0 +1,73 @@ +/* $Xorg: cache.h,v 1.4 2001/02/09 02:05:43 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, DIGITAL OR MIT 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.h 4.1 91/05/02 + * + */ +#ifndef _CACHE_H_ +#define _CACHE_H_ +#include "misc.h" + +#define CacheWasReset 1 +#define CacheEntryFreed 2 +#define CacheEntryOld 3 + +typedef unsigned long CacheID; +typedef unsigned long Cache; +typedef void (*CacheFree) (); + +typedef struct _cache *CachePtr; + +extern CacheID CacheStoreMemory(); +extern int CacheFreeMemory(); +extern void CacheSimpleFree(); +extern Cache CacheInit(); +extern void CacheReset(); +extern void CacheResize(); +extern pointer CacheFetchMemory(); +extern void CacheStats(); + +#endif /* _CACHE_H_ */ diff --git a/include/cachestr.h b/include/cachestr.h new file mode 100644 index 0000000..19bdd5a --- /dev/null +++ b/include/cachestr.h @@ -0,0 +1,77 @@ +/* $Xorg: cachestr.h,v 1.4 2001/02/09 02:05:43 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. + * + * @(#)cachestr.h 4.1 91/05/02 + * + */ + +#ifndef _CACHSTR_H_ +#define _CACHSTR_H_ +#include "cache.h" + +typedef struct _cache_entry { + pointer data; + unsigned long timestamp; + CacheID id; + unsigned long size; + CacheFree free_func; + struct _cache_entry *next; +} CacheEntryRec, *CacheEntryPtr; + +typedef struct _cache { + Cache id; + CacheEntryPtr *entries; + int elements; + int buckets; + int hashsize; + CacheID nextid; + unsigned long maxsize; + unsigned long cursize; +} CacheRec; + +#define NullCacheEntryPtr ((CacheEntryPtr) 0) + +#endif /* _CACHSTR_H_ */ diff --git a/include/client.h b/include/client.h new file mode 100644 index 0000000..e09f513 --- /dev/null +++ b/include/client.h @@ -0,0 +1,117 @@ +/* $Xorg: client.h,v 1.4 2001/02/09 02:05:43 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. + */ + +#ifndef _CLIENT_H_ +#define _CLIENT_H_ + +typedef struct _Client *ClientPtr; + +extern ClientPtr *clients; +extern ClientPtr serverClient; + +#define NullClient ((ClientPtr) NULL) + +#define SERVER_CLIENT 0 +#define MINCLIENT 1 + +#define CLIENT_ALIVE 0 +#define CLIENT_GONE 1 +#define CLIENT_AGED 2 +#define CLIENT_TIMED_OUT 4 + +extern int currentMaxClients; + +#define REQUEST(type) \ + type *stuff = (type *)client->requestBuffer + +#define REQUEST_FIXED_SIZE(fs_req, n) \ + if (((SIZEOF(fs_req) >> 2) > stuff->length) || \ + (((SIZEOF(fs_req) + (n) + 3) >> 2) != stuff->length)) { \ + int lengthword = stuff->length; \ + SendErrToClient(client, FSBadLength, (pointer)&lengthword); \ + return (FSBadLength); \ + } + +#define REQUEST_SIZE_MATCH(fs_req) \ + if ((SIZEOF(fs_req) >> 2) != stuff->length) { \ + int lengthword = stuff->length; \ + SendErrToClient(client, FSBadLength, (pointer)&lengthword); \ + return (FSBadLength); \ + } + +#define REQUEST_AT_LEAST_SIZE(fs_req) \ + if ((SIZEOF(fs_req) >> 2) > stuff->length) { \ + int lengthword = stuff->length; \ + SendErrToClient(client, FSBadLength, (pointer)&lengthword); \ + return (FSBadLength); \ + } + +#define WriteReplyToClient(client, size, reply) \ + if ((client)->swapped) \ + (*ReplySwapVector[((fsReq *)(client)->requestBuffer)->reqType]) \ + (client, (int)(size), reply); \ + else (void)WriteToClient(client, (int)(size), (char *)(reply)); + +#define WriteSwappedDataToClient(client, size, pbuf) \ + if ((client)->swapped) \ + (*(client)->pSwapReplyFunc)(client, (int)(size), pbuf); \ + else (void) WriteToClient(client, (int)(size), (char *)(pbuf)); + + +extern void SendErrToClient(); + +extern void SwapFontHeader(); +extern void SwapExtents(); +extern void SwapPropInfo(); +extern void SwapCharInfo(); +extern void WriteSConnSetup(); +extern void WriteSConnectionInfo(); +extern void SErrorEvent(); + +typedef struct _WorkQueue *WorkQueuePtr; +extern void ProcessWorkQueue(); + +#endif /* _CLIENT_H_ */ diff --git a/include/clientstr.h b/include/clientstr.h new file mode 100644 index 0000000..c52c746 --- /dev/null +++ b/include/clientstr.h @@ -0,0 +1,89 @@ +/* $Xorg: clientstr.h,v 1.4 2001/02/09 02:05:43 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. + */ + +#ifndef _CLIENTSTR_H_ +#define _CLIENTSTR_H_ + +#include "FS.h" +#include "client.h" +#include "auth.h" +#include "misc.h" + +typedef struct _Client { + int index; + pointer osPrivate; + int noClientException; + int (**requestVector) (); + pointer requestBuffer; + int clientGone; + int sequence; + Bool swapped; + long last_request_time; + void (*pSwapReplyFunc) (); + AuthContextPtr auth; + int auth_generation; + AuthContextPtr default_auth; + char *catalogues; + int num_catalogues; + Mask eventmask; + fsResolution *resolutions; + int num_resolutions; + int major_version; /* client-major-protocol-version */ + int minor_version; +} ClientRec; + +typedef struct _WorkQueue { + struct _WorkQueue *next; + Bool (*function) (); + ClientPtr client; + pointer closure; +} WorkQueueRec; + + +extern void CloseDownClient(); + +#endif /* _CLIENTSTR_H_ */ diff --git a/include/closestr.h b/include/closestr.h new file mode 100644 index 0000000..925af84 --- /dev/null +++ b/include/closestr.h @@ -0,0 +1,143 @@ +/* $Xorg: closestr.h,v 1.4 2001/02/09 02:05:44 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. + * + * $NCDId: @(#)closestr.h,v 4.1 1991/05/02 04:15:46 lemke Exp $ + * + */ + +#ifndef CLOSESTR_H +#define CLOSESTR_H + +#include "FSproto.h" +#include "closure.h" +#include "misc.h" +#include "font.h" + +/* closure structures */ + +/* OpenFont */ + +typedef struct _OFclosure { + ClientPtr client; + short current_fpe; + short num_fpes; + FontPathElementPtr *fpe_list; + Mask flags; + fsBitmapFormat format; + fsBitmapFormatMask format_mask; + Bool slept; + FSID fontid; + char *fontname; + int fnamelen; + char *orig_name; + int orig_len; + FontPtr non_cachable_font; +} OFclosureRec; + +/* QueryExtents */ + +typedef struct _QEclosure { + ClientPtr client; + int nranges; + fsRange *range; + FontPtr pfont; + Mask flags; + Bool slept; +} QEclosureRec; + +/* QueryBitmaps */ + +typedef struct _QBclosure { + ClientPtr client; + int nranges; + fsRange *range; + FontPtr pfont; + fsBitmapFormat format; + Mask flags; + Bool slept; +} QBclosureRec; + +/* ListFontsWithInfo */ + +#define XLFDMAXFONTNAMELEN 256 +typedef struct _LFWIstate { + char pattern[XLFDMAXFONTNAMELEN]; /* max len of font name */ + int patlen; + int current_fpe; + int max_names; + Bool list_started; + pointer private; +} LFWIstateRec, *LFWIstatePtr; + + +typedef struct _LFWXIclosure { + ClientPtr client; + int num_fpes; + FontPathElementPtr *fpe_list; + fsListFontsWithXInfoReply *reply; + int length; + LFWIstateRec current; + LFWIstateRec saved; + int savedNumFonts; + Bool haveSaved; + Bool slept; + char *savedName; +} LFWXIclosureRec; + +typedef struct _LFclosure { + ClientPtr client; + int num_fpes; + FontPathElementPtr *fpe_list; + FontNamesPtr names; + LFWIstateRec current; + LFWIstateRec saved; + Bool haveSaved; + Bool slept; + char *savedName; + int savedNameLen; +} LFclosureRec; + +#endif /* CLOSESTR_H */ diff --git a/include/closure.h b/include/closure.h new file mode 100644 index 0000000..ea8e260 --- /dev/null +++ b/include/closure.h @@ -0,0 +1,59 @@ +/* $Xorg: closure.h,v 1.4 2001/02/09 02:05:44 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, DIGITAL OR MIT 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. + * + * @(#)closure.h 4.1 91/05/02 + * + */ +#ifndef CLOSURE_H +#define CLOSURE_H 1 + +typedef struct _LFclosure *LFclosurePtr; +typedef struct _LFWXIclosure *LFWXIclosurePtr; +typedef struct _OFclosure *OFclosurePtr; +typedef struct _QEclosure *QEclosurePtr; +typedef struct _QBclosure *QBclosurePtr; + +#endif /* CLOSURE_H */ diff --git a/include/difsfn.h b/include/difsfn.h new file mode 100644 index 0000000..c795eea --- /dev/null +++ b/include/difsfn.h @@ -0,0 +1,63 @@ +/* $Xorg: difsfn.h,v 1.4 2001/02/09 02:05:44 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. + */ + +#ifndef _DIFSFONT_H_ +#define _DIFSFONT_H_ +#include "misc.h" +#include "font.h" + +typedef struct _ClientFont *ClientFontPtr; +typedef struct _FontIDList *FontIDListPtr; +typedef struct _font_name_cache FontNameCachePtr; + +#define NullClientFont ((ClientFontPtr)0) + +extern FontPtr FindCachedFontName(); +extern int CacheFontName(); +extern void RemoveBlockAndWakeupHandlers(); + +#endif /* _DIFSFONT_H_ */ diff --git a/include/difsfnst.h b/include/difsfnst.h new file mode 100644 index 0000000..5141051 --- /dev/null +++ b/include/difsfnst.h @@ -0,0 +1,74 @@ +/* $Xorg: difsfnst.h,v 1.4 2001/02/09 02:05:44 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. + */ + +#ifndef _DIFSFONTST_H_ +#define _DIFSFONTST_H_ + +#include "difsfn.h" +#include "font.h" +#include "misc.h" + +/* has per-client info about the font */ +typedef struct _ClientFont { + FontPtr font; + int clientindex; +} ClientFontRec; + +typedef struct _font_name_cache { + char *name; + int namelen; + FontPtr font; +} FontNameCacheRec; + +/* one of these per client, with as many IDs as are needed */ +typedef struct _FontIDList { + Font *client_list; + int num; + int size; +} FontIDListRec; + +#endif /* _DIFSFONTST_H_ */ diff --git a/include/extentst.h b/include/extentst.h new file mode 100644 index 0000000..2d0f0ed --- /dev/null +++ b/include/extentst.h @@ -0,0 +1,88 @@ +/* $Xorg: extentst.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)extentst.h 4.1 91/05/02 + * + */ + +#ifndef _EXTENTST_H_ +#define _EXTENTST_H_ + +typedef struct _ExtensionEntry { + int index; + void (*CloseDown) (); + char *name; + int base; + int eventBase; + int eventLast; + int errorBase; + int errorLast; + int num_aliases; + char **aliases; + pointer extPrivate; + unsigned short (*MinorOpcode) (); +} ExtensionEntry; + +extern void (*EventSwapVector[]) (); + +typedef void (*ExtensionLookupProc) (); + +typedef struct _ProcEntry { + char *name; + ExtensionLookupProc proc; +} ProcEntryRec, *ProcEntryPtr; + +extern void InitExtensions(); +extern int ProcQueryExtension(); +extern int ProcListExtensions(); +extern ExtensionEntry *AddExtension(); +extern Bool AddExtensionAlias(); +extern ExtensionLookupProc LookupProc(); +extern Bool RegisterProc(); +extern unsigned short MinorOpcodeOfRequest(); +extern unsigned short StandardMinorOpcode(); + +#endif /* _EXTENTST_H_ */ diff --git a/include/globals.h b/include/globals.h new file mode 100644 index 0000000..9b4d083 --- /dev/null +++ b/include/globals.h @@ -0,0 +1,78 @@ +/* $Xorg: globals.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)globals.h 4.2 91/05/03 + * + */ + +#ifndef _GLOBALS_H_ +#define _GLOBALS_H_ + +#include "FSproto.h" /* for fsResolution */ + +extern long TimeOutValue; +extern long ReapClientTime; + +extern int currentMaxClients; +extern long MaxClients; +extern int serverGeneration; + +extern char isItTimeToYield; +extern char dispatchException; + +extern int argcGlobal; +extern char **argvGlobal; + +/* bit values for dispatchException */ +#define DE_RESET 0x1 +#define DE_TERMINATE 0x2 +#define DE_RECONFIG 0x4 +#define DE_FLUSH 0x8 + +/* size of vector tables */ +#define NUM_PROC_VECTORS 25 +#define NUM_EVENT_VECTORS 8 +#endif /* _GLOBALS_H_ */ diff --git a/include/misc.h b/include/misc.h new file mode 100644 index 0000000..b4038aa --- /dev/null +++ b/include/misc.h @@ -0,0 +1,195 @@ +/* $Xorg: misc.h,v 1.4 2001/02/09 02:05:44 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. + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +#include <X11/Xosdefs.h> +#include <X11/Xfuncs.h> + +#include "assert.h" /* so its everywhere */ + +#ifndef NULL + +#ifndef X_NOT_STDC_ENV +#include <stddef.h> +#else +#define NULL 0 +#endif + +#endif + +#define MAXCLIENTS 128 + +typedef unsigned char *pointer; +typedef int Bool; +typedef unsigned long Atom; + +#define MILLI_PER_SECOND (1000) +#define MILLI_PER_MINUTE (1000 * 60) + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define abs(a) ((a) > 0 ? (a) : -(a)) + +#include "os.h" + +#define lowbit(x) ((x) & (~(x) + 1)) + +/* byte swapping helpers */ + +/* byte swap a long literal */ +#define lswapl(x) ((((x) & 0xff) << 24) |\ + (((x) & 0xff00) << 8) |\ + (((x) & 0xff0000) >> 8) |\ + (((x) >> 24) & 0xff)) + +/* byte swap a short literal */ +#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)) + + +/* byte swap a long */ +#define swapl(x, n) n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[3];\ + ((char *) (x))[3] = n;\ + n = ((char *) (x))[1];\ + ((char *) (x))[1] = ((char *) (x))[2];\ + ((char *) (x))[2] = n; + +/* byte swap a short */ +#define swaps(x, n) n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[1];\ + ((char *) (x))[1] = n + +/* copy long from src to dst byteswapping on the way */ +#define cpswapl(src, dst) \ + ((char *)&(dst))[0] = ((char *) &(src))[3];\ + ((char *)&(dst))[1] = ((char *) &(src))[2];\ + ((char *)&(dst))[2] = ((char *) &(src))[1];\ + ((char *)&(dst))[3] = ((char *) &(src))[0]; + +/* copy short from src to dst byteswapping on the way */ +#define cpswaps(src, dst)\ + ((char *) &(dst))[0] = ((char *) &(src))[1];\ + ((char *) &(dst))[1] = ((char *) &(src))[0]; + + +extern void SwapLongs(); +extern void SwapShorts(); + +extern void CopyIsoLatin1Lowered(); +extern void NoopDDA(); +extern char *NameForAtom(); +extern void BitOrderInvert(); +extern void TwoByteInvert(); +extern void FourByteInvert(); + +extern long GetTimeInMillis(); + + +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define fsCat(x,y) x##_##y +#else +#define fsCat(x,y) x/**/_/**/y +#endif + +/* copy a xCharInfo into a XCharInfo */ + +#define fsPack_XCharInfo(structure, packet) \ + fsCat(packet,left) = (structure)->leftSideBearing; \ + fsCat(packet,right) = (structure)->rightSideBearing; \ + fsCat(packet,width) = (structure)->characterWidth; \ + fsCat(packet,ascent) = (structure)->ascent; \ + fsCat(packet,descent) = (structure)->descent; \ + fsCat(packet,attributes) = (structure)->attributes + + +/* copy a FontInfoRec into a XFontInfoHeader */ + +#define fsPack_XFontInfoHeader(structure, packet, clientversion) \ + (packet)->font_header_flags = ((structure)->allExist) ? FontInfoAllCharsExist : 0; \ + (packet)->font_header_draw_direction = ((structure)->drawDirection == LeftToRight) \ + ? LeftToRightDrawDirection : RightToLeftDrawDirection; \ + \ + if ((structure)->inkInside) \ + (packet)->font_header_flags |= FontInfoInkInside; \ + \ + if (clientversion > 1) { \ + (packet)->font_hdr_char_range_min_char_high = (structure)->firstRow; \ + (packet)->font_hdr_char_range_min_char_low = (structure)->firstCol; \ + (packet)->font_hdr_char_range_max_char_high = (structure)->lastRow; \ + (packet)->font_hdr_char_range_max_char_low = (structure)->lastCol; \ + (packet)->font_header_default_char_high = (structure)->defaultCh >> 8; \ + (packet)->font_header_default_char_low = (structure)->defaultCh & 0xff; \ + } else { \ + (packet)->font_hdr_char_range_min_char_high = (structure)->firstCol; \ + (packet)->font_hdr_char_range_min_char_low = (structure)->firstRow; \ + (packet)->font_hdr_char_range_max_char_high = (structure)->lastCol; \ + (packet)->font_hdr_char_range_max_char_low = (structure)->lastRow; \ + (packet)->font_header_default_char_high = (structure)->defaultCh & 0xff; \ + (packet)->font_header_default_char_low = (structure)->defaultCh >> 8; \ + } \ + \ + fsPack_XCharInfo(&(structure)->ink_minbounds, (packet)->font_header_min_bounds); \ + fsPack_XCharInfo(&(structure)->ink_maxbounds, (packet)->font_header_max_bounds); \ + \ + (packet)->font_header_font_ascent = (structure)->fontAscent; \ + (packet)->font_header_font_descent = (structure)->fontDescent + + +typedef struct { /* when cloning, need old transport info */ + int trans_id; + int fd; + int portnum; +} OldListenRec; + + +#endif /* _MISC_H_ */ diff --git a/include/os.h b/include/os.h new file mode 100644 index 0000000..c5ff552 --- /dev/null +++ b/include/os.h @@ -0,0 +1,96 @@ +/* $Xorg: os.h,v 1.5 2001/02/09 02:05:44 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. + * + * $NCDId: @(#)os.h,v 4.2 1991/05/10 07:59:16 lemke Exp $ + * + */ + +#ifndef _OS_H_ +#define _OS_H_ + +#include "FSproto.h" +#include "misc.h" +#define ALLOCATE_LOCAL_FALLBACK(_size) FSalloc((unsigned long)_size) +#define DEALLOCATE_LOCAL_FALLBACK(_ptr) FSfree((pointer)_ptr) +#include "X11/Xalloca.h" + +#define MAX_REQUEST_SIZE 16384 + +extern unsigned long *FSalloc(); +extern unsigned long *FSrealloc(); +extern void FSfree(); + +#define fsalloc(size) FSalloc((unsigned long)size) +#define fsrealloc(ptr, size) FSrealloc((pointer)ptr, (unsigned long)size) +#define fsfree(ptr) FSfree((pointer)ptr) + +int ReadRequest(); + +Bool CloseDownConnection(); +void CreateSockets(); +void CloseSockets(); +void FlushAllOuput(); +long GetTimeInMIllis(); +void Error(); +void InitErrors(); +void CloseErrors(); +void NoticeF(); +void ErrorF(); +void FatalError(); +void SetConfigValues(); + +typedef pointer FID; +typedef struct _FontPathRec *FontPathPtr; + +FontPathPtr expand_font_name_pattern(); + +typedef struct _alt_server *AlternateServerPtr; +typedef struct _auth *AuthPtr; + +extern int ListCatalogues(); +extern int ListAlternateServers(); + +#endif /* _OS_H_ */ diff --git a/include/osstruct.h b/include/osstruct.h new file mode 100644 index 0000000..cea8603 --- /dev/null +++ b/include/osstruct.h @@ -0,0 +1,68 @@ +/* $Xorg: osstruct.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)osstruct.h 4.1 91/05/02 + * + */ + +#ifndef _OSSTRUCT_H_ +#define _OSSTRUCT_H_ +#include "os.h" + +typedef struct _alt_server { + char subset; + short namelen; + char *name; +} AlternateServerRec; + +typedef struct _auth { + short namelen; + short datalen; + char *name; + char *data; +} AuthRec; + +#endif /* _OSSTRUCT_H_ */ diff --git a/include/servermd.h b/include/servermd.h new file mode 100644 index 0000000..7233bd9 --- /dev/null +++ b/include/servermd.h @@ -0,0 +1,62 @@ +/* $Xorg: servermd.h,v 1.6 2001/02/09 02:05:44 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, DIGITAL OR MIT 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. + */ +#ifndef _SERVERMD_H_ +#define _SERVERMD_H_ + +#ifndef VENDOR_RELEASE +#define VENDOR_RELEASE 6600 +#endif + +#ifndef VENDOR_STRING +#define VENDOR_STRING "The X.Org Group" +#endif + +#ifndef DEFAULT_FS_PORT +#define DEFAULT_FS_PORT 7100 +#endif + +#endif /* _SERVERMD_H_ */ diff --git a/include/site.h b/include/site.h new file mode 100644 index 0000000..41ebc15 --- /dev/null +++ b/include/site.h @@ -0,0 +1,67 @@ +/* $Xorg: site.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)site.h 4.3 91/05/06 + * + */ + +#ifndef _SITE_H_ +#define _SITE_H_ +/* + * site dependent definitions + */ + +/* after twice this amount of time (in seconds) with no input from the + * client, it'll be toasted + */ +#define CLIENT_TIMEOUT 600 + + +#define DEFAULT_TIMEOUT 60 + +#define DEFAULT_CLIENT_LIMIT 20 + +#endif /* _SITE_H_ */ diff --git a/os/access.c b/os/access.c new file mode 100644 index 0000000..43c035b --- /dev/null +++ b/os/access.c @@ -0,0 +1,138 @@ +/* $Xorg: access.c,v 1.4 2001/02/09 02:05:44 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. + */ + +#include <X11/Xos.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include "clientstr.h" +#include "misc.h" +#include "site.h" +#include "accstr.h" +#include "osdep.h" +#include "osstruct.h" + +long MaxClients = DEFAULT_CLIENT_LIMIT; + +void +AccessSetConnectionLimit(num) + int num; +{ + num++; /* take serverClient into account */ + if (num > MAXSOCKS) { + ErrorF("Client limit of %d too high; using default of %d\n", + num, DEFAULT_CLIENT_LIMIT); + return; + } + MaxClients = num; +} + +/* + * XXX + * + * needs massive amounts of OS-dependent work (big surprise) + */ +int +GetHostAddress(addr) + HostAddress *addr; +{ + char hname[64]; + struct hostent *hp; + + addr->addr_len = sizeof(struct in_addr); + addr->address = (pointer) fsalloc(addr->addr_len); + if (!addr->address) + return FSBadAlloc; + addr->type = HOST_AF_INET; + gethostname(hname, sizeof(hname)); + hp = gethostbyname(hname); + if (hp) { + memmove( (char *) addr->address, (char *) hp->h_addr, addr->addr_len); + } else { + fsfree((char *) addr->address); + return FSBadName; + } + return FSSuccess; +} + +/* ARGSUSED */ +int +CheckClientAuthorization(client, client_auth, accept, index, size, auth_data) + ClientPtr client; + AuthPtr client_auth; + int *accept; + int *index; + int *size; + char **auth_data; +{ + OsCommPtr oc; + int i; + + /* now that it's connected, zero the connect time + so it doesn't get killed */ + oc = (OsCommPtr)client->osPrivate; + oc->conn_time = 0; + + *size = 0; + *accept = AuthSuccess; + + client->auth_generation++; + +#define AUTH1_NAME "hp-hostname-1" +#define AUTH2_NAME "hp-printername-1" + for (i = 0; i < *index; i++) + if (client_auth[i].namelen == sizeof(AUTH1_NAME) && + !strcmp(client_auth[i].name, AUTH1_NAME) || + client_auth[i].namelen == sizeof(AUTH2_NAME) && + !strcmp(client_auth[i].name, AUTH2_NAME)) break; + if (i == *index) + i = 0; + else + i++; + *index = i; + return FSSuccess; +} diff --git a/os/config.c b/os/config.c new file mode 100644 index 0000000..5648e5b --- /dev/null +++ b/os/config.c @@ -0,0 +1,610 @@ +/* $Xorg: config.c,v 1.4 2001/02/09 02:05:44 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. + * + * $NCDId: @(#)config.c,v 4.6 1991/07/09 14:08:09 lemke Exp $ + * + */ + +#include <stdio.h> +#include <ctype.h> +#include <X11/Xos.h> +#include "misc.h" +#include "configstr.h" +#include "osdep.h" +#include "globals.h" +#include "access.h" + +static char *font_catalogue = NULL; + +static char *config_set_int(), + *config_set_bool(), + *config_set_catalogue(), + *config_set_glyph_caching_mode(), + *config_set_list(), + *config_set_file(), + *config_set_resolutions(), + *config_set_snf_format(); + +/* these need to be in lower case and alphabetical order so a + * binary search lookup can be used + */ +static ConfigOptionRec config_options[] = { + {"alternate-servers", config_set_list}, + {"catalogue", config_set_catalogue}, + {"client-limit", config_set_int}, + {"clone-self", config_set_bool}, + {"default-point-size", config_set_int}, + {"default-resolutions", config_set_resolutions}, + {"deferglyphs", config_set_glyph_caching_mode}, + {"error-file", config_set_file}, + {"port", config_set_int}, + {"server-number", config_set_int}, + {"snf-format", config_set_snf_format}, + {"trusted-clients", config_set_list}, + {"use-syslog", config_set_bool}, + {(char *) 0, 0}, +}; + +char *ConfigErrors[] = { + "", + "CONFIG: insufficient memory to load configuration file \"%s\"\n", + "CONFIG: can't open configuration file \"%s\"\n", + "CONFIG: error reading configuration file \"%s\"\n", + "CONFIG: bad value \"%s\" for parameter \"%s\"\n", + "CONFIG: unknown parameter \"%s\"\n", + "CONFIG: missing '=' after parameter \"%s\"\n", + "CONFIG: value out of range for parameter \"%s\"\n", + "CONFIG: syntax error near parameter \"%s\"\n", + "CONFIG: missing value for parameter \"%s\"\n", + "CONFIG: extra value for parameter \"%s\"\n", +}; + +#define iseol(c) ((c) == '\n' || (c) == '\r' || (c) == '\f') +#define skip_whitespace(c) while(isspace(*(c)) || *(c) == ',') (c)++; +#define skip_val(c) while(!isspace(*(c)) && *(c) != ',' && *(c) != '\0')\ + (c) ++; +#define skip_list_val(c) while(!isspace(*(c)) && *(c) != '\0')\ + (c) ++; +#define blank_comment(c) while (!iseol(*(c)) && *(c) != '\0') \ + *(c)++= ' '; + +static char * +next_assign(c) + char *c; +{ + int nesting = 0; + + while (*c != '\0') { + if (*c == '(') + nesting++; + else if (*c == ')') + nesting--; + else if (*c == '=' && nesting == 0) + return c; + c++; + } + return (char *) 0; +} + +static void +strip_comments(data) + char *data; +{ + char *c; + + c = data; + while ((c = strchr(c, '#')) != NULL) { + if (c == data || *(c - 1) != '\\') { + blank_comment(c); + } else { + c++; + } + } +} + +static ConfigOptionPtr +match_param_name(name) + char *name; +{ + int pos, + rc, + low, + high; + + low = 0; + high = sizeof(config_options) / sizeof(ConfigOptionRec) - 2; + pos = high >> 1; + + while (low <= high) { + rc = strcmp(name, config_options[pos].parm_name); + if (rc == 0) { + return &config_options[pos]; + } else if (rc < 0) { + high = pos - 1; + } else { + low = pos + 1; + } + pos = ((high + low) >> 1); + } + return 0; +} + +static int +parse_config(data) + char *data; +{ + char *c, + *val, + *next_eq, + *consumed, + *p; + char param_name[64]; + Bool equals_missing; + ConfigOptionPtr param; + + c = data; + skip_whitespace(c); + + while (*c != '\0') { + equals_missing = FALSE; + + /* get parm name in lower case */ + p = c; + while (isalnum(*c) || *c == '-') { + if (isupper(*c)) + *c = tolower(*c); + c++; + } + memmove( param_name, p, min(sizeof(param_name), (int) (c - p))); + param_name[(int) (c - p)] = '\0'; + + /* check for junk */ + if (!isspace(*c) && *c != '=') { + ErrorF(ConfigErrors[CONFIG_ERR_SYNTAX], param_name); + /* eat garbage */ + while (!isspace(*c) && *c != '=' && *c != '\0') + c++; + } + skip_whitespace(c); + if (*c != '=') { + ErrorF(ConfigErrors[CONFIG_ERR_NOEQUALS], param_name); + equals_missing = TRUE; + } else { + c++; + } + + skip_whitespace(c); + + /* find next assignment to guess where the value ends */ + if ((next_eq = next_assign(c)) != NULL) { + /* back up over whitespace */ + for (val = next_eq - 1; val >= c && + (isspace(*val) || *val == ','); + val--); + + /* back over parm name */ + for (; val >= c && (isalnum(*val) || *val == '-'); val--); + + if (val <= c) { + /* no value, ignore */ + ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name); + continue; + } + *val = '\0'; + } else if (*c == '\0') { + /* no value, ignore */ + ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name); + continue; + } + /* match parm name */ + if (equals_missing) { + equals_missing = FALSE; + } else if ((param = match_param_name(param_name)) == NULL) { + ErrorF(ConfigErrors[CONFIG_ERR_UNKNOWN], param_name); + } else { + consumed = (param->set_func) (param, c); + + skip_whitespace(consumed); + if (*consumed != '\0') { + ErrorF(ConfigErrors[CONFIG_ERR_EXTRAVALUE], + param_name); + } + } + + if (next_eq != NULL) + c = val + 1; + else /* last setting */ + break; + } + return FSSuccess; +} + +/* + * handles anything that should be set once the file is parsed + */ +void +SetConfigValues() +{ + int err, + num; + + err = SetFontCatalogue(font_catalogue, &num); + if (err != FSSuccess) { + FatalError("Element #%d (starting at 0) of font path is bad or has a bad font:\n\"%s\"\n", + num, font_catalogue); + } + InitErrors(); + fsfree((char *) font_catalogue); + font_catalogue = NULL; +} + +int +ReadConfigFile(filename) + char *filename; +{ + FILE *fp; + int ret; + int len; + char *data; + + data = (char *) fsalloc(CONFIG_MAX_FILESIZE); + if (!data) { + ErrorF(ConfigErrors[CONFIG_ERR_MEMORY], filename); + return FSBadAlloc; + } + if ((fp = fopen(filename, "r")) == NULL) { + fsfree(data); + ErrorF(ConfigErrors[CONFIG_ERR_OPEN], filename); + return FSBadName; + } + ret = fread(data, sizeof(char), CONFIG_MAX_FILESIZE, fp); + if (ret <= 0) { + fsfree(data); + (void) fclose(fp); + ErrorF(ConfigErrors[CONFIG_ERR_READ], filename); + return FSBadName; + } + len = ftell(fp); + len = min(len, CONFIG_MAX_FILESIZE); + data[len] = '\0'; /* NULL terminate the data */ + + (void) fclose(fp); + + strip_comments(data); + ret = parse_config(data); + + fsfree(data); + + return ret; +} + +struct nameVal { + char *name; + int val; +}; + +static char * +config_parse_nameVal (c, ret, pval, name_val) + char *c; + int *ret; + int *pval; + struct nameVal *name_val; +{ + char *start, + t; + int i, + len; + + start = c; + skip_val(c); + t = *c; + *c = '\0'; + len = c - start; + + for (i = 0; name_val[i].name; i++) { + if (!strncmpnocase(start, name_val[i].name, len)) { + *pval = name_val[i].val; + *ret = 0; + *c = t; + return c; + } + } + ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start); + *c = t; + *ret = -1; + return c; +} + +static char * +config_parse_bool (c, ret, pval) + char *c; + int *ret; + Bool *pval; +{ + static struct nameVal bool_val[] = { + "yes", TRUE, + "on", TRUE, + "1", TRUE, + "true", TRUE, + "no", FALSE, + "off", FALSE, + "0", FALSE, + "false", FALSE, + (char *) 0, 0, + }; + return config_parse_nameVal (c, ret, pval, bool_val); +} + +static char * +config_parse_int(c, ret, pval) + char *c; + int *ret; + int *pval; +{ + char *start, + t; + + start = c; + while (*c != '\0' && !isspace(*c) && *c != ',') { + if (!isdigit(*c)) { /* error */ + skip_val(c); + t = *c; + *c = '\0'; + ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start); + *ret = -1; + *c = t; + return c; + } + c++; + } + t = *c; + *c = '\0'; + *ret = 0; + *pval = atoi(start); + *c = t; + return c; +} + + +/* config option sets */ +/* these have to know how to do the real work and tweak the proper things */ +static char * +config_set_int(parm, val) + ConfigOptionPtr parm; + char *val; +{ + int ival, + ret; + extern int ListenPort; + extern void SetDefaultPointSize(); + + val = config_parse_int(val, &ret, &ival); + if (ret == -1) + return val; + + /* now do individual attribute checks */ + if (!strcmp(parm->parm_name, "port")) { + ListenPort = ival; + } else if (!strcmp(parm->parm_name, "client-limit")) { + AccessSetConnectionLimit(ival); + } else if (!strcmp(parm->parm_name, "default-point-size")) { + SetDefaultPointSize(ival); + } + return val; +} + +static char * +config_set_bool(parm, val) + ConfigOptionPtr parm; + char *val; +{ + int + ret; + Bool bval; + extern int ClientLimit; + extern Bool UseSyslog, + CloneSelf; + + val = config_parse_bool(val, &ret, &bval); + if (ret == -1) + return val; + + /* now do individual attribute checks */ + if (!strcmp(parm->parm_name, "use-syslog")) { + UseSyslog = bval; + } else if (!strcmp(parm->parm_name, "clone-self")) { + CloneSelf = bval; + } + return val; +} + +static char * +config_set_file(parm, val) + ConfigOptionPtr parm; + char *val; +{ + extern char ErrorFile[]; + char *start = val, + t; + + skip_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "error-file")) { + memmove( ErrorFile, start, val - start + 1); + } + *val = t; + return val; +} + +static char * +config_set_catalogue(parm, val) + ConfigOptionPtr parm; + char *val; +{ + char *b; + + if (!strcmp(parm->parm_name, "catalogue")) { + /* stash it for later */ + fsfree((char *) font_catalogue); /* dump any previous one */ + b = font_catalogue = (char *) fsalloc(strlen(val) + 1); + if (!font_catalogue) + FatalError("Insufficent memory for font catalogue\n"); + while (*val) { /* remove all the gunk */ + if (!isspace(*val)) { + *b++ = *val; + } + val++; + } + *b = '\0'; + } + return val; +} + +static char * +config_set_list(parm, val) + ConfigOptionPtr parm; + char *val; +{ + char *start = val, + t; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "alternate-servers")) { + SetAlternateServers(start); + } + *val = t; + return val; +} + +static char * +config_set_glyph_caching_mode(parm, val) + ConfigOptionPtr parm; + char *val; +{ + char *start = val, + t; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "deferglyphs")) { + ParseGlyphCachingMode(start); + } + *val = t; + return val; +} + +static char * +config_set_resolutions(parm, val) + ConfigOptionPtr parm; + char *val; +{ + char *start = val, + t; + int err; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "default-resolutions")) { + err = SetDefaultResolutions(start); + if (err != FSSuccess) { + FatalError("Bogus resolution list \"%s\"\n", start); + } + } + *val = t; + return val; +} + + +static char * +config_parse_endian(c, ret, pval) + char *c; + int *ret; + int *pval; +{ + static struct nameVal endian_val[] = { + "lsb", LSBFirst, + "little", LSBFirst, + "lsbfirst", LSBFirst, + "msb", MSBFirst, + "big", MSBFirst, + "msbfirst", MSBFirst, + (char *) 0, 0, + }; + return config_parse_nameVal (c, ret, pval, endian_val); +} + +/* ARGSUSED */ +static char * +config_set_snf_format (parm, val) + ConfigOptionPtr parm; + char *val; +{ + int bit, byte, glyph, scan; + int ret; + + val = config_parse_endian (val, &ret, &bit); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_endian (val, &ret, &byte); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_int (val, &ret, &glyph); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_int (val, &ret, &scan); + if (ret == -1) + return val; + SnfSetFormat (bit, byte, glyph, scan); + return val; +} diff --git a/os/config.h b/os/config.h new file mode 100644 index 0000000..ba6db45 --- /dev/null +++ b/os/config.h @@ -0,0 +1,69 @@ +/* $Xorg: config.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)config.h 4.1 91/05/02 + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* max size in bytes of config file */ +#define CONFIG_MAX_FILESIZE 32767 + +/* error codes */ +/* these should be in the same order as the error strings in config.c */ +#define CONFIG_ERR_MEMORY 1 +#define CONFIG_ERR_OPEN 2 +#define CONFIG_ERR_READ 3 +#define CONFIG_ERR_VALUE 4 +#define CONFIG_ERR_UNKNOWN 5 +#define CONFIG_ERR_NOEQUALS 6 +#define CONFIG_ERR_RANGE 7 +#define CONFIG_ERR_SYNTAX 8 +#define CONFIG_ERR_NOVALUE 9 +#define CONFIG_ERR_EXTRAVALUE 10 +#endif /* _CONFIG_H_ */ diff --git a/os/configstr.h b/os/configstr.h new file mode 100644 index 0000000..1c8184f --- /dev/null +++ b/os/configstr.h @@ -0,0 +1,59 @@ +/* $Xorg: configstr.h,v 1.4 2001/02/09 02:05:44 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, DIGITAL OR MIT 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. + * + * @(#)configstr.h 4.1 91/05/02 + * + */ +#ifndef _CONFIGSTR_H_ +#define _CONFIGSTR_H_ +#include "config.h" + +typedef struct _config_options { + char *parm_name; + char *(*set_func) (); +} ConfigOptionRec, *ConfigOptionPtr; + +#endif /* _CONFIGSTR_H_ */ diff --git a/os/connection.c b/os/connection.c new file mode 100644 index 0000000..0e3af59 --- /dev/null +++ b/os/connection.c @@ -0,0 +1,579 @@ +/* $Xorg: connection.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * handles connections + */ +/* + +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. + */ +/* + * 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. + */ + +#include <X11/Xtrans.h> +#include "misc.h" +#include <stdio.h> +#include <errno.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <signal.h> + +#include "FS.h" +#include "FSproto.h" +#include "clientstr.h" +#include "X11/Xpoll.h" +#include "osdep.h" +#include "globals.h" +#include "osstruct.h" +#include "servermd.h" + +#ifdef X_NOT_STDC_ENV +extern int errno; +#endif + + +int ListenPort = DEFAULT_FS_PORT; /* port to listen on */ +int lastfdesc; + +fd_set WellKnownConnections; +fd_set AllSockets; +fd_set AllClients; +fd_set LastSelectMask; +fd_set ClientsWithInput; +fd_set ClientsWriteBlocked; +fd_set OutputPending; +extern long MaxClients; +long OutputBufferSize = BUFSIZE; + +Bool NewOutputPending; +Bool AnyClientsWriteBlocked; + +int ConnectionTranslation[MAXSOCKS]; + +XtransConnInfo *ListenTransConns = NULL; +int *ListenTransFds = NULL; +int ListenTransCount; + +extern ClientPtr NextAvailableClient(); + +#ifdef SIGNALRETURNSINT +#define SIGVAL int +#else +#define SIGVAL void +#endif + +extern SIGVAL AutoResetServer(); +extern SIGVAL GiveUp(); +extern SIGVAL ServerReconfig(); +extern SIGVAL ServerCacheFlush(); +extern SIGVAL CleanupChild(); + +extern void FreeOsBuffers(); + +static void error_conn_max(); +static void close_fd(); + + +static XtransConnInfo +lookup_trans_conn (fd) + +int fd; + +{ + if (ListenTransFds) + { + int i; + for (i = 0; i < ListenTransCount; i++) + if (ListenTransFds[i] == fd) + return ListenTransConns[i]; + } + + return (NULL); +} + +StopListening() +{ + int i; + + for (i = 0; i < ListenTransCount; i++) + { + FD_CLR (ListenTransFds[i], &AllSockets); + _FontTransCloseForCloning (ListenTransConns[i]); + } + + free ((char *) ListenTransFds); + free ((char *) ListenTransConns); + + ListenTransFds = NULL; + ListenTransConns = NULL; +} + +/* + * creates the sockets for listening to clients + * + * only called when server first started + */ +void +CreateSockets(old_listen_count, old_listen) + +int old_listen_count; +OldListenRec *old_listen; + +{ + int request, + i; + + FD_ZERO(&AllSockets); + FD_ZERO(&AllClients); + FD_ZERO(&LastSelectMask); + FD_ZERO(&ClientsWithInput); + FD_ZERO(&WellKnownConnections); + + for (i = 0; i < MAXSOCKS; i++) + ConnectionTranslation[i] = 0; + +#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */ +#undef _SC_OPEN_MAX +#endif +#ifdef _SC_OPEN_MAX + lastfdesc = sysconf(_SC_OPEN_MAX) - 1; +#else +#ifdef hpux + lastfdesc = _NFILE - 1; +#else + lastfdesc = getdtablesize() - 1; +#endif +#endif + + if (lastfdesc > MAXSOCKS) { + lastfdesc = MAXSOCKS; + } + + if (old_listen_count > 0) { + + /* + * The font server cloned itself. Re-use previously opened + * transports for listening. + */ + + ListenTransConns = (XtransConnInfo *) malloc ( + old_listen_count * sizeof (XtransConnInfo)); + + ListenTransFds = (int *) malloc (old_listen_count * sizeof (int)); + + ListenTransCount = 0; + + for (i = 0; i < old_listen_count; i++) + { + char portnum[10]; + + if (old_listen[i].portnum != ListenPort) + continue; /* this should never happen */ + else + sprintf (portnum, "%d", old_listen[i].portnum); + + if ((ListenTransConns[ListenTransCount] = + _FontTransReopenCOTSServer (old_listen[i].trans_id, + old_listen[i].fd, portnum)) != NULL) + { + ListenTransFds[ListenTransCount] = old_listen[i].fd; + FD_SET (old_listen[i].fd, &WellKnownConnections); + + NoticeF("Reusing existing file descriptor %d\n", + old_listen[i].fd); + + ListenTransCount++; + } + } + } else { + char port[20]; + int partial; + + sprintf (port, "%d", ListenPort); + + if ((_FontTransMakeAllCOTSServerListeners (port, &partial, + &ListenTransCount, &ListenTransConns) >= 0) && + (ListenTransCount >= 1)) + { + ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int)); + + for (i = 0; i < ListenTransCount; i++) + { + int fd = _FontTransGetConnectionNumber (ListenTransConns[i]); + + ListenTransFds[i] = fd; + FD_SET (fd, &WellKnownConnections); + } + } + } + + if (! XFD_ANYSET(&WellKnownConnections)) + FatalError("Cannot establish any listening sockets\n"); + + + /* set up all the signal handlers */ + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, AutoResetServer); + signal(SIGINT, GiveUp); + signal(SIGTERM, GiveUp); + signal(SIGUSR1, ServerReconfig); + signal(SIGUSR2, ServerCacheFlush); + signal(SIGCHLD, CleanupChild); + + XFD_COPYSET (&WellKnownConnections, &AllSockets); +} + +/* + * called when server cycles + */ +ResetSockets() +{ +} + +void +CloseSockets(void) +{ + int i; + + for (i = 0; i < ListenTransCount; i++) + _FontTransClose (ListenTransConns[i]); +} + +/* + * accepts new connections + */ +void +MakeNewConnections() +{ + fd_mask readyconnections; + int curconn; + int newconn; + long connect_time; + int i; + ClientPtr client; + OsCommPtr oc; + fd_set tmask; + + XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections); + readyconnections = tmask.fds_bits[0]; + if (!readyconnections) + return; + connect_time = GetTimeInMillis(); + + /* kill off stragglers */ + for (i = MINCLIENT; i < currentMaxClients; i++) { + if ((client = clients[i]) != NullClient) { + oc = (OsCommPtr) client->osPrivate; + if (oc && (oc->conn_time != 0) && + (connect_time - oc->conn_time) >= TimeOutValue || + client->noClientException != FSSuccess && + client->clientGone != CLIENT_GONE) + CloseDownClient(client); + } + } + + while (readyconnections) { + XtransConnInfo trans_conn, new_trans_conn; + int status; + + curconn = ffs(readyconnections) - 1; + readyconnections &= ~(1 << curconn); + + if ((trans_conn = lookup_trans_conn (curconn)) == NULL) + continue; + + if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL) + continue; + + newconn = _FontTransGetConnectionNumber (new_trans_conn); + + _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); + + oc = (OsCommPtr) fsalloc(sizeof(OsCommRec)); + if (!oc) { + fsfree(oc); + error_conn_max(new_trans_conn); + _FontTransClose(new_trans_conn); + continue; + } + FD_SET(newconn, &AllClients); + FD_SET(newconn, &AllSockets); + oc->fd = newconn; + oc->trans_conn = new_trans_conn; + oc->input = (ConnectionInputPtr) NULL; + oc->output = (ConnectionOutputPtr) NULL; + oc->conn_time = connect_time; + + if ((newconn < lastfdesc) && + (client = NextAvailableClient((pointer) oc))) { + ConnectionTranslation[newconn] = client->index; + } else { + error_conn_max(new_trans_conn); + close_fd(oc); + } + } +} + +#define NOROOM "Maximum number of clients reached" + +static void +error_conn_max(trans_conn) + +XtransConnInfo trans_conn; + +{ + int fd = _FontTransGetConnectionNumber (trans_conn); + fsConnSetup conn; + char pad[3]; + char byteOrder = 0; + int whichbyte = 1; + struct timeval waittime; + fd_set mask; + + + waittime.tv_usec = BOTIMEOUT / MILLI_PER_SECOND; + waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) * + (1000000 / MILLI_PER_SECOND); + FD_ZERO(&mask); + FD_SET(fd, &mask); + (void) Select(fd + 1, &mask, NULL, NULL, &waittime); + /* try to read the byteorder of the connection */ + (void) _FontTransRead(trans_conn, &byteOrder, 1); + if ((byteOrder == 'l') || (byteOrder == 'B')) { + int num_alts; + AlternateServerPtr altservers, + as; + int i, + altlen = 0; + + num_alts = ListAlternateServers(&altservers); + conn.status = AuthDenied; + conn.major_version = FS_PROTOCOL; + conn.minor_version = FS_PROTOCOL_MINOR; + conn.num_alternates = num_alts; + for (i = 0, as = altservers; i < num_alts; i++, as++) { + altlen += (2 + as->namelen + 3) >> 2; + } + conn.alternate_len = altlen; + /* blow off the auth info */ + conn.auth_index = 0; + conn.auth_len = 0; + + if (((*(char *) &whichbyte) && (byteOrder == 'B')) || + (!(*(char *) &whichbyte) && (byteOrder == 'l'))) { + conn.status = lswaps(conn.status); + conn.major_version = lswaps(conn.major_version); + conn.minor_version = lswaps(conn.minor_version); + conn.alternate_len = lswaps(conn.alternate_len); + } + (void) _FontTransWrite(trans_conn, + (char *) &conn, SIZEOF(fsConnSetup)); + /* dump alternates */ + for (i = 0, as = altservers; i < num_alts; i++, as++) { + (void) _FontTransWrite(trans_conn, + (char *) as, 2); /* XXX */ + (void) _FontTransWrite(trans_conn, + (char *) as->name, as->namelen); + altlen = 2 + as->namelen; + /* pad it */ + if (altlen & 3) + (void) _FontTransWrite(trans_conn, + (char *) pad, ((4 - (altlen & 3)) & 3)); + } + } +} + +static void +close_fd(oc) + OsCommPtr oc; +{ + int fd = oc->fd; + + if (oc->trans_conn) + _FontTransClose(oc->trans_conn); + FreeOsBuffers(oc); + FD_CLR(fd, &AllSockets); + FD_CLR(fd, &AllClients); + FD_CLR(fd, &ClientsWithInput); + FD_CLR(fd, &ClientsWriteBlocked); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + FD_CLR(fd, &OutputPending); + fsfree(oc); +} + +CheckConnections() +{ + fd_set mask; + fd_set tmask; + int curclient; + int i; + struct timeval notime; + int r; + + notime.tv_sec = 0; + notime.tv_usec = 0; + + XFD_COPYSET(&AllClients, &mask); + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { + while (mask.fds_bits[i]) { + curclient = ffs(mask.fds_bits[i]) - 1 + (i << 5); + FD_ZERO(&tmask); + FD_SET(curclient, &tmask); + r = Select(curclient + 1, &tmask, NULL, NULL, ¬ime); + if (r < 0) + CloseDownClient(clients[ConnectionTranslation[curclient]]); + FD_CLR(curclient, &mask); + } + } +} + +CloseDownConnection(client) + ClientPtr client; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + + if (oc->output && oc->output->count) + FlushClient(client, oc, (char *) NULL, 0, 0); + ConnectionTranslation[oc->fd] = 0; + close_fd(oc); + client->osPrivate = (pointer) NULL; +} + + +/**************** + * IgnoreClient + * Removes one client from input masks. + * Must have cooresponding call to AttendClient. + ****************/ + +static fd_set IgnoredClientsWithInput; + +IgnoreClient(client) + ClientPtr client; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + int connection = oc->fd; + + if (FD_ISSET(connection, &ClientsWithInput)) + FD_SET(connection, &IgnoredClientsWithInput); + else + FD_CLR(connection, &IgnoredClientsWithInput); + FD_CLR(connection, &ClientsWithInput); + FD_CLR(connection, &AllSockets); + FD_CLR(connection, &AllClients); + FD_CLR(connection, &LastSelectMask); + isItTimeToYield = TRUE; +} + +/**************** + * AttendClient + * Adds one client back into the input masks. + ****************/ + +AttendClient(client) + ClientPtr client; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + int connection = oc->fd; + + FD_SET(connection, &AllClients); + FD_SET(connection, &AllSockets); + FD_SET(connection, &LastSelectMask); + if (FD_ISSET(connection, &IgnoredClientsWithInput)) + FD_SET(connection, &ClientsWithInput); +} + +/* + * figure out which clients need to be toasted + */ +ReapAnyOldClients() +{ + int i; + long cur_time = GetTimeInMillis(); + ClientPtr client; + extern void SendKeepAliveEvent(); + +#ifdef DEBUG + fprintf(stderr, "Looking for clients to reap\n"); +#endif + + for (i = MINCLIENT; i < currentMaxClients; i++) { + client = clients[i]; + if (client) { + if ((cur_time - client->last_request_time) >= ReapClientTime) { + if (client->clientGone == CLIENT_AGED) { + client->clientGone = CLIENT_TIMED_OUT; + +#ifdef DEBUG + fprintf(stderr, "reaping client #%d\n", i); +#endif + + CloseDownClient(client); + } else { + client->clientGone = CLIENT_AGED; + SendKeepAliveEvent(client); + } + } + } + } +} diff --git a/os/error.c b/os/error.c new file mode 100644 index 0000000..e1b02e7 --- /dev/null +++ b/os/error.c @@ -0,0 +1,217 @@ +/* $Xorg: error.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * error message handling + */ +/* +Copyright 1994, 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 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, 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. + */ + +#include <stdio.h> +#include <X11/Xos.h> +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#include <sys/param.h> +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#ifdef USE_SYSLOG +#include <syslog.h> +#endif + +#include "misc.h" + +extern char *progname; + +Bool UseSyslog; +char ErrorFile[PATH_MAX]; + +static void +abort_server() +{ + fflush(stderr); + +#ifdef SABER + saber_stop(); +#else + abort(); +#endif +} + +void +InitErrors() +{ + int i; + +#ifdef USE_SYSLOG + if (UseSyslog && !log_open) { + openlog("Font Server", LOG_PID, LOG_LOCAL0); + log_open = TRUE; + return; + } +#endif + + if (ErrorFile[0]) { + i = creat(ErrorFile, 0666); + if (i != -1) { + dup2(i, 2); + close(i); + } else { + ErrorF("Can't open error file \"%s\"\n", ErrorFile); + } + } +} + +void +CloseErrors() +{ +#ifdef USE_SYSLOG + if (UseSyslog) { + closelog(); + log_open = FALSE; + return; + } +#endif +} + +void +Error(str) + char *str; +{ + /* XXX this should also go to syslog() */ + perror(str); +} + +/* + * used for informational messages + */ +/* VARARGS1 */ +void +NoticeF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of 10 args */ + char *f; + char *s0, + *s1, + *s2, + *s3, + *s4, + *s5, + *s6, + *s7, + *s8, + *s9; +{ + +#ifdef USE_SYSLOG + if (UseSyslog) { + syslog(LOG_NOTICE, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); + return; + } +#endif + + /* XXX should Notices just be ignored if not using syslog? */ + fprintf(stderr, "%s notice: ", progname); + fprintf(stderr, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); +} + +/* + * used for non-fatal error messages + */ +/* VARARGS1 */ +void +ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of 10 args */ + char *f; + char *s0, + *s1, + *s2, + *s3, + *s4, + *s5, + *s6, + *s7, + *s8, + *s9; +{ + +#ifdef USE_SYSLOG + if (UseSyslog) { + syslog(LOG_ERR, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); + return; + } +#endif + + fprintf(stderr, "%s error: ", progname); + fprintf(stderr, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); +} + +/* VARARGS1 */ +void +FatalError(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of 10 args */ + char *f; + char *s0, + *s1, + *s2, + *s3, + *s4, + *s5, + *s6, + *s7, + *s8, + *s9; +{ + ErrorF("Fatal font server error:\n"); + ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); + abort_server(); + /* NOTREACHED */ +} @@ -0,0 +1,688 @@ +/* $Xorg: io.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * i/o functions + */ +/* + +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. + */ + +#include <X11/Xtrans.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/uio.h> + +#include "FSproto.h" +#include "clientstr.h" +#include "X11/Xpoll.h" +#include "osdep.h" +#include "globals.h" + +#ifdef X_NOT_STDC_ENV +extern int errno; +#endif + + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ + +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK) +#else + +#ifdef EAGAIN +#define ETEST(err) (err == EAGAIN) +#else +#define ETEST(err) (err == EWOULDBLOCK) +#endif + +#endif + + +extern fd_set ClientsWithInput; +extern fd_set ClientsWriteBlocked; +extern fd_set OutputPending; + +extern long OutputBufferSize; + +extern int ConnectionTranslation[]; + +extern Bool AnyClientsWriteBlocked; +extern Bool NewOutputPending; + +static int timesThisConnection = 0; +static ConnectionInputPtr FreeInputs = (ConnectionInputPtr) NULL; +static ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr) NULL; +static OsCommPtr AvailableInput = (OsCommPtr) NULL; + +static ConnectionInputPtr AllocateInputBuffer(); +static ConnectionOutputPtr AllocateOutputBuffer(); + + +#define MAX_TIMES_PER 10 + +#define yield_control() \ + { isItTimeToYield = TRUE; \ + timesThisConnection = 0; } + +#define yield_control_no_input() \ + { yield_control(); \ + FD_CLR(fd, &ClientsWithInput); } + +#define yield_control_death() \ + { timesThisConnection = 0; } + +#define request_length(req, client) \ + ((int)((client)->swapped ? lswaps((req)->length) : (req)->length) << 2) + +int +ReadRequest(client) + ClientPtr client; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionInputPtr oci = oc->input; + fsReq *request; + int fd = oc->fd; + int result, + gotnow, + needed = 0; + + if (AvailableInput) { + if (AvailableInput != oc) { + ConnectionInputPtr aci = AvailableInput->input; + + if (aci->size > BUFWATERMARK) { + fsfree(aci->buffer); + fsfree(aci); + } else { + aci->next = FreeInputs; + FreeInputs = aci; + } + AvailableInput->input = (ConnectionInputPtr) NULL; + } + AvailableInput = (OsCommPtr) NULL; + } + if (!oci) { + if ((oci = FreeInputs ) != (ConnectionInputPtr) 0) { + FreeInputs = oci->next; + } else if (!(oci = AllocateInputBuffer())) { + yield_control_death(); + return -1; + } + oc->input = oci; + } + oci->bufptr += oci->lenLastReq; + + gotnow = oci->bufcnt + oci->buffer - oci->bufptr; + +#ifdef WORD64 + /* need 8-byte alignment */ + if ((oci->bufptr - oci->buffer) & 7 && gotnow > 0) + { + memmove( oci->buffer, oci->bufptr, gotnow); + oci->bufptr = oci->buffer; + oci->bufcnt = gotnow; + } +#endif + + request = (fsReq *) oci->bufptr; + + /* not enough for a request */ + if ((gotnow < SIZEOF(fsReq)) || + (gotnow < (needed = request_length(request, client)))) { + oci->lenLastReq = 0; + if ((gotnow < SIZEOF(fsReq)) || needed == 0) + needed = SIZEOF(fsReq); + else if (needed > MAXBUFSIZE) { + yield_control_death(); + return -1; + } + /* see if we need to shift up a partial request so the rest can fit */ + if ((gotnow == 0) || + ((oci->bufptr - oci->buffer + needed) > oci->size)) + { + if ((gotnow > 0) && (oci->bufptr != oci->buffer)) + memmove( oci->buffer, oci->bufptr, gotnow); + /* grow buffer if necessary */ + if (needed > oci->size) { + char *ibuf; + + ibuf = (char *) fsrealloc(oci->buffer, needed); + if (!ibuf) { + yield_control_death(); + return -1; + } + oci->size = needed; + oci->buffer = ibuf; + } + oci->bufptr = oci->buffer; + oci->bufcnt = gotnow; + } + /* fill 'er up */ + result = _FontTransRead(oc->trans_conn, oci->buffer + oci->bufcnt, + oci->size - oci->bufcnt); + if (result <= 0) { + if ((result < 0) && ETEST(errno)) { + yield_control_no_input(); + return 0; + } else { + yield_control_death(); + return -1; + } + } + oci->bufcnt += result; + gotnow += result; + + /* free up space after huge requests */ + if ((oci->size > BUFWATERMARK) && + (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE)) { + char *ibuf; + + ibuf = (char *) fsrealloc(oci, BUFSIZE); + if (ibuf) { + oci->size = BUFSIZE; + oci->buffer = ibuf; + oci->bufptr = ibuf + oci->bufcnt - gotnow; + } + } + request = (fsReq *) oci->bufptr; + if ((gotnow < SIZEOF(fsReq)) || + (gotnow < (needed = request_length(request, client)))) { + yield_control_no_input(); + return 0; + } + } + if (needed == 0) + needed = SIZEOF(fsReq); + oci->lenLastReq = needed; + /* + * Check to see if client has at least one whole request in the buffer. If + * there is only a partial request, treat like buffer is empty so that + * select() will be called again and other clients can get into the queue. + */ + + if (gotnow >= needed + SIZEOF(fsReq)) { + request = (fsReq *) (oci->bufptr + needed); + if (gotnow >= needed + request_length(request, client)) + FD_SET(fd, &ClientsWithInput); + else + yield_control_no_input(); + } else { + if (gotnow == needed) + AvailableInput = oc; + yield_control_no_input(); + } + + if (++timesThisConnection >= MAX_TIMES_PER) + yield_control(); + + client->requestBuffer = (pointer) oci->bufptr; + return needed; +} + +Bool +InsertFakeRequest(client, data, count) + ClientPtr client; + char *data; + int count; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionInputPtr oci = oc->input; + int fd = oc->fd; + fsReq *request; + int gotnow, + moveup; + + if (AvailableInput) { + if (AvailableInput != oc) { + register ConnectionInputPtr aci = AvailableInput->input; + + if (aci->size > BUFWATERMARK) { + fsfree(aci->buffer); + fsfree(aci); + } else { + aci->next = FreeInputs; + FreeInputs = aci; + } + AvailableInput->input = (ConnectionInputPtr) NULL; + } + AvailableInput = (OsCommPtr) NULL; + } + if (!oci) { + if ((oci = FreeInputs) != (ConnectionInputPtr) 0) + FreeInputs = oci->next; + else if (!(oci = AllocateInputBuffer())) + return FALSE; + oc->input = oci; + + } + oci->bufptr += oci->lenLastReq; + oci->lenLastReq = 0; + gotnow = oci->bufcnt + oci->buffer - oci->bufptr; + if ((gotnow + count) > oci->size) { + char *ibuf; + + ibuf = (char *) fsrealloc(oci->buffer, gotnow + count); + if (!ibuf) + return FALSE; + oci->size = gotnow + count; + oci->buffer = ibuf; + oci->bufptr = ibuf + oci->bufcnt - gotnow; + } + moveup = count - (oci->bufptr - oci->buffer); + if (moveup > 0) { + if (gotnow > 0) + memmove( oci->bufptr + moveup, oci->bufptr, gotnow); + oci->bufptr += moveup; + oci->bufcnt += moveup; + } + memmove( oci->bufptr - count, data, count); + oci->bufptr -= count; + request = (fsReq *) oci->bufptr; + gotnow += count; + if ((gotnow >= SIZEOF(fsReq)) && + (gotnow >= request_length(request, client))) + FD_SET(fd, &ClientsWithInput); + else + yield_control_no_input(); + return TRUE; +} + +ResetCurrentRequest(client) + ClientPtr client; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionInputPtr oci = oc->input; + int fd = oc->fd; + fsReq *request; + int gotnow; + + if (AvailableInput == oc) + AvailableInput = (OsCommPtr) NULL; + oci->lenLastReq = 0; + request = (fsReq *) oci->bufptr; + gotnow = oci->bufcnt + oci->buffer - oci->bufptr; + if ((gotnow >= SIZEOF(fsReq)) && + (gotnow >= request_length(request, client))) { + FD_SET(fd, &ClientsWithInput); + yield_control(); + } else { + yield_control_no_input(); + } +} + +int +FlushClient(client, oc, extraBuf, extraCount, padsize) + ClientPtr client; + OsCommPtr oc; + char *extraBuf; + int extraCount; + int padsize; +{ + ConnectionOutputPtr oco = oc->output; + int fd = oc->fd; + struct iovec iov[3]; + char padBuffer[3]; + long written; + long notWritten; + long todo; + + if (!oco) + return 0; + written = 0; + notWritten = oco->count + extraCount + padsize; + todo = notWritten; + while (notWritten) { + long before = written; + long remain = todo; + int i = 0; + long len; + + /*- + * You could be very general here and have "in" and "out" iovecs and + * write a loop without using a macro, but what the heck. This + * translates to: + * + * how much of this piece is new? + * if more new then we are trying this time, clamp + * if nothing new + * then bump down amount already written, for next piece + * else put new stuff in iovec, will need all of next piece + * + * Note that todo had better be at least 1 or else we'll end up + * writing 0 iovecs. + */ + +#define InsertIOV(pointer, length) \ + len = (length) - before; \ + if (len > remain) \ + len = remain; \ + if (len <= 0) { \ + before = (-len); \ + } else { \ + iov[i].iov_len = len; \ + iov[i].iov_base = (pointer) + before; \ + i++; \ + remain -= len; \ + before = 0; \ + } + + InsertIOV((char *) oco->buf, oco->count); + InsertIOV(extraBuf, extraCount); + InsertIOV(padBuffer, padsize); + + errno = 0; + if (oc->trans_conn && (len = _FontTransWritev(oc->trans_conn, iov, i)) >= 0) { + written += len; + notWritten -= len; + todo = notWritten; + } else if (ETEST(errno) +#ifdef SUNSYSV /* check for another brain-damaged OS bug */ + || (errno == 0) +#endif +#ifdef EMSGSIZE /* check for another brain-damaged OS bug */ + || ((errno == EMSGSIZE) && (todo == 1)) +#endif + ) + { + FD_SET(fd, &ClientsWriteBlocked); + AnyClientsWriteBlocked = TRUE; + + if (written < oco->count) { + if (written > 0) { + oco->count -= written; + memmove( (char *) oco->buf, (char *) oco->buf + written, + oco->count); + written = 0; + } + } else { + written -= oco->count; + oco->count = 0; + } + + /* grow buffer if necessary */ + if (notWritten > oco->size) { + unsigned char *obuf; + + obuf = (unsigned char *) fsrealloc(oco->buf, + notWritten + OutputBufferSize); + if (!obuf) { + _FontTransClose(oc->trans_conn); + oc->trans_conn = NULL; + MarkClientException(client); + oco->count = 0; + return -1; + } + oco->size = notWritten + OutputBufferSize; + oco->buf = obuf; + } + if ((len = extraCount - written) > 0) { + memmove( (char *) oco->buf + oco->count, + extraBuf + written, len); + } + oco->count = notWritten; + return extraCount; + } +#ifdef EMSGSIZE /* check for another brain-damaged OS bug */ + else if (errno == EMSGSIZE) + { + todo >>= 1; + } +#endif + else + { + if (oc->trans_conn) + _FontTransClose(oc->trans_conn); + oc->trans_conn = NULL; + MarkClientException(client); + oco->count = 0; + return -1; + } + } + + /* everything was flushed */ + oco->count = 0; + + /* clear the write block if it was set */ + if (AnyClientsWriteBlocked) { + FD_CLR(fd, &ClientsWriteBlocked); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + } + if (oco->size > BUFWATERMARK) { + fsfree(oco->buf); + fsfree(oco); + } else { + oco->next = FreeOutputs; + FreeOutputs = oco; + } + oc->output = (ConnectionOutputPtr) NULL; + + return extraCount; +} + +void +FlushAllOutput() +{ + int index, base; + fd_mask mask; + OsCommPtr oc; + ClientPtr client; + + if (!NewOutputPending) + return; + + NewOutputPending = FALSE; + + for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) { + mask = OutputPending.fds_bits[base]; + OutputPending.fds_bits[base] = 0; + while (mask) { + index = ffs(mask) - 1; + mask &= ~lowbit(mask); + if ((index = ConnectionTranslation[(base << 5) + index]) == 0) + continue; + client = clients[index]; + if (client->clientGone == CLIENT_GONE) + continue; + oc = (OsCommPtr) client->osPrivate; + if (FD_ISSET(oc->fd, &ClientsWithInput)) { + FD_SET(oc->fd, &OutputPending); + NewOutputPending = TRUE; + } else { + (void) FlushClient(client, oc, (char *) NULL, 0, 0); + } + } + } +} + +/* + * returns number of bytes written + */ +static int +write_to_client_internal(client, count, buf, padBytes) + ClientPtr client; + int count; + char *buf; + int padBytes; +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionOutputPtr oco = oc->output; + + if (!count) + return 0; + + if (!oco) { + if ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) { + FreeOutputs = oco->next; + } else if (!(oco = AllocateOutputBuffer())) { + _FontTransClose(oc->trans_conn); + oc->trans_conn = NULL; + MarkClientException(client); + return -1; + } + oc->output = oco; + } + if (oco->count + count + padBytes > oco->size) { + FD_CLR(oc->fd, &OutputPending); + NewOutputPending = FALSE; + return FlushClient(client, oc, buf, count, padBytes); + } + NewOutputPending = TRUE; + FD_SET(oc->fd, &OutputPending); + memmove( (char *) oco->buf + oco->count, buf, count); + oco->count += count + padBytes; + + return count; +} + +WriteToClientUnpadded(client, count, buf) + ClientPtr client; + int count; + char *buf; +{ + write_to_client_internal(client, count, buf, 0); +} + +static int padlength[4] = {0, 3, 2, 1}; + +WriteToClient(client, count, buf) + ClientPtr client; + int count; + char *buf; +{ + write_to_client_internal(client, count, buf, padlength[count & 3]); +} + +static ConnectionInputPtr +AllocateInputBuffer() +{ + register ConnectionInputPtr oci; + + oci = (ConnectionInputPtr) fsalloc(sizeof(ConnectionInput)); + if (!oci) + return (ConnectionInputPtr) NULL; + oci->buffer = (char *) fsalloc(BUFSIZE); + if (!oci->buffer) { + fsfree(oci); + return (ConnectionInputPtr) NULL; + } + oci->next = 0; + oci->size = BUFSIZE; + oci->bufptr = oci->buffer; + oci->bufcnt = 0; + oci->lenLastReq = 0; + return oci; +} +static ConnectionOutputPtr +AllocateOutputBuffer() +{ + register ConnectionOutputPtr oco; + + oco = (ConnectionOutputPtr) fsalloc(sizeof(ConnectionOutput)); + if (!oco) + return (ConnectionOutputPtr) NULL; + oco->buf = (unsigned char *) fsalloc(BUFSIZE); + if (!oco->buf) { + fsfree(oco); + return (ConnectionOutputPtr) NULL; + } + oco->size = BUFSIZE; + oco->count = 0; + return oco; +} + + +void +FreeOsBuffers(oc) + OsCommPtr oc; +{ + register ConnectionInputPtr oci; + register ConnectionOutputPtr oco; + + if (AvailableInput == oc) + AvailableInput = (OsCommPtr) NULL; + if ((oci = oc->input) != (ConnectionInputPtr) 0) { + if (FreeInputs) { + fsfree(oci->buffer); + fsfree(oci); + } else { + FreeInputs = oci; + oci->next = (ConnectionInputPtr) NULL; + oci->bufptr = oci->buffer; + oci->bufcnt = 0; + oci->lenLastReq = 0; + } + } + if ((oco = oc->output) != (ConnectionOutputPtr) 0) { + if (FreeOutputs) { + fsfree(oco->buf); + fsfree(oco); + } else { + FreeOutputs = oco; + oco->next = (ConnectionOutputPtr) NULL; + oco->count = 0; + } + } +} + +void +ResetOsBuffers() +{ + register ConnectionInputPtr oci; + register ConnectionOutputPtr oco; + + while ((oci = FreeInputs) != (ConnectionInputPtr) 0) { + FreeInputs = oci->next; + fsfree(oci->buffer); + fsfree(oci); + } + while ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) { + FreeOutputs = oco->next; + fsfree(oco->buf); + fsfree(oco); + } +} diff --git a/os/osdep.h b/os/osdep.h new file mode 100644 index 0000000..c588edb --- /dev/null +++ b/os/osdep.h @@ -0,0 +1,123 @@ +/* $Xorg: osdep.h,v 1.4 2001/02/09 02:05:44 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. + * + * @(#)osdep.h 4.1 5/2/91 + * + */ + +#ifndef _OSDEP_H_ +#define _OSDEP_H_ + +#define BOTIMEOUT 200 /* in milliseconds */ +#define BUFSIZE 4096 +#define BUFWATERMARK 8192 +#define MAXBUFSIZE (1 << 18) + +#ifndef sgi /* SGI defines OPEN_MAX in a useless way */ +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#endif + +#ifndef OPEN_MAX +#ifdef SVR4 +#define OPEN_MAX 128 +#else +#include <sys/param.h> +#ifndef OPEN_MAX +#if defined(NOFILE) && !defined(NOFILES_MAX) +#define OPEN_MAX NOFILE +#else +#define OPEN_MAX NOFILES_MAX +#endif +#endif +#endif +#endif + +#if OPEN_MAX <= 128 /* 128 is value of MAXCLIENTS */ +#define MAXSOCKS (OPEN_MAX - 1) +#else +#define MAXSOCKS 128 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +typedef struct _connectionInput { + struct _connectionInput *next; + char *buffer; /* contains current client input */ + char *bufptr; /* pointer to current start of data */ + int bufcnt; /* count of bytes in buffer */ + int lenLastReq; + int size; +} ConnectionInput, *ConnectionInputPtr; + +typedef struct _connectionOutput { + struct _connectionOutput *next; + int size; + unsigned char *buf; + int count; +} ConnectionOutput, *ConnectionOutputPtr; + +typedef struct _osComm { + int fd; + ConnectionInputPtr input; + ConnectionOutputPtr output; + long conn_time; /* timestamp if not established, else 0 */ + struct _XtransConnInfo *trans_conn; /* transport connection object */ +} OsCommRec, *OsCommPtr; + +extern Bool CloneSelf; +extern Bool UseSyslog; + +#endif /* _OSDEP_H_ */ diff --git a/os/osglue.c b/os/osglue.c new file mode 100644 index 0000000..d0dd8cc --- /dev/null +++ b/os/osglue.c @@ -0,0 +1,384 @@ +/* $Xorg: osglue.c,v 1.4 2001/02/09 02:05:44 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. + * + * $NCDId: @(#)osglue.c,v 4.6 1991/07/09 14:07:30 lemke Exp $ + * + */ + +/* + * this is miscellaneous OS specific stuff. + * + * Catalogue support, alternate servers, and cloneing + */ + +#include <X11/Xtrans.h> +#include "osstruct.h" +#include <stdio.h> +#define XK_LATIN1 +#include <X11/keysymdef.h> + +Bool drone_server = FALSE; +extern Bool CloneSelf; +extern char *progname; +extern char *configfilename; + +static int num_alts; +static AlternateServerPtr alt_servers = (AlternateServerPtr) 0; + +extern XtransConnInfo *ListenTransConns; +extern int *ListenTransFds; +extern int ListenTransCount; + +/* + * XXX + * + * Catalogue support is absolutely minimal. Some guts are here, but + * we don't actually do anything with them so the only one exported is + * 'all'. Be warned that other parts of the server may incorrectly + * assume the catalogue list is global, and will therefore need fixing. + * + */ + +static char *catalogue_name = "all"; + +static Bool /* stolen from R4 Match() */ +pattern_match(pat, plen, string) + char *pat; + int plen; + char *string; +{ + register int i, + l; + int j, + m, + res; + register char cp, + cs; + int head, + tail; + + head = 0; + tail = plen; + + res = -1; + for (i = 0; i < head; i++) { + cp = pat[i]; + if (cp == XK_question) { + if (!string[i]) + return res; + res = 0; + } else if (cp != string[i]) + return res; + } + if (head == plen) + return (string[head] ? res : 1); + l = head; + while (++i < tail) { + /* we just skipped an asterisk */ + j = i; + m = l; + while ((cp = pat[i]) != XK_asterisk) { + if (!(cs = string[l])) + return 0; + if ((cp != cs) && (cp != XK_question)) { + m++; + cp = pat[j]; + if (cp == XK_asterisk) { + if (!string[m]) + return 0; + } else { + while ((cs = string[m]) != cp) { + if (!cs) + return 0; + m++; + } + } + l = m; + i = j; + } + l++; + i++; + } + } + m = strlen(&string[l]); + j = plen - tail; + if (m < j) + return 0; + l = (l + m) - j; + while (cp = pat[i]) { + if ((cp != string[l]) && (cp != XK_question)) + return 0; + l++; + i++; + } + return 1; +} + +int +ListCatalogues(pattern, patlen, maxnames, catalogues, len) + char *pattern; + int patlen; + int maxnames; + char **catalogues; + int *len; +{ + int count = 0; + char *catlist = NULL; + int size = 0; + + if (maxnames) { + if (pattern_match(pattern, patlen, catalogue_name)) { + size = strlen(catalogue_name); + catlist = (char *) fsalloc(size + 1); + if (!catlist) + goto bail; + *catlist = size; + memmove( &catlist[1], catalogue_name, size); + size++; /* for length */ + count++; + } + } +bail: + *len = size; + *catalogues = catlist; + return count; +} + +/* + * check if catalogue list is valid + */ + +int +ValidateCatalogues(num, cats) + int *num; + char *cats; +{ + char *c = cats; + int i, + len; + + for (i = 0; i < *num; i++) { + len = *c++; + if (strncmp(c, catalogue_name, len)) { + *num = i; /* return bad entry index */ + return FSBadName; + } + c += len; + } + return FSSuccess; +} + +int +SetAlternateServers(list) + char *list; +{ + char *t, + *st; + AlternateServerPtr alts, + a; + int num, + i; + + t = list; + num = 1; + while (*t) { + if (*t == ',') + num++; + t++; + } + + a = alts = (AlternateServerPtr) fsalloc(sizeof(AlternateServerRec) * num); + if (!alts) + return FSBadAlloc; + + st = t = list; + a->namelen = 0; + while (*t) { + if (*t == ',') { + a->name = (char *) fsalloc(a->namelen); + if (!a->name) { + /* XXX -- leak */ + return FSBadAlloc; + } + memmove( a->name, st, a->namelen); + a->subset = FALSE; /* XXX */ + a++; + t++; + st = t; + a->namelen = 0; + } else { + a->namelen++; + t++; + } + } + a->name = (char *) fsalloc(a->namelen); + if (!a->name) { + /* XXX -- leak */ + return FSBadAlloc; + } + memmove( a->name, st, a->namelen); + a->subset = FALSE; /* XXX */ + + for (i = 0; i < num_alts; i++) { + fsfree((char *) alt_servers[i].name); + } + fsfree((char *) alt_servers); + num_alts = num; + alt_servers = alts; + return FSSuccess; +} + +int +ListAlternateServers(svrs) + AlternateServerPtr *svrs; +{ + *svrs = alt_servers; + return num_alts; +} + +/* + * here's some fun stuff. in order to cleanly handle becoming overloaded, + * this allows us to clone ourselves. the parent keeps the Listen + * socket open, and sends it to itself. the child stops listening, + * and becomes a drone, hanging out till it loses all its clients. + */ +int +CloneMyself() +{ + int child; + char old_listen_arg[256]; + char *arg_ptr = old_listen_arg; + int i, j; + int lastfdesc; + char portnum[20]; + extern int ListenPort; + + assert(!drone_server); /* a drone shouldn't hit this */ + + if (!CloneSelf) + return -1; + + old_listen_arg[0] = '\0'; + +#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */ +#undef _SC_OPEN_MAX +#endif +#ifdef _SC_OPEN_MAX + lastfdesc = sysconf(_SC_OPEN_MAX) - 1; +#else +#ifdef hpux + lastfdesc = _NFILE - 1; +#else + lastfdesc = getdtablesize() - 1; +#endif +#endif + + NoticeF("attempting clone...\n"); + child = fork(); + if (child == -1) { + /* failed to fork */ + ErrorF("Clone failed to fork()\n"); + return -1; + } + /* + * Note: they still share the same process group, and killing the parent + * will take out all the kids as well. this is considered a feature (at + * least until i'm convinced otherwise) + */ + if (child == 0) { + StopListening(); + NoticeF("Clone: child becoming drone\n"); + drone_server = TRUE; + return 1; + } else { /* parent */ + NoticeF("Clone: parent revitalizing as %s\n", progname); + CloseErrors(); + /* XXX should we close stdio as well? */ + for (i = 3; i < lastfdesc; i++) + { + for (j = 0; j < ListenTransCount; j++) + if (ListenTransFds[j] == i) + break; + + if (j >= ListenTransCount) + (void) close(i); + } + + for (i = 0; i < ListenTransCount; i++) + { + int trans_id, fd; + char *port; + + if (!_FontTransGetReopenInfo (ListenTransConns[i], + &trans_id, &fd, &port)) + continue; + + sprintf (arg_ptr, "%d/%d/%s", trans_id, fd, port); + arg_ptr += strlen (arg_ptr); + free (port); + + if (i < ListenTransCount - 1) + { + strcat (arg_ptr, ","); + arg_ptr++; + } + } + + sprintf (portnum, "%d", ListenPort); + if (*old_listen_arg != '\0') + execlp(progname, progname, + "-ls", old_listen_arg, + "-cf", configfilename, + "-port", portnum, + NULL); + + InitErrors(); /* reopen errors, since we don't want to lose + * this */ + Error("Clone failed"); + FatalError("Failed to clone self\n"); + } + /* NOTREACHED */ +} diff --git a/os/osinit.c b/os/osinit.c new file mode 100644 index 0000000..995bf8c --- /dev/null +++ b/os/osinit.c @@ -0,0 +1,62 @@ +/* $Xorg: osinit.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * os init code + */ +/* +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. + * + * @(#)osinit.c 4.3 5/7/91 + * + */ + +#include "os.h" + +extern long LastReapTime; + +OsInit() +{ + LastReapTime = GetTimeInMillis(); + OsInitAllocator (); +} diff --git a/os/utils.c b/os/utils.c new file mode 100644 index 0000000..30c9f4f --- /dev/null +++ b/os/utils.c @@ -0,0 +1,443 @@ +/* $Xorg: utils.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * misc os utilities + */ +/* + +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. + */ + +#include <stdio.h> +#include <X11/Xos.h> +#include "misc.h" +#include "globals.h" +#include <signal.h> +#ifdef MEMBUG +#include <util/memleak/memleak.h> +#endif + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif /* X_NOT_POSIX */ +#ifndef PATH_MAX +#include <sys/param.h> +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif /* PATH_MAX */ + +#ifdef SIGNALRETURNSINT +#define SIGVAL int +#else +#define SIGVAL void +#endif + +#if defined(X_NOT_POSIX) && (defined(SYSV) || defined(SVR4)) +#define SIGNALS_RESET_WHEN_CAUGHT +#endif + +extern char *configfilename; +char *progname; +Bool CloneSelf; +extern int ListenPort; + +OldListenRec *OldListen = NULL; +int OldListenCount = 0; + +/* ARGSUSED */ +SIGVAL +AutoResetServer(n) + int n; +{ + +#ifdef DEBUG + fprintf(stderr, "got a reset signal\n"); +#endif + + dispatchException |= DE_RESET; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGHUP, AutoResetServer); +#endif +} + +SIGVAL +GiveUp() +{ + +#ifdef DEBUG + fprintf(stderr, "got a TERM signal\n"); +#endif + + dispatchException |= DE_TERMINATE; + isItTimeToYield = TRUE; +} + +/* ARGSUSED */ +SIGVAL +ServerReconfig(n) + int n; +{ + +#ifdef DEBUG + fprintf(stderr, "got a re-config signal\n"); +#endif + + dispatchException |= DE_RECONFIG; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGUSR1, ServerReconfig); +#endif +} + +/* ARGSUSED */ +SIGVAL +ServerCacheFlush(n) + int n; +{ + +#ifdef DEBUG + fprintf(stderr, "got a flush signal\n"); +#endif + + dispatchException |= DE_FLUSH; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGUSR2, ServerCacheFlush); +#endif +} + +/* ARGSUSED */ +SIGVAL +CleanupChild(n) + int n; +{ + +#ifdef DEBUG + fprintf(stderr, "got a child signal\n"); +#endif + + wait(NULL); + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGCHLD, CleanupChild); +#endif +} + +long +GetTimeInMillis() +{ + struct timeval tp; + + X_GETTIMEOFDAY(&tp); + return ((tp.tv_sec * 1000) + (tp.tv_usec / 1000)); +} + +static void +usage() +{ + fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port]\n", + progname); + exit(1); +} + +OsInitAllocator () +{ +#ifdef MEMBUG + CheckMemory (); +#endif +} + + +/* + * The '-ls' option is used for cloning the font server. + * + * We expect a single string of the form... + * + * transport_id/fd/portnum[,transport_id/fd/portnum]... + * + * [] denotes optional and ... denotes repitition. + * + * The string must be _exactly_ in the above format. Since this is + * an internal option used by the font server, it's ok to be strict + * about the format of the string. + */ + +void +ProcessLSoption (str) + +char *str; + +{ + char *ptr = str; + char *slash, *next; + char number[20]; + int count = 0; + int len, i; + + while (*ptr != '\0') + { + if (*ptr == ',') + count++; + ptr++; + } + + OldListenCount = count + 1; + OldListen = (OldListenRec *) malloc ( + OldListenCount * sizeof (OldListenRec)); + + ptr = str; + + for (i = 0; i < OldListenCount; i++) + { + slash = (char *) strchr (ptr, '/'); + len = slash - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].trans_id = atoi (number); + + ptr = slash + 1; + + slash = (char *) strchr (ptr, '/'); + len = slash - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].fd = atoi (number); + + ptr = slash + 1; + + if (i == OldListenCount - 1) + OldListen[i].portnum = atoi (ptr); + else + { + char *comma = (char *) strchr (ptr, ','); + + len = comma - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].portnum = atoi (number); + + ptr = comma + 1; + } + } +} + + + +/* ARGSUSED */ +void +ProcessCmdLine(argc, argv) + int argc; + char **argv; +{ + int i; + + progname = argv[0]; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-port")) { + if (argv[i + 1]) + ListenPort = atoi(argv[++i]); + else + usage(); + } else if (!strcmp(argv[i], "-ls")) { + if (argv[i + 1]) + ProcessLSoption (argv[++i]); + else + usage(); + } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) { + if (argv[i + 1]) + configfilename = argv[++i]; + else + usage(); + } +#ifdef MEMBUG + else if ( strcmp( argv[i], "-alloc") == 0) + { + extern unsigned long MemoryFail; + if(++i < argc) + MemoryFail = atoi(argv[i]); + else + usage (); + } +#endif + else + usage(); + } +} + + +#ifndef SPECIAL_MALLOC + +unsigned long Must_have_memory; + +#ifdef MEMBUG +#define MEM_FAIL_SCALE 100000 +unsigned long MemoryFail; + +#endif + +/* FSalloc -- FS's internal memory allocator. Why does it return unsigned + * int * instead of the more common char *? Well, if you read K&R you'll + * see they say that alloc must return a pointer "suitable for conversion" + * to whatever type you really want. In a full-blown generic allocator + * there's no way to solve the alignment problems without potentially + * wasting lots of space. But we have a more limited problem. We know + * we're only ever returning pointers to structures which will have to + * be long word aligned. So we are making a stronger guarantee. It might + * have made sense to make FSalloc return char * to conform with people's + * expectations of malloc, but this makes lint happier. + */ + +unsigned long * +FSalloc (amount) + unsigned long amount; +{ + register pointer ptr; + + if ((long)amount < 0) + return (unsigned long *)NULL; + if (amount == 0) + amount++; + /* aligned extra on long word boundary */ + amount = (amount + 3) & ~3; +#ifdef MEMBUG + if (!Must_have_memory && MemoryFail && + ((random() % MEM_FAIL_SCALE) < MemoryFail)) + return (unsigned long *)NULL; + if (ptr = (pointer)fmalloc(amount)) + return (unsigned long *) ptr; +#else + if (ptr = (pointer)malloc(amount)) + return (unsigned long *)ptr; +#endif + if (Must_have_memory) + FatalError("Out of memory\n"); + return (unsigned long *)NULL; +} + +/***************** + * FScalloc + *****************/ + +unsigned long * +FScalloc (amount) + unsigned long amount; +{ + unsigned long *ret; + + ret = FSalloc (amount); + if (ret) + bzero ((char *) ret, (int) amount); + return ret; +} + +/***************** + * FSrealloc + *****************/ + +unsigned long * +FSrealloc (ptr, amount) + register pointer ptr; + unsigned long amount; +{ + char *realloc(); + +#ifdef MEMBUG + if (!Must_have_memory && MemoryFail && + ((random() % MEM_FAIL_SCALE) < MemoryFail)) + return (unsigned long *)NULL; + ptr = (pointer)frealloc((char *) ptr, amount); + if (ptr) + return (unsigned long *) ptr; +#else + if ((long)amount <= 0) + { + if (ptr && !amount) + free(ptr); + return (unsigned long *)NULL; + } + amount = (amount + 3) & ~3; + if (ptr) + ptr = (pointer)realloc((char *)ptr, amount); + else + ptr = (pointer)malloc(amount); + if (ptr) + return (unsigned long *)ptr; +#endif + if (Must_have_memory) + FatalError("Out of memory\n"); + return (unsigned long *)NULL; +} + +/***************** + * FSfree + * calls free + *****************/ + +void +FSfree(ptr) + register pointer ptr; +{ +#ifdef MEMBUG + if (ptr) + ffree((char *)ptr); +#else + if (ptr) + free((char *)ptr); +#endif +} + +#endif /* SPECIAL_MALLOC */ diff --git a/os/waitfor.c b/os/waitfor.c new file mode 100644 index 0000000..9b69621 --- /dev/null +++ b/os/waitfor.c @@ -0,0 +1,230 @@ +/* $Xorg: waitfor.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * waits for input + */ +/* +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. + * + * $NCDId: @(#)waitfor.c,v 4.5 1991/06/24 11:59:20 lemke Exp $ + * + */ + +#include <X11/Xos.h> /* strings, time, etc */ + +#include <stdio.h> +#include <errno.h> +#include <sys/param.h> + +#include "clientstr.h" +#include "globals.h" +#include "X11/Xpoll.h" +#include "osdep.h" + +extern WorkQueuePtr workQueue; + +#ifdef X_NOT_STDC_ENV +extern int errno; +#endif + + +extern void MakeNewConnections(); +extern void FlushAllOutput(); + +extern fd_set WellKnownConnections; +extern fd_set LastSelectMask; +extern fd_set WriteMask; +extern fd_set ClientsWithInput; +extern fd_set ClientsWriteBlocked; +extern fd_set AllSockets; +extern fd_set AllClients; +extern fd_set OutputPending; + +extern Bool AnyClientsWriteBlocked; +extern Bool NewOutputPending; + +extern int ConnectionTranslation[]; + +long LastReapTime; + +/* + * wait_for_something + * + * server suspends until + * - data from clients + * - new client connects + * - room to write data to clients + */ + +WaitForSomething(pClientsReady) + int *pClientsReady; +{ + struct timeval *wt, + waittime; + fd_set clientsReadable; + fd_set clientsWriteable; + long curclient; + int selecterr; + long current_time = 0; + long timeout; + int nready, + i; + + while (1) { + /* handle the work Q */ + if (workQueue) + ProcessWorkQueue(); + + if (XFD_ANYSET(&ClientsWithInput)) { + XFD_COPYSET(&ClientsWithInput, &clientsReadable); + break; + } + /* + * deal with KeepAlive timeouts. if this seems to costly, SIGALRM + * could be used, but its more dangerous since some it could catch us + * at an inopportune moment (like inside un-reentrant malloc()). + */ + current_time = GetTimeInMillis(); + timeout = current_time - LastReapTime; + if (timeout > ReapClientTime) { + ReapAnyOldClients(); + LastReapTime = current_time; + timeout = ReapClientTime; + } + timeout = ReapClientTime - timeout; + waittime.tv_sec = timeout / MILLI_PER_SECOND; + waittime.tv_usec = (timeout % MILLI_PER_SECOND) * + (1000000 / MILLI_PER_SECOND); + wt = &waittime; + + XFD_COPYSET(&AllSockets, &LastSelectMask); + + BlockHandler((pointer) &wt, (pointer) &LastSelectMask); + if (NewOutputPending) + FlushAllOutput(); + + if (AnyClientsWriteBlocked) { + XFD_COPYSET(&ClientsWriteBlocked, &clientsWriteable); + i = Select(MAXSOCKS, &LastSelectMask, &clientsWriteable, NULL, wt); + } else { + i = Select(MAXSOCKS, &LastSelectMask, NULL, NULL, wt); + } + selecterr = errno; + + WakeupHandler(i, (pointer) &LastSelectMask); + if (i <= 0) { /* error or timeout */ + FD_ZERO(&clientsWriteable); + if (i < 0) { + if (selecterr == EBADF) { /* somebody disconnected */ + CheckConnections(); + } else if (selecterr != EINTR) { + ErrorF("WaitForSomething: select(): errno %d\n", selecterr); + } else { + /* + * must have been broken by a signal. go deal with any + * exception flags + */ + return 0; + } + } else { /* must have timed out */ + ReapAnyOldClients(); + LastReapTime = GetTimeInMillis(); + } + } else { + if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWriteable)) { + NewOutputPending = TRUE; + XFD_ORSET(&OutputPending, &clientsWriteable, &OutputPending); + XFD_UNSET(&ClientsWriteBlocked, &clientsWriteable); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + } + XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); + if (LastSelectMask.fds_bits[0] & WellKnownConnections.fds_bits[0]) + MakeNewConnections(); + if (XFD_ANYSET(&clientsReadable)) + break; + + } + } + nready = 0; + + if (XFD_ANYSET(&clientsReadable)) { + ClientPtr client; + int conn; + + if (current_time) /* may not have been set */ + current_time = GetTimeInMillis(); + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { + while (clientsReadable.fds_bits[i]) { + curclient = ffs(clientsReadable.fds_bits[i]) - 1; + conn = ConnectionTranslation[curclient + (i << 5)]; + FD_CLR (curclient, &clientsReadable); + client = clients[conn]; + if (!client) + continue; + pClientsReady[nready++] = conn; + client->last_request_time = current_time; + client->clientGone = CLIENT_ALIVE; + } + } + } + return nready; +} + +#if 0 +/* + * This is not always a macro + */ +ANYSET(src) + long *src; +{ + int i; + + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) + if (src[i]) + return (1); + return (0); +} + +#endif @@ -0,0 +1,205 @@ +.\" Copyright 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 +.\" dealing in this Software without prior written authorization from the +.\" The Open Group. +.\" Copyright 1991 Network Computing Devices +.\" +.\" 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 name of Network Computing Devices +.\" not be used in advertising or +.\" publicity pertaining to distribution of the software without specific, +.\" written prior permission. Network Computing Devices make +.\" no representations about the +.\" suitability of this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" $Xorg: xfs.man,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $ +.TH XFS 1 "Release 6.4" "X Version 11" +.SH NAME +xfs \- X font server +.SH SYNOPSIS +.B "xfs" +[\-config \fIconfiguration_file\fP] +[\-port \fItcp_port\fP] +.SH DESCRIPTION +.PP +.I Xfs +is the X Window System font server. It supplies fonts to X Window +System display servers. +.SH "STARTING THE SERVER" +The server is usually run by a system administrator, and started via +boot files like \fI/etc/rc.local\fR. Users may also wish to start +private font servers for specific sets of fonts. +.SH "OPTIONS" +.TP 8 +.B \-config configuration_file +Specifies the configuration file the font server will use. +.TP 8 +.B \-ls listen-socket +Specifies a file descriptor which is already set up to be used as the +listen socket. This option is only intended to be used by the font server +itself when automatically spawning another copy of itself to handle +additional connections. +.TP 8 +.B \-port tcp_port +Specifies the TCP port number on which the server will listen for connections. +The default port number is 7100. +.SH "SIGNALS" +.TP 8 +.I SIGTERM +This causes the font server to exit cleanly. +.TP 8 +.I SIGUSR1 +This signal is used to cause the server to re-read its configuration file. +.TP 8 +.I SIGUSR2 +This signal is used to cause the server to flush any cached data it +may have. +.TP 8 +.I SIGHUP +This signal is used to cause the server to reset, closing all active +connections and re-reading the configuration file. +.SH "CONFIGURATION" +The configuration language is a list of keyword and value pairs. +Each keyword is followed by an '=' and then the desired value. +.PP +Recognized keywords include: +.sp +.\" .IP "cache-size (cardinal)" +.\" Size in bytes of the font server cache. +.IP "catalogue (list of string)" +Ordered list of font path element names. +Use of the keyword "catalogue" is very misleading at present, +the current implementation only supports a single catalogue ("all"), +containing all of the specified fonts. +.IP "alternate-servers (list of string)" +List of alternate servers for this font server. +.IP "client-limit (cardinal)" +Number of clients this font server will support +before refusing service. This is useful for tuning +the load on each individual font server. +.IP "clone-self (boolean)" +Whether this font server should attempt to clone itself +when it reachs the client-limit. +.IP "default-point-size (cardinal)" +The default pointsize (in decipoints) for fonts that +don't specify. The default is 120. +.IP "default-resolutions (list of resolutions)" +Resolutions the server supports by default. +This information may be used as a hint for +pre-rendering, and substituted for scaled fonts +which do not specify a resolution. +A resolution is a comma-separated pair of x and y resolutions in +pixels per inch. +Multiple resolutions are separated by commas. +.IP "error-file (string)" +Filename of the error file. All warnings and errors +will be logged here. +.IP "port (cardinal)" +TCP port on which the server will listen for connections. +.IP "use-syslog (boolean)" +Whether syslog(3) (on supported systems) is to be used +for errors. +.IP "deferglyphs (string)" +Set the mode for delayed fetching and caching of glyphs. Value is +"none", meaning deferred glyphs is disabled, "all", meaning it is +enabled for all fonts, and "16", meaning it is enabled only for +16-bits fonts. +.\" .IP "trusted-clients (list of string)" +.\" Those clients the fontserver will talk to. Others +.\" will be refused for the initial connection. An empty +.\" list means the server will talk to any client. +.SH "EXAMPLE" +.nf +# +# sample font server configuration file +# + +# allow a max of 10 clients to connect to this font server +client-limit = 10 + +# when a font server reaches its limit, start up a new one +clone-self = on + +# alternate font servers for clients to use +alternate-servers = hansen:7101,hansen:7102 + +# where to look for fonts +# the first is a set of Speedo outlines, the second is a set of +# misc bitmaps and the last is a set of 100dpi bitmaps +# +catalogue = /usr/X11R6/lib/X11/fonts/speedo, + /usr/X11R6/lib/X11/fonts/misc, + /usr/X11R6/lib/X11/fonts/100dpi/ + +# in 12 points, decipoints +default-point-size = 120 + +# 100 x 100 and 75 x 75 +default-resolutions = 100,100,75,75 +use-syslog = off +.fi +.sp +.SH "FONT SERVER NAMES" +One of the following forms can be used to name a font server that +accepts TCP connections: +.sp +.nf + tcp/\fIhostname\fP:\fIport\fP + tcp/\fIhostname\fP:\fIport\fP/\fIcataloguelist\fP +.fi +.PP +The \fIhostname\fP specifies the name (or decimal numeric address) +of the machine on which the font server is running. The \fIport\fP +is the decimal TCP port on which the font server is listening for connections. +The \fIcataloguelist\fP specifies a list of catalogue names, +with '+' as a separator. +.PP +Examples: \fItcp/fs.x.org:7100\fP, \fItcp/18.30.0.212:7101/all\fP. +.PP +One of the following forms can be used to name a font server that +accepts DECnet connections: +.sp +.nf + decnet/\fInodename\fP::font$\fIobjname\fP + decnet/\fInodename\fP::font$\fIobjname\fP/\fIcataloguelist\fP +.fi +.PP +The \fInodename\fP specifies the name (or decimal numeric address) +of the machine on which the font server is running. +The \fIobjname\fP is a normal, case-insensitive DECnet object name. +The \fIcataloguelist\fP specifies a list of catalogue names, +with '+' as a separator. +.PP +Examples: \fIDECnet/SRVNOD::FONT$DEFAULT\fP, \fIdecnet/44.70::font$special/symbols\fP. +.SH "SEE ALSO" +X(1), \fIThe X Font Service Protocol\fP, +.br +\fIFont server implementation overview\fP +.SH BUGS +Multiple catalogues should be supported. +.SH AUTHORS +Dave Lemke, Network Computing Devices, Inc +.br +Keith Packard, Massachusetts Institute of Technology |