803 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			803 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
/* $Xorg: lbxopts.c,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
 | 
						|
/*
 | 
						|
 * Copyright 1994 Network Computing Devices, Inc.
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and
 | 
						|
 * its documentation for any purpose is hereby granted without fee, provided
 | 
						|
 * that the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name Network Computing Devices, Inc. not be
 | 
						|
 * used in advertising or publicity pertaining to distribution of this
 | 
						|
 * software without specific, written prior permission.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED `AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
 | 
						|
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
 | 
						|
 * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 | 
						|
 * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
 | 
						|
 * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
 | 
						|
 * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
 | 
						|
 * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
 | 
						|
 * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
 | 
						|
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 */
 | 
						|
/* $XFree86: xc/programs/Xserver/lbx/lbxopts.c,v 1.6 2001/10/28 03:34:12 tsi Exp $ */
 | 
						|
 | 
						|
#ifdef OPTDEBUG
 | 
						|
#include <stdio.h>
 | 
						|
#endif
 | 
						|
#include "X.h"
 | 
						|
#include "Xproto.h"
 | 
						|
#include "misc.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "propertyst.h"
 | 
						|
#include "lbxserve.h"
 | 
						|
#include "lbxstr.h"
 | 
						|
#include "lbximage.h"
 | 
						|
#include "lbxopts.h"
 | 
						|
#include "lbxsrvopts.h"
 | 
						|
#ifndef NO_ZLIB
 | 
						|
#include "lbxzlib.h"
 | 
						|
#endif /* NO_ZLIB */
 | 
						|
 | 
						|
static int LbxProxyDeltaOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
			      int optlen, unsigned char *preply );
 | 
						|
static int LbxServerDeltaOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
			       int optlen, unsigned char *preply );
 | 
						|
static int LbxDeltaOpt ( unsigned char *popt, int optlen, 
 | 
						|
			 unsigned char *preply, short *pn, short *pmaxlen );
 | 
						|
static int LbxStreamCompOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
			      int optlen, unsigned char *preply );
 | 
						|
static int ZlibParse ( LbxNegOptsPtr pno, unsigned char *popt, int optlen, 
 | 
						|
		       unsigned char *preply );
 | 
						|
static int LbxMessageCompOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
			       int optlen, unsigned char *preply );
 | 
						|
static int LbxUseTagsOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
				  int optlen, unsigned char *preply );
 | 
						|
static int LbxBitmapCompOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
				     int optlen, unsigned char *preply );
 | 
						|
static int LbxPixmapCompOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
				     int optlen, unsigned char *preply );
 | 
						|
static int MergeDepths ( int *depths, LbxPixmapCompMethod *method );
 | 
						|
static int LbxCmapAllOpt ( LbxNegOptsPtr pno, unsigned char *popt, 
 | 
						|
				  int optlen, unsigned char *preply );
 | 
						|
 | 
						|
/*
 | 
						|
 * List of LBX options we recognize and are willing to negotiate
 | 
						|
 */
 | 
						|
static struct _LbxOptionParser {
 | 
						|
    CARD8	optcode;
 | 
						|
    int		(*parser)(LbxNegOptsPtr, unsigned char *, 
 | 
						|
			  int, unsigned char *);
 | 
						|
} LbxOptions[] = {
 | 
						|
    { LBX_OPT_DELTA_PROXY, 	LbxProxyDeltaOpt },
 | 
						|
    { LBX_OPT_DELTA_SERVER,	LbxServerDeltaOpt },
 | 
						|
    { LBX_OPT_STREAM_COMP,	LbxStreamCompOpt },
 | 
						|
    { LBX_OPT_BITMAP_COMP,	LbxBitmapCompOpt },
 | 
						|
    { LBX_OPT_PIXMAP_COMP,	LbxPixmapCompOpt },
 | 
						|
    { LBX_OPT_MSG_COMP,		LbxMessageCompOpt },
 | 
						|
    { LBX_OPT_USE_TAGS,		LbxUseTagsOpt },
 | 
						|
    { LBX_OPT_CMAP_ALL,		LbxCmapAllOpt }
 | 
						|
};
 | 
						|
 | 
						|
