xserver-multidpi/lbx/lbxgfx.c

855 lines
21 KiB
C

/* $Xorg: lbxgfx.c,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
/*
* Copyright 1993 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/lbxgfx.c,v 1.3 2001/01/17 22:36:59 dawes Exp $ */
/* various bits of DIX-level mangling */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#define NEED_REPLIES
#define NEED_EVENTS
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "servermd.h"
#include "windowstr.h"
#include "scrnintstr.h"
#define _XLBX_SERVER_
#include <X11/extensions/lbxstr.h>
#include "lbxserve.h"
#include "lbxtags.h"
#include <X11/Xfuncproto.h>
#include <X11/extensions/lbximage.h>
#include "lbxsrvopts.h"
#define DrawableCache(client) (LbxClient(client)->drawableCache)
#define GContextCache(client) (LbxClient(client)->gcontextCache)
static void
push (XID cache[GFX_CACHE_SIZE],
XID xid)
{
memmove (cache+1, cache, (GFX_CACHE_SIZE - 1) * sizeof (cache[0]));
cache[0] = xid;
}
static XID
use (XID cache[GFX_CACHE_SIZE],
int i)
{
XID tmp;
tmp = cache[i];
if (i != 0)
{
memmove (cache + 1, cache, i * sizeof (cache[0]));
cache[0] = tmp;
}
return tmp;
}
extern char *ConnectionInfo;
static int
LbxDecodeGFXCache(ClientPtr client,
CARD8 cacheEnts,
char *after,
Drawable *drawp,
GContext *gcp)
{
int skip;
int dcache, gcache;
dcache = GFXdCacheEnt (cacheEnts);
gcache = GFXgCacheEnt (cacheEnts);
skip = 0;
if (dcache == GFXCacheNone)
{
memcpy (drawp, after, sizeof (Drawable));
push (DrawableCache(client), *drawp);
after += sizeof (Drawable);
skip += sizeof (Drawable);
}
else
*drawp = use (DrawableCache(client), dcache);
if (gcache == GFXCacheNone)
{
memcpy (gcp, after, sizeof (GContext));
push (GContextCache(client), *gcp);
skip += sizeof (GContext);
}
else
*gcp = use (GContextCache(client), gcache);
return skip;
}
static int
LbxDecodeDrawableCache(ClientPtr client,
CARD8 cacheEnts,
char *after,
Drawable *drawp)
{
int skip;
int dcache;
dcache = GFXdCacheEnt (cacheEnts);
skip = 0;
if (dcache == GFXCacheNone)
{
memcpy (drawp, after, sizeof (Drawable));
push (DrawableCache(client), *drawp);
after += sizeof (Drawable);
skip += sizeof (Drawable);
}
else
*drawp = use (DrawableCache(client), dcache);
return skip;
}
#ifdef notyet
static int
LbxDecodeGCCache(ClientPtr client,
CARD8 cacheEnts,
char *after,
GContext *gcp)
{
int skip;
int gcache;
gcache = GFXgCacheEnt (cacheEnts);
skip = 0;
if (gcache == GFXCacheNone)
{
memcpy (gcp, after, sizeof (GContext));
push (GContextCache(client), *gcp);
after += sizeof (GContext);
skip += sizeof (GContext);
}
else
*gcp = use (GContextCache(client), gcache);
return skip;
}
#endif
#define GFX_GET_DRAWABLE_AND_GC(type,in,len) {\
int skip; \
len = (client->req_len << 2) - SIZEOF(type); \
in = ((char *) stuff) + SIZEOF(type);\
skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
&drawable, &gc); \
in += skip; \
len -= skip; \
}
#define GFX_GET_DST_DRAWABLE_AND_GC(type,in,len) {\
int skip; \
len = (client->req_len << 2) - SIZEOF(type); \
in = ((char *) stuff) + SIZEOF(type);\
skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
&dstDrawable, &gc); \
in += skip; \
len -= skip; \
}
#define GFX_GET_SRC_DST_DRAWABLE_AND_GC(type, in, len) { \
int skip; \
len = (client->req_len << 2) - SIZEOF(type); \
in = ((char *) stuff) + SIZEOF(type); \
skip = LbxDecodeDrawableCache(client, stuff->srcCache, in, \
&srcDrawable); \
in += skip; \
len -= skip; \
skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
&dstDrawable, &gc); \
in += skip; \
len -= skip; \
}
#define GFX_GET_GC(type, in, len) { \
int skip; \
len = (client->req_len << 2) - SIZEOF(type); \
in = ((char *) stuff) + SIZEOF(type); \
skip = LbxDecodeGCCache(client, stuff->gcCache, in, &gc); \
in += skip; \
len -= skip; \
}
int
LbxDecodePoly(ClientPtr client,
CARD8 xreqtype,
int (*decode_rtn)(char *, char *, short *))
{
REQUEST(xLbxPolyPointReq);
char *in;
xPolyPointReq *xreq;
int len;
int retval;
Drawable drawable;
GContext gc;
GFX_GET_DRAWABLE_AND_GC(xLbxPolyPointReq, in, len);
if ((xreq = (xPolyPointReq *)
xalloc(sizeof(xPolyPointReq) + (len << 1))) == NULL)
return BadAlloc;
len = (*decode_rtn)(in, in + len - stuff->padBytes, (short *)(&xreq[1]));
xreq->reqType = xreqtype;
xreq->coordMode = 1;
xreq->drawable = drawable;
xreq->gc = gc;
xreq->length = client->req_len = (sizeof(xPolyPointReq) + len) >> 2;
client->requestBuffer = (pointer)xreq;
retval = (*ProcVector[xreqtype])(client);
xfree(xreq);
return retval;
}
int
LbxDecodeFillPoly(ClientPtr client)
{
REQUEST(xLbxFillPolyReq);
char *in;
xFillPolyReq *xreq;
int len;
int retval;
Drawable drawable;
GContext gc;
GFX_GET_DRAWABLE_AND_GC(xLbxFillPolyReq, in, len);
if ((xreq = (xFillPolyReq *)
xalloc(sizeof(xFillPolyReq) + (len << 1))) == NULL)
return BadAlloc;
len = LbxDecodePoints(in, in + len - stuff->padBytes, (short *) &xreq[1]);
xreq->reqType = X_FillPoly;
xreq->drawable = drawable;
xreq->gc = gc;
xreq->shape = stuff->shape;
xreq->coordMode = 1;
xreq->length = client->req_len = (sizeof(xFillPolyReq) + len) >> 2;
client->requestBuffer = (pointer)xreq;
retval = (*ProcVector[X_FillPoly])(client);
xfree(xreq);
return retval;
}
/*
* Routines for decoding line drawing requests
*/
#define DECODE_PSHORT(in, val) \
if ((*(in) & 0xf0) != 0xf0) \
(val) = *(CARD8 *)(in)++; \
else { \
(val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
if ((val) >= 0xe00) \
(val) -= 0x1000; \
else \
(val) += 0xf0; \
(in) += 2; \
}
#define DECODE_SHORT(in, val) \
if ((*(in) & 0xf0) != 0x80) \
(val) = *(INT8 *)(in)++; \
else { \
(val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
if ((val) & 0x0800) \
(val) = ((val) | 0xf000) - 0x70; \
else \
(val) += 0x80; \
(in) += 2; \
}
#define DECODE_USHORT(in, val) \
if ((*(in) & 0xf0) != 0xf0) \
(val) = *(CARD8 *)(in)++; \
else { \
(val) = (((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1)) + 0xf0; \
(in) += 2; \
}
#define DECODE_ANGLE(in, val) \
if (*(INT8 *)(in) >= 0x6e) \
(val) = (*(INT8 *)(in)++ - 0x67) * (15 << 6); \
else if (*(INT8 *)(in) >= 0x5a) \
(val) = (*(INT8 *)(in)++ - 0x5a) * (5 << 6); \
else if (*(INT8 *)(in) <= (INT8)0x91) \
(val) = (*(INT8 *)(in)++ - (INT8)0x98) * (15 << 6); \
else if (*(INT8 *)(in) <= (INT8)0xa5) \
(val) = (*(INT8 *)(in)++ - (INT8)0xa6) * (5 << 6); \
else { \
(val) = (*(CARD8 *)(in) << 8) | *(CARD8 *)((in) + 1); \
(in) += 2; \
}
int
LbxDecodePoints(char *in,
char *inend,
short *out)
{
char *start_out = (char *)out;
while (in < inend) {
DECODE_SHORT(in, *out);
out++;
DECODE_SHORT(in, *out);
out++;
}
return ((char *)out - start_out);
}
int
LbxDecodeSegment(char *in,
char *inend,
short *out)
{
short diff;
short last_x = 0;
short last_y = 0;
char *start_out = (char *)out;
while (in < inend) {
DECODE_SHORT(in, diff);
*out = last_x + diff;
last_x += diff;
out++;
DECODE_SHORT(in, diff);
*out = last_y + diff;
last_y += diff;
out++;
DECODE_SHORT(in, diff);
*out = last_x + diff;
out++;
DECODE_SHORT(in, diff);
*out = last_y + diff;
out++;
}
return ((char *)out - start_out);
}
int
LbxDecodeRectangle(char *in,
char *inend,
short *out)
{
short diff;
short last_x = 0;
short last_y = 0;
char *start_out = (char *)out;
while (in < inend) {
DECODE_SHORT(in, diff);
*out = last_x + diff;
last_x += diff;
out++;
DECODE_SHORT(in, diff);
*out = last_y + diff;
last_y += diff;
out++;
DECODE_USHORT(in, *(unsigned short *)out);
out++;
DECODE_USHORT(in, *(unsigned short *)out);
out++;
}
return ((char *)out - start_out);
}
int
LbxDecodeArc(char *in,
char *inend,
short *out)
{
short diff;
short last_x = 0;
short last_y = 0;
char *start_out = (char *)out;
while (in < inend) {
DECODE_SHORT(in, diff);
*out = last_x + diff;
last_x += diff;
out++;
DECODE_SHORT(in, diff);
*out = last_y + diff;
last_y += diff;
out++;
DECODE_USHORT(in, *(unsigned short *)out);
out++;
DECODE_USHORT(in, *(unsigned short *)out);
out++;
DECODE_ANGLE(in, *out);
out++;
DECODE_ANGLE(in, *out);
out++;
}
return ((char *)out - start_out);
}
int
LbxDecodeCopyArea (ClientPtr client)
{
REQUEST(xLbxCopyAreaReq);
char *in;
xCopyAreaReq req;
int len;
Drawable srcDrawable, dstDrawable;
GContext gc;
GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyAreaReq, in, len);
req.reqType = X_CopyArea;
req.length = client->req_len = SIZEOF(xCopyAreaReq) >> 2;
req.srcDrawable = srcDrawable;
req.dstDrawable = dstDrawable;
req.gc = gc;
DECODE_PSHORT (in, req.srcX);
DECODE_PSHORT (in, req.srcY);
DECODE_PSHORT (in, req.dstX);
DECODE_PSHORT (in, req.dstY);
DECODE_USHORT (in, req.width);
DECODE_USHORT (in, req.height);
client->requestBuffer = (pointer) &req;
return (*ProcVector[X_CopyArea])(client);
}
int
LbxDecodeCopyPlane (ClientPtr client)
{
REQUEST(xLbxCopyPlaneReq);
char *in;
xCopyPlaneReq req;
int len;
Drawable srcDrawable, dstDrawable;
GContext gc;
GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyPlaneReq, in, len);
req.reqType = X_CopyPlane;
req.length = client->req_len = SIZEOF(xCopyPlaneReq) >> 2;
req.srcDrawable = srcDrawable;
req.dstDrawable = dstDrawable;
req.gc = gc;
DECODE_PSHORT (in, req.srcX);
DECODE_PSHORT (in, req.srcY);
DECODE_PSHORT (in, req.dstX);
DECODE_PSHORT (in, req.dstY);
DECODE_USHORT (in, req.width);
DECODE_USHORT (in, req.height);
req.bitPlane = stuff->bitPlane;
client->requestBuffer = (pointer) &req;
return (*ProcVector[X_CopyPlane])(client);
}
static pointer
get_gfx_buffer(ClientPtr client,
int len)
{
LbxClientPtr lbxClient = LbxClient(client);
pointer tmp;
/* XXX should probably shrink this sucker too */
if (len > lbxClient->gb_size) {
tmp = (pointer) xrealloc(lbxClient->gfx_buffer, len);
if (!tmp)
return (pointer) NULL;
lbxClient->gfx_buffer = tmp;
lbxClient->gb_size = len;
}
return lbxClient->gfx_buffer;
}
int
LbxDecodePolyText (ClientPtr client)
{
REQUEST(xLbxPolyTextReq);
char *in, *pos;
xPolyTextReq *xreq;
int len;
Drawable drawable;
GContext gc;
GFX_GET_DRAWABLE_AND_GC(xLbxPolyTextReq, in, len);
xreq = (xPolyTextReq *) get_gfx_buffer(client, sizeof (xPolyTextReq) + len);
if (!xreq)
return BadAlloc;
xreq->reqType = stuff->lbxReqType == X_LbxPolyText8? X_PolyText8 : X_PolyText16;
xreq->drawable = drawable;
xreq->gc = gc;
pos = in;
DECODE_PSHORT(in, xreq->x);
DECODE_PSHORT(in, xreq->y);
len -= (in - pos);
memmove ((char *) (xreq + 1), in, len);
xreq->length = client->req_len = (sizeof (xPolyTextReq) + len) >> 2;
client->requestBuffer = (pointer) xreq;
return (*ProcVector[xreq->reqType])(client);
}
int
LbxDecodeImageText (ClientPtr client)
{
REQUEST(xLbxImageTextReq);
char *in, *pos;
xImageTextReq *xreq;
int len;
Drawable drawable;
GContext gc;
GFX_GET_DRAWABLE_AND_GC(xLbxImageTextReq, in, len);
xreq = (xImageTextReq *) get_gfx_buffer(client, sizeof (xImageTextReq) + len);
if (!xreq)
return BadAlloc;
xreq->reqType = stuff->lbxReqType == X_LbxImageText8? X_ImageText8 : X_ImageText16;
xreq->drawable = drawable;
xreq->gc = gc;
xreq->nChars = stuff->nChars;
pos = in;
DECODE_PSHORT(in, xreq->x);
DECODE_PSHORT(in, xreq->y);
len -= (in - pos);
memmove ((char *) (xreq + 1), in, len);
xreq->length = client->req_len = (sizeof (xImageTextReq) + len) >> 2;
client->requestBuffer = (pointer) xreq;
return (*ProcVector[xreq->reqType])(client);
}
int
LbxDecodePutImage (ClientPtr client)
{
REQUEST (xLbxPutImageReq);
char *in, *data;
xPutImageReq xreq;
int ppl, bpl, nbytes;
int retval;
int n;
xreq.reqType = X_PutImage;
in = (char *) stuff + sz_xLbxPutImageReq;
if (stuff->bitPacked & 0x80) {
xreq.format = (stuff->bitPacked >> 5) & 0x3;
xreq.depth = ((stuff->bitPacked >> 2) & 0x7) + 1;
xreq.leftPad = 0;
} else {
xreq.depth = (stuff->bitPacked >> 2) + 1;
xreq.format = (*in >> 5) & 0x3;
xreq.leftPad = *in++ & 0x1f;
}
DECODE_USHORT(in, xreq.width);
DECODE_USHORT(in, xreq.height);
DECODE_PSHORT(in, xreq.dstX);
DECODE_PSHORT(in, xreq.dstY);
if (client->swapped) {
if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone ||
GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
{
swapl (in, n);
if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone &&
GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
swapl (in + 4, n);
}
}
in += LbxDecodeGFXCache(client, stuff->cacheEnts, in,
&xreq.drawable, &xreq.gc);
ppl = xreq.width + xreq.leftPad;
if (xreq.format != ZPixmap ||
(xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1)) {
#ifdef INTERNAL_VS_EXTERNAL_PADDING
bpl = BitmapBytePadProto(ppl);
#else
bpl = BitmapBytePad(ppl);
#endif
nbytes = bpl;
if (xreq.format == XYPixmap)
nbytes *= xreq.depth;
} else {
#ifdef INTERNAL_VS_EXTERNAL_PADDING
bpl = PixmapBytePadProto(ppl, xreq.depth);
#else
bpl = PixmapBytePad(ppl, xreq.depth);
#endif
nbytes = bpl;
}
nbytes *= xreq.height;
xreq.length = ((nbytes + 3) >> 2) + (sz_xPutImageReq >> 2);
/* +1 is because fillspan in DecodeFaxG42D seems to go 1 byte too far,
* and I don't want to mess with that code */
if ((data = (char *) xalloc ((xreq.length << 2) + 1)) == NULL)
return BadAlloc;
*((xPutImageReq *)data) = xreq;
if (!stuff->compressionMethod)
{
memcpy(data + sz_xPutImageReq, in, nbytes);
}
else if (xreq.format != ZPixmap ||
(xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1))
{
LbxBitmapCompMethod *compMethod;
compMethod = LbxSrvrLookupBitmapCompMethod (LbxProxy(client),
stuff->compressionMethod);
if (!compMethod)
{
xfree (data);
return (BadValue);
}
else
{
if (!compMethod->inited)
{
if (compMethod->compInit)
(*compMethod->compInit)();
compMethod->inited = 1;
}
(*compMethod->decompFunc) (
(unsigned char *) in, (unsigned char *) data + sz_xPutImageReq,
nbytes,
#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
(ppl + BITMAP_SCANLINE_UNIT - 1) & ~BITMAP_SCANLINE_UNIT,
#else
ppl,
#endif
bpl,
((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst);
}
}
else
{
LbxPixmapCompMethod *compMethod;
compMethod = LbxSrvrLookupPixmapCompMethod (LbxProxy(client),
stuff->compressionMethod);
if (!compMethod)
{
xfree (data);
return (BadValue);
}
else
{
if (!compMethod->inited)
{
if (compMethod->compInit)
(*compMethod->compInit)();
compMethod->inited = 1;
}
(*compMethod->decompFunc) (
in, (char *) data + sz_xPutImageReq,
(int) xreq.height, bpl);
}
}
client->req_len = xreq.length;
client->requestBuffer = (pointer) data;
retval = (*ProcVector[X_PutImage])(client);
xfree(data);
return retval;
}
int
LbxDecodeGetImage (ClientPtr client)
{
REQUEST (xLbxGetImageReq);
xLbxGetImageReply *reply = NULL;
int lbxLen, xLen, n;
int method = 0, bytes, status;
xGetImageReply *theImage;
REQUEST_SIZE_MATCH(xLbxGetImageReq);
status = DoGetImage(client, stuff->format, stuff->drawable,
stuff->x, stuff->y,
(int)stuff->width, (int)stuff->height,
stuff->planeMask, &theImage);
if (status != Success)
return (status);
if ((reply = (xLbxGetImageReply *) xalloc (
sz_xLbxGetImageReply + theImage->length)) == NULL)
{
xfree(theImage);
return (BadAlloc);
}
if (stuff->format != ZPixmap ||
(theImage->depth == 1 && screenInfo.formats->bitsPerPixel == 1))
{
LbxBitmapCompMethod *compMethod;
compMethod = LbxSrvrFindPreferredBitmapCompMethod (LbxProxy(client));
if (!compMethod)
status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
else
{
if (!compMethod->inited)
{
if (compMethod->compInit)
(*compMethod->compInit)();
compMethod->inited = 1;
}
status = (*compMethod->compFunc) (
(unsigned char *) &theImage[1],
(unsigned char *) &reply[1],
theImage->length,
theImage->length,
#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
(int) (stuff->width + BITMAP_SCANLINE_UNIT - 1) &
~BITMAP_SCANLINE_UNIT,
#else
(int) stuff->width,
#endif
#ifdef INTERNAL_VS_EXTERNAL_PADDING
BitmapBytePadProto(stuff->width),
#else
BitmapBytePad(stuff->width),
#endif
((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst,
&bytes);
method = compMethod->methodOpCode;
}
}
else
{
LbxPixmapCompMethod *compMethod;
compMethod = LbxSrvrFindPreferredPixmapCompMethod (
LbxProxy(client), (int) stuff->format, theImage->depth);
if (!compMethod)
status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
else
{
if (!compMethod->inited)
{
if (compMethod->compInit)
(*compMethod->compInit)();
compMethod->inited = 1;
}
status = (*compMethod->compFunc) (
(char *) &theImage[1],
(char *) &reply[1],
theImage->length,
(int) stuff->format,
theImage->depth,
(int) stuff->height,
#ifdef INTERNAL_VS_EXTERNAL_PADDING
PixmapBytePadProto(stuff->width, theImage->depth),
#else
PixmapBytePad(stuff->width, theImage->depth),
#endif
&bytes);
method = compMethod->methodOpCode;
}
}
reply->type = X_Reply;
reply->depth = theImage->depth;
reply->sequenceNumber = client->sequence;
reply->visual = theImage->visual;
reply->pad1 = reply->pad2 = reply->pad3 = reply->pad4 = reply->pad5 = 0;
if (status != LBX_IMAGE_COMPRESS_SUCCESS)
{
reply->compressionMethod = LbxImageCompressNone;
reply->lbxLength = reply->xLength = (theImage->length + 3) >> 2;
}
else
{
reply->compressionMethod = method;
reply->lbxLength = (bytes + 3) >> 2;
reply->xLength = (theImage->length + 3) >> 2;
}
lbxLen = reply->lbxLength;
xLen = reply->xLength;
if (client->swapped)
{
swaps (&reply->sequenceNumber, n);
swapl (&reply->lbxLength, n);
swapl (&reply->xLength, n);
swapl (&reply->visual, n);
}
if (reply->compressionMethod != LbxImageCompressNone)
{
/*
* If the compressed image is greater that 25% of the original
* image, run the GetImage reply through the regular stream
* compressor. Otherwise, just write the compressed image.
*/
if (lbxLen > (xLen / 4))
{
WriteToClient (client,
sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
}
else
{
UncompressedWriteToClient (client,
sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
}
}
else
{
/*
* Write back the original uncompressed image.
*/
WriteToClient (client, sz_xLbxGetImageReply, (char *)reply);
WriteToClient (client, lbxLen << 2, (char *)&theImage[1]);
}
xfree (theImage);
if (reply)
xfree ((char *) reply);
return (Success);
}