2003-11-14 16:54:54 +01:00
|
|
|
/* $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.
|
|
|
|
*
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
/* $XFree86: xc/programs/Xserver/lbx/lbxopts.c,v 1.6 2001/10/28 03:34:12 tsi Exp $ */
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
#ifdef OPTDEBUG
|
|
|
|
#include <stdio.h>
|
|
|
|
#endif
|
|
|
|
#include "X.h"
|
|
|
|
#include "Xproto.h"
|
|
|
|
#include "misc.h"
|
2003-11-14 17:49:22 +01:00
|
|
|
#include "colormapst.h"
|
|
|
|
#include "propertyst.h"
|
2003-11-14 16:54:54 +01:00
|
|
|
#include "lbxserve.h"
|
|
|
|
#include "lbxstr.h"
|
|
|
|
#include "lbximage.h"
|
|
|
|
#include "lbxopts.h"
|
|
|
|
#include "lbxsrvopts.h"
|
|
|
|
#ifndef NO_ZLIB
|
|
|
|
#include "lbxzlib.h"
|
|
|
|
#endif /* NO_ZLIB */
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
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 );
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* List of LBX options we recognize and are willing to negotiate
|
|
|
|
*/
|
|
|
|
static struct _LbxOptionParser {
|
|
|
|
CARD8 optcode;
|
2003-11-14 17:49:22 +01:00
|
|
|
int (*parser)(LbxNegOptsPtr, unsigned char *,
|
|
|
|
int, unsigned char *);
|
2003-11-14 16:54:54 +01:00
|
|
|
} 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
|
|
|
|
*/
|
2003-11-14 17:49:22 +01:00
|
|
|
void
|
|
|
|
LbxOptionInit(LbxNegOptsPtr pno)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxOptionParse(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxProxyDeltaOpt(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
return LbxDeltaOpt(popt, optlen, preply,
|
|
|
|
&pno->proxyDeltaN, &pno->proxyDeltaMaxLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxServerDeltaOpt(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
return LbxDeltaOpt(popt, optlen, preply,
|
|
|
|
&pno->serverDeltaN, &pno->serverDeltaMaxLen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxDeltaOpt(unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply,
|
|
|
|
short *pn,
|
|
|
|
short *pmaxlen)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
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;
|
2003-11-14 17:49:22 +01:00
|
|
|
int (*parser)(LbxNegOptsPtr, unsigned char *,
|
|
|
|
int, unsigned char *);
|
2003-11-14 16:54:54 +01:00
|
|
|
} 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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxStreamCompOpt(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
ZlibParse(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
int level; /* compression level */
|
|
|
|
|
|
|
|
if (*popt++ != 1) /* length should be 1 */
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
level = *popt;
|
|
|
|
if (level < 1 || level > 9)
|
|
|
|
return (-1);
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
pno->streamOpts.streamCompInit =
|
|
|
|
(LbxStreamCompHandle (*)(int, pointer))ZlibInit;
|
|
|
|
pno->streamOpts.streamCompArg = (pointer)(long)level;
|
2003-11-14 16:54:54 +01:00
|
|
|
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;
|
2003-11-14 17:49:22 +01:00
|
|
|
pno->streamOpts.streamCompFreeHandle =
|
|
|
|
(void (*)(LbxStreamCompHandle))ZlibFree;
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxMessageCompOpt(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxUseTagsOpt(LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxImageCompOpt (Bool pixmap,
|
|
|
|
LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
unsigned char *preplyStart = preply;
|
|
|
|
int numMethods = *popt++;
|
2003-11-14 17:49:22 +01:00
|
|
|
unsigned char *myIndices, *hisIndices;
|
|
|
|
unsigned int *retFormats = NULL;
|
|
|
|
int **retDepths = NULL;
|
2003-11-14 16:54:54 +01:00
|
|
|
int replyCount = 0;
|
|
|
|
int status, i, j;
|
|
|
|
|
|
|
|
if (numMethods == 0)
|
|
|
|
{
|
|
|
|
if (pixmap)
|
|
|
|
pno->numPixmapCompMethods = 0;
|
|
|
|
else
|
|
|
|
pno->numBitmapCompMethods = 0;
|
|
|
|
|
|
|
|
*preply++ = 0;
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
myIndices = (unsigned char *) xalloc (numMethods);
|
|
|
|
hisIndices = (unsigned char *) xalloc (numMethods);
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
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++)
|
|
|
|
{
|
2003-11-14 17:49:22 +01:00
|
|
|
unsigned int formatMask = 0, newFormatMask = 0;
|
|
|
|
int depthCount, *depths = NULL, len;
|
2003-11-14 16:54:54 +01:00
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxBitmapCompOpt (LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
return (LbxImageCompOpt (0 /* bitmap */, pno, popt, optlen, preply));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxPixmapCompOpt (LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
return (LbxImageCompOpt (1 /* Pixmap */, pno, popt, optlen, preply));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LbxBitmapCompMethod *
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxSrvrLookupBitmapCompMethod (LbxProxyPtr proxy,
|
|
|
|
int methodOpCode)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
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 *
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxSrvrLookupPixmapCompMethod (LbxProxyPtr proxy,
|
|
|
|
int methodOpCode)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
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 *
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxSrvrFindPreferredBitmapCompMethod (LbxProxyPtr proxy)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
if (proxy->numBitmapCompMethods == 0)
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return (&LbxBitmapCompMethods[proxy->bitmapCompMethods[0]]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LbxPixmapCompMethod *
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxSrvrFindPreferredPixmapCompMethod (LbxProxyPtr proxy,
|
|
|
|
int format,
|
|
|
|
int depth)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-14 17:49:22 +01:00
|
|
|
static int
|
|
|
|
MergeDepths (int *depths,
|
|
|
|
LbxPixmapCompMethod *method)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
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
|
2003-11-14 17:49:22 +01:00
|
|
|
LbxCmapAllOpt (LbxNegOptsPtr pno,
|
|
|
|
unsigned char *popt,
|
|
|
|
int optlen,
|
|
|
|
unsigned char *preply)
|
2003-11-14 16:54:54 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|