(file) Return to lbxopts.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / lbx

File: [XFree86 CVS] / xc / programs / Xserver / lbx / lbxopts.c (download)
Revision: 1.6, Sun Oct 28 03:34:12 2001 UTC (11 years, 6 months ago) by tsi
Branch: MAIN
CVS Tags: xf-4_5_99_9, xf-4_5_99_8, xf-4_5_99_7, xf-4_5_99_6, xf-4_5_99_5, xf-4_5_99_4, xf-4_5_99_3, xf-4_5_99_2, xf-4_5_99_13, xf-4_5_99_12, xf-4_5_99_11, xf-4_5_99_10, xf-4_5_99_1, xf-4_5_0, xf-4_5-branch, xf-4_4_99_903, xf-4_4_99_902, xf-4_4_99_901, xf-4_4_99_9, xf-4_4_99_8, xf-4_4_99_7, xf-4_4_99_6, xf-4_4_99_5, xf-4_4_99_4, xf-4_4_99_3, xf-4_4_99_22, xf-4_4_99_21, xf-4_4_99_20, xf-4_4_99_2, xf-4_4_99_19, xf-4_4_99_18, xf-4_4_99_17, xf-4_4_99_16, xf-4_4_99_15, xf-4_4_99_14, xf-4_4_99_13, xf-4_4_99_12, xf-4_4_99_11, xf-4_4_99_10, xf-4_4_99_1, xf-4_4_0, xf-4_4-branch, xf-4_3_99_903, xf-4_3_99_902, xf-4_3_99_901, xf-4_3_99_9, xf-4_3_99_8, xf-4_3_99_7, xf-4_3_99_6, xf-4_3_99_5, xf-4_3_99_4, xf-4_3_99_3, xf-4_3_99_2, xf-4_3_99_16, xf-4_3_99_15, xf-4_3_99_14, xf-4_3_99_13, xf-4_3_99_12, xf-4_3_99_11, xf-4_3_99_10, xf-4_3_99_1, xf-4_3_0_2, xf-4_3_0_1, xf-4_3_0, xf-4_3-branch, xf-4_2_99_902, xf-4_2_99_901, xf-4_2_99_4, xf-4_2_99_3, xf-4_2_99_2, xf-4_2_99_1, xf-4_2_1_2, xf-4_2_1_1, xf-4_2_1, xf-4_2_0_1, xf-4_2_0-bindist-1, xf-4_2_0-bindist, xf-4_2_0, xf-4_2-branch, xf-4_1_99_7, xf-4_1_99_6, xf-4_1_99_5, xf-4_1_99_4, xf-4_1_99_3, xf-4_1_99_2, Domain-branch
Changes since 1.5: +5 -5 lines
 407. Fix for threaded libraries (Marc La France).
 406. Finish removal of SuperProbe (Marc La France).
 405. A rather large number of warning fixes throughout (Marc La France).
 404. Fix bug in HTML install script (Marc La France).
 403. Missing ident lines for some XFree86-modified files (Marc La France).
 402. Add default half-width doublescanned modes (Marc La France).
 401. Mark all driver-registered resources with ResBus (Maarc La France).
 400. Fix DPMS-related build problem (Marc La France).
 399. Log a message just before calling each ChipProbe() during '-probe'
      processing (Marc La France).
 398. Temporarily disable ISA probing on SPARCs and PowerPCs (Marc La France).
 397. Add PCI IDs for Sun hardware (Marc La France).
 396. Fix memory leak in resource relocation (Marc La France).
 395. Do not relocate resources that only conflict with disabled non-video PCI
      devices or disabled PCI ROMs (Marc La France).
 394. Re-organise SBUS code (Marc La France).
 393. Add as-yet-unused definitions for PCI resource types other than I/O and
      memory (Marc La France).
 392. Add doc for Solaris, but don't format it yet (Marc La France).
 391. Normalise driver names (Marc La France).
 390. For SPARCs, disable DGA support in ATI driver (Marc La France).
 389. Clean up some debugging messages (Marc La France).
 388. Fix newport driver for when a /proc fs isn't mounted (Marc La France).
 387. Fix DAC handling bugs in s3 driver (Marc La France).
 386. Fix resource registration bug for PCI Tseng's (Marc La France).
 385. Add aperture driver for Solaris (not yet used) (Marc La France).
 384. Rework scanpci to fix problems that prevented it from completely
      displaying non-PCI bridges and Simba bridges (Marc La France).
 383. Fix build problems in some input drivers (Marc La France).
 382. Fix int10 compile problem for SPARCs and PowerPCs (Marc La France).
 381. Ensure master aborts on secondary buses complete normally during PCI
      scans (Marc La France).
 380. Some memory mapping and Solaris cleanups (Marc La France).

/* $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.5 2001/01/17 22:37:00 dawes 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;
}

Powered by
ViewCVS 0.9.2