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 /difs |
R6.6 is the Xorg base-lineXORG-MAIN
Diffstat (limited to 'difs')
-rw-r--r-- | difs/atom.c | 205 | ||||
-rw-r--r-- | difs/cache.c | 388 | ||||
-rw-r--r-- | difs/charinfo.c | 631 | ||||
-rw-r--r-- | difs/difsutils.c | 673 | ||||
-rw-r--r-- | difs/dispatch.c | 1109 | ||||
-rw-r--r-- | difs/events.c | 134 | ||||
-rw-r--r-- | difs/extensions.c | 306 | ||||
-rw-r--r-- | difs/fontinfo.c | 435 | ||||
-rw-r--r-- | difs/fonts.c | 1552 | ||||
-rw-r--r-- | difs/globals.c | 67 | ||||
-rw-r--r-- | difs/initfonts.c | 80 | ||||
-rw-r--r-- | difs/main.c | 200 | ||||
-rw-r--r-- | difs/resource.c | 569 | ||||
-rw-r--r-- | difs/swaprep.c | 472 | ||||
-rw-r--r-- | difs/swapreq.c | 286 | ||||
-rw-r--r-- | difs/tables.c | 190 |
16 files changed, 7297 insertions, 0 deletions
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 +}; |