#define LBX_N_OPTS	(sizeof(LbxOptions) / sizeof(struct _LbxOptionParser))
 | 
						|
 | 
						|
/*
 | 
						|
 * Set option defaults
 | 
						|
 */
 | 
						|
void
 | 
						|
LbxOptionInit(LbxNegOptsPtr pno)
 | 
						|
{
 | 
						|
    bzero(pno, sizeof(LbxNegOptsRec));
 | 
						|
    pno->proxyDeltaN = pno->serverDeltaN = LBX_OPT_DELTA_NCACHE_DFLT;
 | 
						|
    pno->proxyDeltaMaxLen = pno->serverDeltaMaxLen = LBX_OPT_DELTA_MSGLEN_DFLT;
 | 
						|
    pno->squish = TRUE;
 | 
						|
    pno->numBitmapCompMethods = 0;
 | 
						|
    pno->bitmapCompMethods = NULL;
 | 
						|
    pno->numPixmapCompMethods = 0;
 | 
						|
    pno->pixmapCompMethods = NULL;
 | 
						|
    pno->pixmapCompDepths = NULL;
 | 
						|
    pno->useTags = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
LbxOptionParse(LbxNegOptsPtr  pno,
 | 
						|
	       unsigned char *popt,
 | 
						|
	       int	      optlen,
 | 
						|
	       unsigned char *preply)
 | 
						|
{
 | 
						|
    int		  i;
 | 
						|
    int		  nopts = *popt++;
 | 
						|
    unsigned char *pout = preply;
 | 
						|
 | 
						|
    for (i = 0; i < nopts; i++) {
 | 
						|
	int j;
 | 
						|
	int len;
 | 
						|
	int hdrlen;
 | 
						|
	int replylen;
 | 
						|
 | 
						|
	LBX_OPT_DECODE_LEN(popt + 1, len, hdrlen);
 | 
						|
	if (len < ++hdrlen || len > optlen) {
 | 
						|
#ifdef OPTDEBUG
 | 
						|
	    fprintf(stderr, "bad option length, len = %d, hdrlen = %d, optlen = %d\n", len, hdrlen, optlen);
 | 
						|
#endif
 | 
						|
	    return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	for (j = 0; j < LBX_N_OPTS; j++) {
 | 
						|
	    if (popt[0] == LbxOptions[j].optcode) {
 | 
						|
		replylen = (*LbxOptions[j].parser)(pno,
 | 
						|
						   popt + hdrlen,
 | 
						|
						   len - hdrlen,
 | 
						|
						   pout + LBX_OPT_SMALLHDR_LEN);
 | 
						|
		if (replylen < 0)
 | 
						|
		    return -1;
 | 
						|
		else if (replylen > 0) {
 | 
						|
		    /*
 | 
						|
		     * None of the current options require big headers,
 | 
						|
		     * so this works for now.
 | 
						|
		     */
 | 
						|
		    *pout++ = i;
 | 
						|
		    *pout++ = LBX_OPT_SMALLHDR_LEN + replylen;
 | 
						|
		    pout += replylen;
 | 
						|
		    pno->nopts++;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	optlen -= len;
 | 
						|
	popt += len;
 | 
						|
    }
 | 
						|
 | 
						|
    return (pout - preply);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxProxyDeltaOpt(LbxNegOptsPtr  pno,
 | 
						|
		 unsigned char *popt,
 | 
						|
		 int		optlen,
 | 
						|
		 unsigned char *preply)
 | 
						|
{
 | 
						|
    return LbxDeltaOpt(popt, optlen, preply,
 | 
						|
		       &pno->proxyDeltaN, &pno->proxyDeltaMaxLen);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxServerDeltaOpt(LbxNegOptsPtr  pno,
 | 
						|
		  unsigned char *popt,
 | 
						|
		  int		 optlen,
 | 
						|
		  unsigned char *preply)
 | 
						|
{
 | 
						|
    return LbxDeltaOpt(popt, optlen, preply,
 | 
						|
		       &pno->serverDeltaN, &pno->serverDeltaMaxLen);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxDeltaOpt(unsigned char *popt,
 | 
						|
	    int		   optlen,
 | 
						|
	    unsigned char *preply,
 | 
						|
	    short	  *pn,
 | 
						|
	    short	  *pmaxlen)
 | 
						|
{
 | 
						|
    short	  n;
 | 
						|
    short	  maxlen;
 | 
						|
 | 
						|
    /*
 | 
						|
     * If there's more data than we expect, we just ignore it.
 | 
						|
     */
 | 
						|
    if (optlen < LBX_OPT_DELTA_REQLEN) {
 | 
						|
#ifdef OPTDEBUG
 | 
						|
	fprintf(stderr, "bad delta option length = %d\n", optlen);
 | 
						|
#endif
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Accept whatever value the proxy prefers, so skip the
 | 
						|
     * min/max offerings.  Note that the max message len value is
 | 
						|
     * encoded as the number of 4-byte values.
 | 
						|
     */
 | 
						|
    popt += 2;
 | 
						|
    n = *popt++;
 | 
						|
    popt += 2;
 | 
						|
    maxlen = *popt++;
 | 
						|
    if ((maxlen <<= 2) == 0)
 | 
						|
	n = 0;
 | 
						|
    else if (maxlen < 32) {
 | 
						|
#ifdef OPTDEBUG
 | 
						|
	fprintf(stderr, "bad delta max msg length %d\n", maxlen);
 | 
						|
#endif
 | 
						|
	return -1;
 | 
						|
     }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Put the response in the reply buffer
 | 
						|
     */
 | 
						|
    *preply++ = n;
 | 
						|
    *preply++ = maxlen >> 2;
 | 
						|
 | 
						|
    *pn = n;
 | 
						|
    *pmaxlen = maxlen;
 | 
						|
 | 
						|
    return LBX_OPT_DELTA_REPLYLEN;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static struct _LbxStreamCompParser {
 | 
						|
    int		typelen;
 | 
						|
    char	*type;
 | 
						|
    int		(*parser)(LbxNegOptsPtr, unsigned char *, 
 | 
						|
			  int, unsigned char *);
 | 
						|
} LbxStreamComp[] = {
 | 
						|
#ifndef NO_ZLIB
 | 
						|
    { ZLIB_STRCOMP_OPT_LEN,	ZLIB_STRCOMP_OPT, 	ZlibParse },
 | 
						|
#endif /* NO_ZLIB */
 | 
						|
};
 | 
						|
 | 
						|
#define LBX_N_STRCOMP	\
 | 
						|
    (sizeof(LbxStreamComp) / sizeof(struct _LbxStreamCompParser))
 | 
						|
 | 
						|
static int
 | 
						|
LbxStreamCompOpt(LbxNegOptsPtr  pno,
 | 
						|
		 unsigned char *popt,
 | 
						|
		 int		optlen,
 | 
						|
		 unsigned char *preply)
 | 
						|
{
 | 
						|
    int		  i;
 | 
						|
    int		  typelen;
 | 
						|
    int		  nopts = *popt++;
 | 
						|
 | 
						|
    for (i = 0; i < nopts; i++) {
 | 
						|
	int j;
 | 
						|
	int len;
 | 
						|
	int lensize;
 | 
						|
	int replylen;
 | 
						|
 | 
						|
	typelen = popt[0];
 | 
						|
	for (j = 0; j < LBX_N_STRCOMP; j++) {
 | 
						|
	    if (typelen == LbxStreamComp[j].typelen &&
 | 
						|
		!strncmp((char *) popt + 1, LbxStreamComp[j].type, typelen))
 | 
						|
		break;
 | 
						|
	}
 | 
						|
 | 
						|
	popt += 1 + typelen;
 | 
						|
	optlen -= 1 + typelen;
 | 
						|
	LBX_OPT_DECODE_LEN(popt, len, lensize);
 | 
						|
 | 
						|
	if (j < LBX_N_STRCOMP) {
 | 
						|
	    if (len > optlen)
 | 
						|
		return -1;
 | 
						|
	    replylen = (*LbxStreamComp[j].parser)(pno,
 | 
						|
						  popt + lensize,
 | 
						|
						  len - lensize,
 | 
						|
						  preply + 1);
 | 
						|
	    if (replylen == -1)
 | 
						|
		return -1;
 | 
						|
	    else if (replylen >= 0) {
 | 
						|
		*preply = i;
 | 
						|
		return replylen + 1;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	optlen -= len;
 | 
						|
	popt += len;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
ZlibParse(LbxNegOptsPtr   pno,
 | 
						|
	  unsigned char  *popt,
 | 
						|
	  int		  optlen,
 | 
						|
	  unsigned char  *preply)
 | 
						|
{
 | 
						|
    int level;		/* compression level */
 | 
						|
 | 
						|
    if (*popt++ != 1)	/* length should be 1 */
 | 
						|
	return (-1);
 | 
						|
 | 
						|
    level = *popt;
 | 
						|
    if (level < 1 || level > 9)
 | 
						|
	return (-1);
 | 
						|
 | 
						|
    pno->streamOpts.streamCompInit =
 | 
						|
	(LbxStreamCompHandle (*)(int, pointer))ZlibInit;
 | 
						|
    pno->streamOpts.streamCompArg = (pointer)(long)level;
 | 
						|
    pno->streamOpts.streamCompStuffInput = ZlibStuffInput;
 | 
						|
    pno->streamOpts.streamCompInputAvail = ZlibInputAvail;
 | 
						|
    pno->streamOpts.streamCompFlush = ZlibFlush;
 | 
						|
    pno->streamOpts.streamCompRead = ZlibRead;
 | 
						|
    pno->streamOpts.streamCompWriteV = ZlibWriteV;
 | 
						|
    pno->streamOpts.streamCompOn = ZlibCompressOn;
 | 
						|
    pno->streamOpts.streamCompOff = ZlibCompressOff;
 | 
						|
    pno->streamOpts.streamCompFreeHandle =
 | 
						|
	(void (*)(LbxStreamCompHandle))ZlibFree;
 | 
						|
 | 
						|
    return (0);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxMessageCompOpt(LbxNegOptsPtr  pno,
 | 
						|
		  unsigned char *popt,
 | 
						|
		  int		 optlen,
 | 
						|
		  unsigned char *preply)
 | 
						|
{
 | 
						|
 | 
						|
    if (optlen == 0) {
 | 
						|
#ifdef OPTDEBUG
 | 
						|
	fprintf(stderr, "bad message-comp option length specified %d\n", optlen);
 | 
						|
#endif
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    pno->squish = *preply = *popt;
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
LbxUseTagsOpt(LbxNegOptsPtr  pno,
 | 
						|
	      unsigned char *popt,
 | 
						|
	      int 	     optlen,
 | 
						|
	      unsigned char *preply)
 | 
						|
{
 | 
						|
 | 
						|
    if (optlen == 0) {
 | 
						|
#ifdef OPTDEBUG
 | 
						|
	fprintf(stderr, "bad use-tags option length specified %d\n", optlen);
 | 
						|
#endif
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    pno->useTags = *preply = *popt;
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Option negotiation for image compression
 | 
						|
 */
 | 
						|
 | 
						|
LbxBitmapCompMethod
 | 
						|
LbxBitmapCompMethods [] = {
 | 
						|
  {
 | 
						|
    "XC-FaxG42D",		/* compression method name */
 | 
						|
    0,				/* inited */
 | 
						|
    2,				/* method opcode */
 | 
						|
    NULL,			/* init function */
 | 
						|
    LbxImageEncodeFaxG42D,	/* encode function */
 | 
						|
    LbxImageDecodeFaxG42D	/* decode function */
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_BITMAP_METHODS \
 | 
						|
	(sizeof (LbxBitmapCompMethods) / sizeof (LbxBitmapCompMethod))
 | 
						|
 | 
						|
 | 
						|
#if 1
 | 
						|
/*
 | 
						|
 * Currently, we don't support any pixmap compression algorithms
 | 
						|
 * because regular stream compression does much better than PackBits.
 | 
						|
 * If we want to plug in a better pixmap image compression algorithm,
 | 
						|
 * it would go here.
 | 
						|
 */
 | 
						|
 | 
						|
#define NUM_PIXMAP_METHODS 0
 | 
						|
LbxPixmapCompMethod LbxPixmapCompMethods [1]; /* dummy */
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
LbxPixmapCompMethod
 | 
						|
LbxPixmapCompMethods [] = {
 | 
						|
  {
 | 
						|
    "XC-PackBits",		/* compression method name */
 | 
						|
    1 << ZPixmap,		/* formats supported */
 | 
						|
    1, {8},			/* depths supported */
 | 
						|
    0,				/* inited */
 | 
						|
    1,				/* method opcode */
 | 
						|
    NULL,			/* init function */
 | 
						|
    LbxImageEncodePackBits,	/* encode function */
 | 
						|
    LbxImageDecodePackBits	/* decode function */
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
#define NUM_PIXMAP_METHODS \
 | 
						|
	(sizeof (LbxPixmapCompMethods) / sizeof (LbxPixmapCompMethod))
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
LbxImageCompOpt (Bool	         pixmap,
 | 
						|
		 LbxNegOptsPtr   pno,
 | 
						|
		 unsigned char  *popt,
 | 
						|
		 int	         optlen,
 | 
						|
		 unsigned char  *preply)
 | 
						|
 | 
						|
{
 | 
						|
    unsigned char *preplyStart = preply;
 | 
						|
    int numMethods = *popt++;
 | 
						|
    unsigned char *myIndices, *hisIndices;
 | 
						|
    unsigned int *retFormats = NULL;
 | 
						|
    int **retDepths = NULL;
 | 
						|
    int replyCount = 0;
 | 
						|
    int status, i, j;
 | 
						|
 | 
						|
    if (numMethods == 0)
 | 
						|
    {
 | 
						|
	if (pixmap)
 | 
						|
	    pno->numPixmapCompMethods = 0;
 | 
						|
	else
 | 
						|
	    pno->numBitmapCompMethods = 0;
 | 
						|
 | 
						|
	*preply++ = 0;
 | 
						|
	return (1);
 | 
						|
    }
 | 
						|
 | 
						|
    myIndices = (unsigned char *) xalloc (numMethods);
 | 
						|
    hisIndices = (unsigned char *) xalloc (numMethods);
 | 
						|
 | 
						|
    if (!myIndices || !hisIndices)
 | 
						|
    {
 | 
						|
	if (myIndices)
 | 
						|
	    xfree (myIndices);
 | 
						|
	if (hisIndices)
 | 
						|
	    xfree (hisIndices);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pixmap)
 | 
						|
    {
 | 
						|
	retFormats = (unsigned *) xalloc (numMethods);
 | 
						|
	retDepths = (int **) xalloc (numMethods * sizeof (int *));
 | 
						|
 | 
						|
	if (!retFormats || !retDepths)
 | 
						|
	{
 | 
						|
	    if (retFormats)
 | 
						|
		xfree (retFormats);
 | 
						|
	    if (retDepths)
 | 
						|
		xfree (retDepths);
 | 
						|
	    xfree (myIndices);
 | 
						|
	    xfree (hisIndices);
 | 
						|
	    return -1;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * For each method in the list sent by the proxy, see if the server
 | 
						|
     * supports this method.  If YES, update the following lists:
 | 
						|
     *
 | 
						|
     * myIndices[] is a list of indices into the server's
 | 
						|
     * LbxBit[Pix]mapCompMethods table.
 | 
						|
     *
 | 
						|
     * hisIndices[] is a list of indices into the list of
 | 
						|
     * method names sent by the proxy.
 | 
						|
     *
 | 
						|
     * retFormats[] indicates for each pixmap compression method,
 | 
						|
     * the pixmap formats supported.
 | 
						|
     *
 | 
						|
     * retDepths[] indicates for each pixmap compression method,
 | 
						|
     * the pixmap depths supported.
 | 
						|
     */
 | 
						|
 | 
						|
    for (i = 0; i < numMethods; i++)
 | 
						|
    {
 | 
						|
	unsigned int formatMask = 0, newFormatMask = 0;
 | 
						|
	int depthCount, *depths = NULL, len;
 | 
						|
	int freeDepths;
 | 
						|
	char *methodName;
 | 
						|
 | 
						|
	freeDepths = 0;
 | 
						|
	len = *popt++;
 | 
						|
	methodName = (char *) popt;
 | 
						|
	popt += len;
 | 
						|
 | 
						|
	if (pixmap)
 | 
						|
	{
 | 
						|
	    formatMask = *popt++;
 | 
						|
	    depthCount = *popt++;
 | 
						|
	    depths = (int *) xalloc ((depthCount + 1) * sizeof (int));
 | 
						|
	    freeDepths = 1;
 | 
						|
	    depths[0] = depthCount;
 | 
						|
	    for (j = 1; j <= depthCount; j++)
 | 
						|
		depths[j] = *popt++;
 | 
						|
	}
 | 
						|
 | 
						|
	for (j = 0;
 | 
						|
	    j < (pixmap ? NUM_PIXMAP_METHODS : NUM_BITMAP_METHODS); j++)
 | 
						|
	{
 | 
						|
 | 
						|
	    status = strncmp (methodName,
 | 
						|
		(pixmap ? LbxPixmapCompMethods[j].methodName :
 | 
						|
		          LbxBitmapCompMethods[j].methodName),
 | 
						|
		len);
 | 
						|
 | 
						|
	    if (status == 0 && pixmap)
 | 
						|
	    {
 | 
						|
		newFormatMask =
 | 
						|
		    formatMask & LbxPixmapCompMethods[j].formatMask;
 | 
						|
 | 
						|
		depthCount = MergeDepths (depths, &LbxPixmapCompMethods[j]);
 | 
						|
		
 | 
						|
		if (newFormatMask == 0 || depthCount == 0)
 | 
						|
		    status = 1;
 | 
						|
	    }
 | 
						|
 | 
						|
	    if (status == 0)
 | 
						|
	    {
 | 
						|
		myIndices[replyCount] = j;
 | 
						|
		hisIndices[replyCount] = i;
 | 
						|
 | 
						|
		if (pixmap)
 | 
						|
		{
 | 
						|
		    retFormats[replyCount] = newFormatMask;
 | 
						|
		    retDepths[replyCount] = depths;
 | 
						|
		    freeDepths = 0;
 | 
						|
		}
 | 
						|
 | 
						|
		replyCount++;
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	if (freeDepths)
 | 
						|
	    xfree (depths);
 | 
						|
    }
 | 
						|
 | 
						|
    *preply++ = replyCount;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Sort the lists by LBX server preference (increasing myIndices[] vals)
 | 
						|
     */
 | 
						|
 | 
						|
    for (i = 0; i <= replyCount - 2; i++)
 | 
						|
	for (j = replyCount - 1; j >= i; j--)
 | 
						|
	    if (myIndices[j - 1] > myIndices[j])
 | 
						|
	    {
 | 
						|
		char temp1 = myIndices[j - 1];
 | 
						|
		char temp2 = hisIndices[j - 1];
 | 
						|
 | 
						|
		myIndices[j - 1] = myIndices[j];
 | 
						|
		myIndices[j] = temp1;
 | 
						|
 | 
						|
		hisIndices[j - 1] = hisIndices[j];
 | 
						|
		hisIndices[j] = temp2;
 | 
						|
 | 
						|
		if (pixmap)
 | 
						|
		{
 | 
						|
		    unsigned temp3 = retFormats[j - 1];
 | 
						|
		    int *temp4 = retDepths[j - 1];
 | 
						|
 | 
						|
		    retFormats[j - 1] = retFormats[j];
 | 
						|
		    retFormats[j] = temp3;
 | 
						|
 | 
						|
		    retDepths[j - 1] = retDepths[j];
 | 
						|
		    retDepths[j] = temp4;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * For each method supported, return to the proxy an index into
 | 
						|
     * the list sent by the proxy, the opcode to be used for the method,
 | 
						|
     * the pixmap formats supported, and the list of depths supported.
 | 
						|
     */
 | 
						|
 | 
						|
    for (i = 0; i < replyCount; i++)
 | 
						|
    {
 | 
						|
	*preply++ = hisIndices[i];
 | 
						|
 | 
						|
	if (pixmap)
 | 
						|
	{
 | 
						|
	    int left;
 | 
						|
	    *preply++ = LbxPixmapCompMethods[myIndices[i]].methodOpCode;
 | 
						|
	    *preply++ = retFormats[i];
 | 
						|
	    *preply++ = left = retDepths[i][0];
 | 
						|
	    j = 1;
 | 
						|
	    while (left > 0)
 | 
						|
	    {
 | 
						|
		*preply++ = retDepths[i][j];
 | 
						|
		left--;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    *preply++ = LbxBitmapCompMethods[myIndices[i]].methodOpCode;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (pixmap)
 | 
						|
    {
 | 
						|
	pno->numPixmapCompMethods = replyCount;
 | 
						|
	pno->pixmapCompMethods = myIndices;
 | 
						|
	pno->pixmapCompDepths = retDepths;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	pno->numBitmapCompMethods = replyCount;
 | 
						|
	pno->bitmapCompMethods = myIndices;
 | 
						|
    }
 | 
						|
 | 
						|
    if (hisIndices)
 | 
						|
	xfree (hisIndices);
 | 
						|
 | 
						|
    if (pixmap)
 | 
						|
    {
 | 
						|
	if (retFormats)
 | 
						|
	    xfree (retFormats);
 | 
						|
    }
 | 
						|
 | 
						|
    return (preply - preplyStart);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
LbxBitmapCompOpt (LbxNegOptsPtr   pno,
 | 
						|
		  unsigned char  *popt,
 | 
						|
		  int	          optlen,
 | 
						|
		  unsigned char  *preply)
 | 
						|
 | 
						|
{
 | 
						|
    return (LbxImageCompOpt (0 /* bitmap */, pno, popt, optlen, preply));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
LbxPixmapCompOpt (LbxNegOptsPtr   pno,
 | 
						|
		  unsigned char  *popt,
 | 
						|
		  int	          optlen,
 | 
						|
		  unsigned char  *preply)
 | 
						|
 | 
						|
{
 | 
						|
    return (LbxImageCompOpt (1 /* Pixmap */, pno, popt, optlen, preply));
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
LbxBitmapCompMethod *
 | 
						|
LbxSrvrLookupBitmapCompMethod (LbxProxyPtr proxy,
 | 
						|
			       int methodOpCode)
 | 
						|
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < proxy->numBitmapCompMethods; i++)
 | 
						|
    {
 | 
						|
	LbxBitmapCompMethod *method;
 | 
						|
 | 
						|
	method = &LbxBitmapCompMethods[proxy->bitmapCompMethods[i]];
 | 
						|
 | 
						|
	if (method->methodOpCode == methodOpCode)
 | 
						|
	    return (method);
 | 
						|
    }
 | 
						|
 | 
						|
    return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
LbxPixmapCompMethod *
 | 
						|
LbxSrvrLookupPixmapCompMethod (LbxProxyPtr proxy,
 | 
						|
			       int methodOpCode)
 | 
						|
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < proxy->numPixmapCompMethods; i++)
 | 
						|
    {
 | 
						|
	LbxPixmapCompMethod *method;
 | 
						|
 | 
						|
	method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
 | 
						|
 | 
						|
	if (method->methodOpCode == methodOpCode)
 | 
						|
	    return (method);
 | 
						|
    }
 | 
						|
 | 
						|
    return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
LbxBitmapCompMethod *
 | 
						|
LbxSrvrFindPreferredBitmapCompMethod (LbxProxyPtr proxy)
 | 
						|
 | 
						|
{
 | 
						|
    if (proxy->numBitmapCompMethods == 0)
 | 
						|
	return NULL;
 | 
						|
    else
 | 
						|
	return (&LbxBitmapCompMethods[proxy->bitmapCompMethods[0]]);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
LbxPixmapCompMethod *
 | 
						|
LbxSrvrFindPreferredPixmapCompMethod (LbxProxyPtr proxy,
 | 
						|
				      int format,
 | 
						|
				      int depth)
 | 
						|
 | 
						|
{
 | 
						|
    if (proxy->numPixmapCompMethods == 0)
 | 
						|
	return NULL;
 | 
						|
    else
 | 
						|
    {
 | 
						|
	LbxPixmapCompMethod *method;
 | 
						|
	int i, j;
 | 
						|
 | 
						|
	for (i = 0; i < proxy->numPixmapCompMethods; i++)
 | 
						|
	{
 | 
						|
	    method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
 | 
						|
 | 
						|
	    if ((method->formatMask & (1 << format)))
 | 
						|
	    {
 | 
						|
		int n = proxy->pixmapCompDepths[i][0];
 | 
						|
		j = 1;
 | 
						|
		while (n > 0)
 | 
						|
		{
 | 
						|
		    if (depth == proxy->pixmapCompDepths[i][j])
 | 
						|
			return method;
 | 
						|
		    else
 | 
						|
			n--;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	}
 | 
						|
 | 
						|
	return NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int 
 | 
						|
MergeDepths (int *depths,
 | 
						|
	     LbxPixmapCompMethod *method)
 | 
						|
 | 
						|
{
 | 
						|
    int i, j, count;
 | 
						|
    int temp[LBX_MAX_DEPTHS + 1];
 | 
						|
 | 
						|
    temp[0] = count = 0;
 | 
						|
 | 
						|
    for (i = 1; i <= depths[0]; i++)
 | 
						|
    {
 | 
						|
	for (j = 0; j < method->depthCount; j++)
 | 
						|
	    if (method->depths[j] == depths[i])
 | 
						|
	    {
 | 
						|
		temp[0]++;
 | 
						|
		temp[++count] = depths[i];
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
    }
 | 
						|
 | 
						|
    memcpy (depths, temp, (count + 1) * sizeof (int));
 | 
						|
 | 
						|
    return (count);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#define LbxCmapAllMethod "XC-CMAP"
 | 
						|
 | 
						|
static int
 | 
						|
LbxCmapAllOpt (LbxNegOptsPtr   pno,
 | 
						|
	       unsigned char  *popt,
 | 
						|
	       int	       optlen,
 | 
						|
	       unsigned char  *preply)
 | 
						|
 | 
						|
{
 | 
						|
    int numMethods = *popt++;
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = 0; i < numMethods; i++)
 | 
						|
    {
 | 
						|
	int len;
 | 
						|
	char *methodName;
 | 
						|
 | 
						|
	len = *popt++;
 | 
						|
	methodName = (char *) popt;
 | 
						|
	popt += len;
 | 
						|
	if (!strncmp(methodName, LbxCmapAllMethod, len))
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
    if (i >= numMethods)
 | 
						|
	i = 0; /* assume first one is proxy's favorite */
 | 
						|
    *preply = i;
 | 
						|
    return 1;
 | 
						|
}
 |