855 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			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);
 | 
						|
}
 |