1761 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1761 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			C
		
	
	
	
/* $Xorg: lbxmain.c,v 1.4 2001/02/09 02:05:16 xorgcvs Exp $ */
 | 
						|
/*
 | 
						|
 | 
						|
Copyright 1996, 1998  The Open Group
 | 
						|
 | 
						|
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.
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
						|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | 
						|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
						|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of The Open Group shall not be
 | 
						|
used in advertising or otherwise to promote the sale, use or other dealings
 | 
						|
in this Software without prior written authorization from The Open Group.
 | 
						|
 | 
						|
*/
 | 
						|
/*
 | 
						|
 * Copyright 1992 Network Computing Devices
 | 
						|
 *
 | 
						|
 * 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 of NCD. not be used in advertising or
 | 
						|
 * publicity pertaining to distribution of the software without specific,
 | 
						|
 * written prior permission.  NCD. makes no representations about the
 | 
						|
 * suitability of this software for any purpose.  It is provided "as is"
 | 
						|
 * without express or implied warranty.
 | 
						|
 *
 | 
						|
 * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 | 
						|
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
 | 
						|
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
						|
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
						|
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
 | 
						|
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 */
 | 
						|
/* $XFree86: xc/programs/Xserver/lbx/lbxmain.c,v 1.12 2001/10/28 03:34:12 tsi Exp $ */
 | 
						|
 
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#define NEED_REPLIES
 | 
						|
#define NEED_EVENTS
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include <X11/Xos.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "os.h"
 | 
						|
#include "dixstruct.h"
 | 
						|
#include "resource.h"
 | 
						|
#include "scrnintstr.h"
 | 
						|
#include "windowstr.h"
 | 
						|
#include "pixmapstr.h"
 | 
						|
#include "gcstruct.h"
 | 
						|
#include "extnsionst.h"
 | 
						|
#include "servermd.h"
 | 
						|
#define _XLBX_SERVER_
 | 
						|
#include <X11/extensions/lbxstr.h>
 | 
						|
#include <X11/extensions/lbxdeltastr.h>
 | 
						|
#include "lbxserve.h"
 | 
						|
#include <X11/extensions/lbximage.h>
 | 
						|
#include "lbxsrvopts.h"
 | 
						|
#include "lbxtags.h"
 | 
						|
#include <X11/Xfuncproto.h>
 | 
						|
#include <errno.h>
 | 
						|
#ifndef Lynx
 | 
						|
#include <sys/uio.h>
 | 
						|
#else
 | 
						|
#include <uio.h>
 | 
						|
#endif
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#ifndef X_NOT_POSIX
 | 
						|
#include <unistd.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#define CloseLbxClient	0xff
 | 
						|
 | 
						|
#define MAXBYTESDIFF	8
 | 
						|
 | 
						|
int LbxWhoAmI = 1;		/*
 | 
						|
				 * for lbx zlib library to know who we are
 | 
						|
				 * server = 1
 | 
						|
				 * proxy = 0
 | 
						|
				 */
 | 
						|
 | 
						|
 | 
						|
static void LbxResetProc ( ExtensionEntry *extEntry );
 | 
						|
static void LbxFreeClient ( ClientPtr client );
 | 
						|
static void LbxShutdownProxy ( LbxProxyPtr proxy );
 | 
						|
static int DecodeLbxDelta ( ClientPtr client );
 | 
						|
 | 
						|
static LbxProxyPtr proxyList;
 | 
						|
unsigned char LbxReqCode;
 | 
						|
int 	LbxEventCode;
 | 
						|
static int BadLbxClientCode;
 | 
						|
static int	uid_seed;
 | 
						|
 | 
						|
static int	lbxCompressWorkProcCount;
 | 
						|
 | 
						|
LbxClientPtr	lbxClients[MAXCLIENTS];
 | 
						|
 | 
						|
extern xConnSetupPrefix connSetupPrefix;
 | 
						|
extern char *ConnectionInfo;
 | 
						|
extern int  (*LbxInitialVector[3])(ClientPtr);
 | 
						|
 | 
						|
#ifdef DEBUG
 | 
						|
int lbxDebug = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
LbxExtensionInit(void)
 | 
						|
{
 | 
						|
    ExtensionEntry *extEntry;
 | 
						|
 | 
						|
    lbxCompressWorkProcCount = 0;
 | 
						|
    proxyList = NULL;
 | 
						|
    uid_seed = 0;
 | 
						|
    if ((extEntry = AddExtension(LBXNAME, LbxNumberEvents, LbxNumberErrors,
 | 
						|
				 ProcLbxDispatch, SProcLbxDispatch,
 | 
						|
				 LbxResetProc, StandardMinorOpcode)))
 | 
						|
    {
 | 
						|
	LbxReqCode = (unsigned char)extEntry->base;
 | 
						|
	LbxEventCode = extEntry->eventBase;
 | 
						|
	BadLbxClientCode = extEntry->errorBase + BadLbxClient;
 | 
						|
        LbxDixInit();
 | 
						|
 | 
						|
	LbxCmapInit ();
 | 
						|
	DeclareExtensionSecurity(LBXNAME, TRUE); 
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static void
 | 
						|
LbxResetProc (ExtensionEntry	*extEntry)
 | 
						|
{
 | 
						|
   LbxResetTags();
 | 
						|
   uid_seed = 0;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
LbxCloseClient (ClientPtr	client)
 | 
						|
{
 | 
						|
    xLbxCloseEvent  closeEvent;
 | 
						|
    ClientPtr	    master;
 | 
						|
    LbxProxyPtr	    proxy;
 | 
						|
    LbxClientPtr    lbxClient = LbxClient(client);
 | 
						|
    CARD32	    id;
 | 
						|
 | 
						|
    if (!lbxClient)
 | 
						|
	return;
 | 
						|
    id = lbxClient->id;
 | 
						|
    proxy = lbxClient->proxy;
 | 
						|
 | 
						|
    DBG (DBG_CLIENT, (stderr, "Close client %d\n", client->index));
 | 
						|
    LbxFreeClient (client);
 | 
						|
    if (!id)
 | 
						|
    {
 | 
						|
	isItTimeToYield = TRUE;
 | 
						|
	CloseDownFileDescriptor (client);
 | 
						|
	LbxShutdownProxy (proxy);
 | 
						|
    } 
 | 
						|
    else
 | 
						|
    {
 | 
						|
	master = NULL;
 | 
						|
	if (proxy->lbxClients[0])
 | 
						|
	    master = LbxProxyClient(proxy);
 | 
						|
	if (master && !master->clientGone)
 | 
						|
	{
 | 
						|
	    closeEvent.type = LbxEventCode;
 | 
						|
	    closeEvent.lbxType = LbxCloseEvent;
 | 
						|
	    closeEvent.client = id;
 | 
						|
	    closeEvent.sequenceNumber = master->sequence;
 | 
						|
	    closeEvent.pad1 = closeEvent.pad2 = closeEvent.pad3 =
 | 
						|
		closeEvent.pad4 = closeEvent.pad5 = closeEvent.pad6 = 0;
 | 
						|
	    if (master->swapped) {
 | 
						|
		int	    n;
 | 
						|
 | 
						|
		swaps(&closeEvent.sequenceNumber, n);
 | 
						|
		swapl(&closeEvent.client, n);
 | 
						|
	    }
 | 
						|
	    WriteToClient(master, sizeof (closeEvent), (char *)&closeEvent);
 | 
						|
	    LbxForceOutput(proxy);
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxReencodeEvent(ClientPtr	client,
 | 
						|
		 LbxProxyPtr	proxy,
 | 
						|
		 char 		*buf)
 | 
						|
{
 | 
						|
    xEvent *ev = (xEvent *)buf;
 | 
						|
    int n;
 | 
						|
    lbxMotionCache *motionCache = &proxy->motionCache;
 | 
						|
    int motionDelta = 0;
 | 
						|
    Bool swapCache;
 | 
						|
    xEvent tev, *sev;
 | 
						|
 | 
						|
    if (ev->u.u.type != MotionNotify) {
 | 
						|
	if (proxy->dosquishing)
 | 
						|
	    return LbxSquishEvent(buf);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check if we can generate a motion delta event.
 | 
						|
     *
 | 
						|
     * The motion cache contains the last motion event the server sent.
 | 
						|
     *
 | 
						|
     * The following are always stored in the cache in the server's
 | 
						|
     * byte order:
 | 
						|
     *     sequenceNumber, time, rootX, rootY, eventX, eventY
 | 
						|
     * This is because when determining if we can do a delta, all
 | 
						|
     * arithmetic must be done using the server's byte order.
 | 
						|
     *
 | 
						|
     * The following are stored in the byte order of the latest client
 | 
						|
     * receiving a motion event (indicated by motionCache->swapped):
 | 
						|
     *     root, event, child, state
 | 
						|
     * These fields do not need to be stored in the server's byte order
 | 
						|
     * because we only use the '==' operator on them.
 | 
						|
     */
 | 
						|
 | 
						|
    if (!proxy->motion_allowed_events) {
 | 
						|
	DBG(DBG_CLIENT, (stderr, "throttling motion event for client %d\n", client->index));
 | 
						|
	return sz_xEvent;
 | 
						|
    }
 | 
						|
    proxy->motion_allowed_events--;
 | 
						|
 | 
						|
    motionCache = &proxy->motionCache;
 | 
						|
 | 
						|
    if (!client->swapped)
 | 
						|
    {
 | 
						|
	swapCache = motionCache->swapped;
 | 
						|
	sev = ev;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	swapCache = !motionCache->swapped;
 | 
						|
	sev = &tev;
 | 
						|
	cpswaps (ev->u.keyButtonPointer.rootX,
 | 
						|
		 sev->u.keyButtonPointer.rootX);
 | 
						|
	cpswaps (ev->u.keyButtonPointer.rootY,
 | 
						|
		 sev->u.keyButtonPointer.rootY);
 | 
						|
	cpswaps (ev->u.keyButtonPointer.eventX,
 | 
						|
		 sev->u.keyButtonPointer.eventX);
 | 
						|
	cpswaps (ev->u.keyButtonPointer.eventY,
 | 
						|
		 sev->u.keyButtonPointer.eventY);
 | 
						|
	cpswaps (ev->u.u.sequenceNumber,
 | 
						|
		 sev->u.u.sequenceNumber);
 | 
						|
	cpswapl (ev->u.keyButtonPointer.time,
 | 
						|
		 sev->u.keyButtonPointer.time);
 | 
						|
    }
 | 
						|
 | 
						|
    if (swapCache)
 | 
						|
    {
 | 
						|
	swapl (&motionCache->root, n);
 | 
						|
	swapl (&motionCache->event, n);
 | 
						|
	swapl (&motionCache->child, n);
 | 
						|
	swaps (&motionCache->state, n);
 | 
						|
 | 
						|
	motionCache->swapped = !motionCache->swapped;
 | 
						|
    }
 | 
						|
 | 
						|
    motionDelta = 0;
 | 
						|
 | 
						|
    if (ev->u.u.detail == motionCache->detail &&
 | 
						|
	ev->u.keyButtonPointer.root == motionCache->root &&
 | 
						|
	ev->u.keyButtonPointer.event == motionCache->event &&
 | 
						|
	ev->u.keyButtonPointer.child == motionCache->child &&
 | 
						|
	ev->u.keyButtonPointer.state == motionCache->state &&
 | 
						|
	ev->u.keyButtonPointer.sameScreen == motionCache->sameScreen) {
 | 
						|
 | 
						|
	int root_delta_x =
 | 
						|
	    sev->u.keyButtonPointer.rootX - motionCache->rootX;
 | 
						|
	int root_delta_y =
 | 
						|
	    sev->u.keyButtonPointer.rootY - motionCache->rootY;
 | 
						|
	int event_delta_x =
 | 
						|
	    sev->u.keyButtonPointer.eventX - motionCache->eventX;
 | 
						|
	int event_delta_y =
 | 
						|
	    sev->u.keyButtonPointer.eventY - motionCache->eventY;
 | 
						|
	unsigned long sequence_delta =
 | 
						|
	    sev->u.u.sequenceNumber - motionCache->sequenceNumber;
 | 
						|
	unsigned long time_delta =
 | 
						|
	    sev->u.keyButtonPointer.time - motionCache->time;
 | 
						|
 | 
						|
	if (root_delta_x == event_delta_x &&
 | 
						|
	    event_delta_x >= -128 && event_delta_x < 128 &&
 | 
						|
	    root_delta_y == event_delta_y &&
 | 
						|
	    event_delta_y >= -128 && event_delta_y < 128) {
 | 
						|
 | 
						|
	    if (sequence_delta == 0 && time_delta < 256) {
 | 
						|
 | 
						|
		lbxQuickMotionDeltaEvent *mev =
 | 
						|
		    (lbxQuickMotionDeltaEvent *)(buf + sz_xEvent -
 | 
						|
						 sz_lbxQuickMotionDeltaEvent);
 | 
						|
 | 
						|
		mev->type = LbxEventCode + LbxQuickMotionDeltaEvent;
 | 
						|
		mev->deltaTime = time_delta;
 | 
						|
		mev->deltaX = event_delta_x;
 | 
						|
		mev->deltaY = event_delta_y;
 | 
						|
 | 
						|
		motionDelta = sz_xEvent - sz_lbxQuickMotionDeltaEvent;
 | 
						|
 | 
						|
	    } else if (sequence_delta < 65536 && time_delta < 65536) {
 | 
						|
 | 
						|
		lbxMotionDeltaEvent *mev =
 | 
						|
		    (lbxMotionDeltaEvent *)(buf + sz_xEvent -
 | 
						|
					    sz_lbxMotionDeltaEvent);
 | 
						|
 | 
						|
		mev->type = LbxEventCode;
 | 
						|
		mev->lbxType = LbxMotionDeltaEvent;
 | 
						|
		mev->deltaTime = time_delta;
 | 
						|
		mev->deltaSequence = sequence_delta;
 | 
						|
		mev->deltaX = event_delta_x;
 | 
						|
		mev->deltaY = event_delta_y;
 | 
						|
 | 
						|
		if (LbxProxyClient(proxy)->swapped)
 | 
						|
		{
 | 
						|
		    swaps (&mev->deltaTime, n);
 | 
						|
		    swaps (&mev->deltaSequence, n);
 | 
						|
		}
 | 
						|
 | 
						|
		motionDelta = sz_xEvent - sz_lbxMotionDeltaEvent;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    motionCache->sequenceNumber = sev->u.u.sequenceNumber;
 | 
						|
    motionCache->time = sev->u.keyButtonPointer.time;
 | 
						|
    motionCache->rootX = sev->u.keyButtonPointer.rootX;
 | 
						|
    motionCache->rootY = sev->u.keyButtonPointer.rootY;
 | 
						|
    motionCache->eventX = sev->u.keyButtonPointer.eventX;
 | 
						|
    motionCache->eventY = sev->u.keyButtonPointer.eventY;
 | 
						|
 | 
						|
    if (motionDelta)
 | 
						|
	return motionDelta;
 | 
						|
 | 
						|
    ev->u.keyButtonPointer.pad1 = 0;
 | 
						|
    motionCache->detail = ev->u.u.detail;
 | 
						|
    motionCache->root = ev->u.keyButtonPointer.root;
 | 
						|
    motionCache->event = ev->u.keyButtonPointer.event;
 | 
						|
    motionCache->child = ev->u.keyButtonPointer.child;
 | 
						|
    motionCache->state = ev->u.keyButtonPointer.state;
 | 
						|
    motionCache->sameScreen = ev->u.keyButtonPointer.sameScreen;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
LbxComposeDelta(LbxProxyPtr	 proxy,
 | 
						|
		char	 	*reply,
 | 
						|
		int		 len,
 | 
						|
		char	 	*buf)
 | 
						|
{
 | 
						|
    int		 diffs;
 | 
						|
    int		 cindex;
 | 
						|
    int		 n;
 | 
						|
    xLbxDeltaReq *p = (xLbxDeltaReq *)buf;
 | 
						|
 | 
						|
    diffs = LBXDeltaMinDiffs(&proxy->outdeltas, (unsigned char *)reply, len,
 | 
						|
			     min(MAXBYTESDIFF, (len - sz_xLbxDeltaReq) >> 1),
 | 
						|
			     &cindex);
 | 
						|
    if (diffs < 0) {
 | 
						|
	LBXAddDeltaOut(&proxy->outdeltas, (unsigned char *)reply, len);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
    LBXEncodeDelta(&proxy->outdeltas, (unsigned char *)reply, diffs, cindex,
 | 
						|
		   (unsigned char *)(&buf[sz_xLbxDeltaReq]));
 | 
						|
    LBXAddDeltaOut(&proxy->outdeltas, (unsigned char *)reply, len);
 | 
						|
    p->reqType = LbxEventCode;
 | 
						|
    p->lbxReqType = LbxDeltaEvent;
 | 
						|
    p->diffs = diffs;
 | 
						|
    p->cindex = cindex;
 | 
						|
    len = (sz_xLbxDeltaReq + sz_xLbxDiffItem * diffs + 3) & ~3;
 | 
						|
    p->length = len >> 2;
 | 
						|
    if (LbxProxyClient(proxy)->swapped) {
 | 
						|
	swaps(&p->length, n);
 | 
						|
    }
 | 
						|
    return len;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
LbxReencodeOutput(ClientPtr 	 client,
 | 
						|
		  char 		*pbuf,
 | 
						|
		  int 		*pcount,
 | 
						|
		  char 		*cbuf,
 | 
						|
		  int 		*ccount)
 | 
						|
{
 | 
						|
    LbxClientPtr lbxClient = LbxClient(client);
 | 
						|
    LbxProxyPtr proxy = lbxClient->proxy;
 | 
						|
    CARD32 len;
 | 
						|
    int n;
 | 
						|
    int count = *ccount;
 | 
						|
    char *obuf = cbuf;
 | 
						|
 | 
						|
    if (client->clientState != ClientStateRunning) {
 | 
						|
	if (DELTA_CACHEABLE(&proxy->outdeltas, count) &&
 | 
						|
	    (n = LbxComposeDelta(proxy, cbuf, count, proxy->oDeltaBuf))) {
 | 
						|
	    memcpy(obuf, proxy->oDeltaBuf, n);
 | 
						|
	    *ccount -= (count - n);
 | 
						|
	}
 | 
						|
	return;
 | 
						|
    }
 | 
						|
    if (lbxClient->bytes_remaining) {
 | 
						|
	if (count < lbxClient->bytes_remaining) {
 | 
						|
	    lbxClient->bytes_remaining -= count;
 | 
						|
	    return;
 | 
						|
	}
 | 
						|
	if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply)) {
 | 
						|
	    len = lbxClient->bytes_in_reply - lbxClient->bytes_remaining;
 | 
						|
	    pbuf += (*pcount - len);
 | 
						|
	    memcpy(proxy->replyBuf, pbuf, len);
 | 
						|
	    memcpy(proxy->replyBuf + len, cbuf, lbxClient->bytes_remaining);
 | 
						|
	    n = LbxComposeDelta(proxy, proxy->replyBuf,
 | 
						|
				lbxClient->bytes_in_reply, proxy->oDeltaBuf);
 | 
						|
	    if (!n)
 | 
						|
		obuf += lbxClient->bytes_remaining;
 | 
						|
	    else if (n <= len) {
 | 
						|
		memcpy(pbuf, proxy->oDeltaBuf, n);
 | 
						|
		*pcount -= (len - n);
 | 
						|
		*ccount -= lbxClient->bytes_remaining;
 | 
						|
	    } else {
 | 
						|
		memcpy(pbuf, proxy->oDeltaBuf, len);
 | 
						|
		memcpy(obuf, proxy->oDeltaBuf + len, n - len);
 | 
						|
		*ccount -= lbxClient->bytes_remaining - (n - len);
 | 
						|
		obuf += n - len;
 | 
						|
	    }
 | 
						|
	} else
 | 
						|
	    obuf += lbxClient->bytes_remaining;
 | 
						|
	cbuf += lbxClient->bytes_remaining;
 | 
						|
	count -= lbxClient->bytes_remaining;
 | 
						|
	lbxClient->bytes_remaining = 0;
 | 
						|
    }
 | 
						|
    while (count) {
 | 
						|
	lbxClient->bytes_in_reply = sz_xEvent;
 | 
						|
	if (((xGenericReply *)cbuf)->type == X_Reply) {
 | 
						|
	    len = ((xGenericReply *)cbuf)->length;
 | 
						|
	    if (client->swapped) {
 | 
						|
		swapl(&len, n);
 | 
						|
            }
 | 
						|
	    lbxClient->bytes_in_reply += (len << 2);
 | 
						|
	    if (LbxProxyClient(proxy)->swapped != client->swapped) {
 | 
						|
		swapl(&((xGenericReply *)cbuf)->length, n);
 | 
						|
	    }
 | 
						|
	    if (count < lbxClient->bytes_in_reply) {
 | 
						|
		lbxClient->bytes_remaining = lbxClient->bytes_in_reply - count;
 | 
						|
		if (obuf != cbuf)
 | 
						|
		    memmove(obuf, cbuf, count);
 | 
						|
		return;
 | 
						|
	    }
 | 
						|
	} else if (((xGenericReply *)cbuf)->type > X_Reply &&
 | 
						|
		   ((xGenericReply *)cbuf)->type < LASTEvent &&
 | 
						|
		   (n = LbxReencodeEvent(client, proxy, cbuf))) {
 | 
						|
	    cbuf += n;
 | 
						|
	    *ccount -= n;
 | 
						|
	    count -= n;
 | 
						|
	    if (n == sz_xEvent)
 | 
						|
		continue;
 | 
						|
	    lbxClient->bytes_in_reply -= n;
 | 
						|
	}
 | 
						|
	if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply) &&
 | 
						|
	    (n = LbxComposeDelta(proxy, cbuf, lbxClient->bytes_in_reply,
 | 
						|
				 proxy->oDeltaBuf))) {
 | 
						|
	    memcpy(obuf, proxy->oDeltaBuf, n);
 | 
						|
	    obuf += n;
 | 
						|
	    *ccount -= (lbxClient->bytes_in_reply - n);
 | 
						|
	} else {
 | 
						|
	    if (obuf != cbuf)
 | 
						|
		memmove(obuf, cbuf, lbxClient->bytes_in_reply);
 | 
						|
	    obuf += lbxClient->bytes_in_reply;
 | 
						|
	}
 | 
						|
	cbuf += lbxClient->bytes_in_reply;
 | 
						|
	count -= lbxClient->bytes_in_reply;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*ARGSUSED*/
 | 
						|
static void
 | 
						|
LbxReplyCallback(CallbackListPtr *pcbl,
 | 
						|
		 pointer 	  nulldata,
 | 
						|
		 pointer 	  calldata)
 | 
						|
{
 | 
						|
    ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
 | 
						|
    ClientPtr client = pri->client;
 | 
						|
    LbxClientPtr lbxClient;
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    if (!pri->startOfReply || stuff->reqType > 127)
 | 
						|
	return;
 | 
						|
    lbxClient = LbxClient(client);
 | 
						|
    if (lbxClient)
 | 
						|
	ZeroReplyPadBytes(pri->replyData, stuff->reqType);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XXX If you think this is moronic, you're in good company,
 | 
						|
 * but things definitely hang if we don't have this.
 | 
						|
 */
 | 
						|
/* ARGSUSED */
 | 
						|
static Bool
 | 
						|
LbxCheckCompressInput (ClientPtr dummy1,
 | 
						|
		       pointer   dummy2)
 | 
						|
{
 | 
						|
    LbxProxyPtr	    proxy;
 | 
						|
 | 
						|
    if (!lbxCompressWorkProcCount)
 | 
						|
	return TRUE;
 | 
						|
 | 
						|
    for (proxy = proxyList; proxy; proxy = proxy->next) {
 | 
						|
	if (proxy->compHandle &&
 | 
						|
	    proxy->streamOpts.streamCompInputAvail(proxy->fd))
 | 
						|
	    AvailableClientInput (LbxProxyClient(proxy));
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
LbxIsClientBlocked (LbxClientPtr lbxClient)
 | 
						|
{
 | 
						|
    LbxProxyPtr		proxy = lbxClient->proxy;
 | 
						|
    
 | 
						|
    return (lbxClient->ignored ||
 | 
						|
	    (GrabInProgress && lbxClient->client->index != GrabInProgress &&
 | 
						|
	     lbxClient != proxy->lbxClients[0]));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxSwitchRecv (LbxProxyPtr  proxy,
 | 
						|
	       LbxClientPtr lbxClient)
 | 
						|
{
 | 
						|
    ClientPtr	client;
 | 
						|
    
 | 
						|
    proxy->curRecv = lbxClient;
 | 
						|
    if (!lbxClient || lbxClient->client->clientGone)
 | 
						|
    {
 | 
						|
	DBG(DBG_CLIENT, (stderr, "switching to dispose input\n"));
 | 
						|
	lbxClient = proxy->lbxClients[0];
 | 
						|
        if (!lbxClient)
 | 
						|
            return;
 | 
						|
    }
 | 
						|
    client = lbxClient->client;
 | 
						|
    DBG (DBG_SWITCH, (stderr, "switching input to client %d\n", client->index));
 | 
						|
 | 
						|
    SwitchClientInput (client, FALSE);
 | 
						|
    proxy->curDix = lbxClient;
 | 
						|
}
 | 
						|
 | 
						|
/* ARGSUSED */
 | 
						|
static Bool
 | 
						|
LbxWaitForUnblocked (ClientPtr	client,
 | 
						|
		     pointer	closure)
 | 
						|
{
 | 
						|
    LbxClientPtr    lbxClient;
 | 
						|
    LbxProxyPtr	    proxy;
 | 
						|
 | 
						|
    if (client->clientGone)
 | 
						|
	return TRUE;
 | 
						|
    lbxClient = LbxClient(client);
 | 
						|
    if (!lbxClient)
 | 
						|
	return TRUE;
 | 
						|
    proxy = lbxClient->proxy;
 | 
						|
    if (LbxIsClientBlocked (lbxClient) ||
 | 
						|
	((lbxClient != proxy->curDix) && proxy->curDix->reqs_pending &&
 | 
						|
	 !LbxIsClientBlocked(proxy->curDix)))
 | 
						|
	return FALSE;
 | 
						|
    lbxClient->input_blocked = FALSE;
 | 
						|
    DBG (DBG_BLOCK, (stderr, "client %d no longer blocked, switching\n",
 | 
						|
		     client->index));
 | 
						|
    SwitchClientInput (client, TRUE);
 | 
						|
    proxy->curDix = lbxClient;
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
LbxSetForBlock(LbxClientPtr lbxClient)
 | 
						|
{
 | 
						|
    lbxClient->reqs_pending++;
 | 
						|
    if (!lbxClient->input_blocked)
 | 
						|
    {
 | 
						|
	lbxClient->input_blocked = TRUE;
 | 
						|
	QueueWorkProc(LbxWaitForUnblocked, lbxClient->client, NULL);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* ARGSUSED */
 | 
						|
static int
 | 
						|
LbxWaitForUngrab (ClientPtr	client,
 | 
						|
		  pointer	closure)
 | 
						|
{
 | 
						|
    LbxClientPtr lbxClient = LbxClient(client);
 | 
						|
    LbxProxyPtr  proxy;
 | 
						|
    xLbxListenToAllEvent ungrabEvent;
 | 
						|
 | 
						|
    if (client->clientGone || !lbxClient)
 | 
						|
	return TRUE;
 | 
						|
    if (GrabInProgress)
 | 
						|
	return FALSE;
 | 
						|
    proxy = lbxClient->proxy;
 | 
						|
    proxy->grabClient = 0;
 | 
						|
    ungrabEvent.type = LbxEventCode;
 | 
						|
    ungrabEvent.lbxType = LbxListenToAll;
 | 
						|
    ungrabEvent.pad1 = ungrabEvent.pad2 = ungrabEvent.pad3 =
 | 
						|
	ungrabEvent.pad4 = ungrabEvent.pad5 = ungrabEvent.pad6 =
 | 
						|
	ungrabEvent.pad7 = 0;
 | 
						|
    WriteToClient (client,
 | 
						|
		   sizeof(xLbxListenToAllEvent), (char *)&ungrabEvent);
 | 
						|
    LbxForceOutput(proxy);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxServerGrab(LbxProxyPtr proxy)
 | 
						|
{
 | 
						|
    LbxClientPtr	grabbingLbxClient;
 | 
						|
    xLbxListenToOneEvent grabEvent;
 | 
						|
 | 
						|
    /*
 | 
						|
     * If the current grabbing client has changed, then we need
 | 
						|
     * to send a message to update the proxy.
 | 
						|
     */
 | 
						|
 | 
						|
    grabEvent.type = LbxEventCode;
 | 
						|
    grabEvent.lbxType = LbxListenToOne;
 | 
						|
    if (!(grabbingLbxClient = lbxClients[GrabInProgress]) ||
 | 
						|
	grabbingLbxClient->proxy != proxy)
 | 
						|
	grabEvent.client = 0xffffffff; /* client other than a proxy client */
 | 
						|
    else
 | 
						|
	grabEvent.client = grabbingLbxClient->id;
 | 
						|
    grabEvent.pad1 = grabEvent.pad2 = grabEvent.pad3 =
 | 
						|
	grabEvent.pad4 = grabEvent.pad5 = grabEvent.pad6 = 0;
 | 
						|
    if (LbxProxyClient(proxy)->swapped) {
 | 
						|
	int n;
 | 
						|
	swapl(&grabEvent.client, n);
 | 
						|
    }
 | 
						|
    WriteToClient(LbxProxyClient(proxy),
 | 
						|
		  sizeof(xLbxListenToOneEvent), (char *)&grabEvent);
 | 
						|
    LbxForceOutput(proxy);
 | 
						|
    if (!proxy->grabClient)
 | 
						|
	QueueWorkProc(LbxWaitForUngrab, LbxProxyClient(proxy), NULL);
 | 
						|
    proxy->grabClient = GrabInProgress;
 | 
						|
}
 | 
						|
 | 
						|
#define MAJOROP(client) ((xReq *)client->requestBuffer)->reqType
 | 
						|
#define MINOROP(client) ((xReq *)client->requestBuffer)->data
 | 
						|
 | 
						|
static Bool lbxCacheable[] = {
 | 
						|
	FALSE,	/* LbxQueryVersion	  0 */
 | 
						|
	FALSE,	/* LbxStartProxy	  1 */
 | 
						|
	TRUE,	/* LbxStopProxy		  2 */
 | 
						|
	FALSE,	/* LbxSwitch		  3 */
 | 
						|
	FALSE,	/* LbxNewClient		  4 */
 | 
						|
	TRUE,	/* LbxCloseClient	  5 */
 | 
						|
	TRUE,	/* LbxModifySequence	  6 */
 | 
						|
	FALSE,	/* LbxAllowMotion	  7 */
 | 
						|
	TRUE,	/* LbxIncrementPixel	  8 */
 | 
						|
	FALSE,	/* LbxDelta		  9 */
 | 
						|
	TRUE,	/* LbxGetModifierMapping 10 */
 | 
						|
	FALSE,	/* nothing		 11 */
 | 
						|
	TRUE,	/* LbxInvalidateTag	 12 */
 | 
						|
	TRUE,	/* LbxPolyPoint		 13 */
 | 
						|
	TRUE,	/* LbxPolyLine		 14 */
 | 
						|
	TRUE,	/* LbxPolySegment	 15 */
 | 
						|
	TRUE,	/* LbxPolyRectangle	 16 */
 | 
						|
	TRUE,	/* LbxPolyArc		 17 */
 | 
						|
	TRUE,	/* LbxFillPoly		 18 */
 | 
						|
	TRUE,	/* LbxPolyFillRectangle	 19 */
 | 
						|
	TRUE,	/* LbxPolyFillArc	 20 */
 | 
						|
	TRUE,	/* LbxGetKeyboardMapping 21 */
 | 
						|
	TRUE,	/* LbxQueryFont		 22 */
 | 
						|
	TRUE,	/* LbxChangeProperty	 23 */
 | 
						|
	TRUE,	/* LbxGetProperty	 24 */
 | 
						|
	TRUE,	/* LbxTagData		 25 */
 | 
						|
	TRUE,	/* LbxCopyArea		 26 */
 | 
						|
	TRUE,	/* LbxCopyPlane		 27 */
 | 
						|
	TRUE,	/* LbxPolyText8		 28 */
 | 
						|
	TRUE,	/* LbxPolyText16	 29 */
 | 
						|
	TRUE,	/* LbxImageText8	 30 */
 | 
						|
	TRUE,	/* LbxImageText16	 31 */
 | 
						|
	FALSE,	/* LbxQueryExtension	 32 */
 | 
						|
	TRUE,	/* LbxPutImage		 33 */
 | 
						|
	TRUE,	/* LbxGetImage		 34 */
 | 
						|
	FALSE,	/* LbxBeginLargeRequest	 35 */
 | 
						|
	FALSE,	/* LbxLargeRequestData	 36 */
 | 
						|
	FALSE,	/* LbxEndLargeRequest	 37 */
 | 
						|
	FALSE,	/* LbxInternAtoms	 38 */
 | 
						|
	TRUE,	/* LbxGetWinAttrAndGeom  39 */
 | 
						|
	TRUE,	/* LbxGrabCmap		 40 */
 | 
						|
	TRUE,	/* LbxReleaseCmap	 41 */
 | 
						|
	TRUE,	/* LbxAllocColor	 42 */
 | 
						|
	TRUE,	/* LbxSync		 43 */
 | 
						|
};
 | 
						|
 | 
						|
#define NUM(a)	(sizeof (a) / sizeof (a[0]))
 | 
						|
 | 
						|
static int
 | 
						|
LbxReadRequestFromClient (ClientPtr	client)
 | 
						|
{
 | 
						|
    int		    ret;
 | 
						|
    LbxClientPtr    lbxClient = LbxClient(client);
 | 
						|
    LbxProxyPtr	    proxy = lbxClient->proxy;
 | 
						|
    ClientPtr	    masterClient = LbxProxyClient(proxy);
 | 
						|
    Bool	    isblocked;
 | 
						|
    Bool	    cacheable;
 | 
						|
 | 
						|
    DBG (DBG_READ_REQ, (stderr, "Reading request from client %d\n", client->index));
 | 
						|
 | 
						|
    if (GrabInProgress && (proxy->grabClient != GrabInProgress))
 | 
						|
	LbxServerGrab(proxy);
 | 
						|
    isblocked = LbxIsClientBlocked(lbxClient);
 | 
						|
 | 
						|
    if (lbxClient->reqs_pending && !isblocked) {
 | 
						|
	ret = StandardReadRequestFromClient(client);
 | 
						|
	if (ret > 0 && (MAJOROP(client) == LbxReqCode) &&
 | 
						|
	    (MINOROP(client) == X_LbxEndLargeRequest))
 | 
						|
	    ret = PrepareLargeReqBuffer(client);
 | 
						|
	if (!--lbxClient->reqs_pending && (lbxClient != proxy->curRecv))
 | 
						|
	    LbxSwitchRecv (proxy, proxy->curRecv);
 | 
						|
	return ret;
 | 
						|
    }
 | 
						|
    while (1) {
 | 
						|
	ret = StandardReadRequestFromClient(masterClient);
 | 
						|
	if (ret <= 0)
 | 
						|
	    return ret;
 | 
						|
	client->requestBuffer = masterClient->requestBuffer;
 | 
						|
	client->req_len = masterClient->req_len;
 | 
						|
	cacheable = client->clientState == ClientStateRunning;
 | 
						|
	if (cacheable && (MAJOROP(client) == LbxReqCode)) {
 | 
						|
	    /* Check to see if this request is delta cached */
 | 
						|
	    if (MINOROP(client) < NUM(lbxCacheable))
 | 
						|
		cacheable = lbxCacheable[MINOROP(client)];
 | 
						|
	    switch (MINOROP(client)) {
 | 
						|
	    case X_LbxSwitch:
 | 
						|
		/* Switch is sent by proxy */
 | 
						|
		if (masterClient->swapped)
 | 
						|
		    SProcLbxSwitch (client);
 | 
						|
		else
 | 
						|
		    ProcLbxSwitch (client);
 | 
						|
		return 0;
 | 
						|
	    case X_LbxDelta:
 | 
						|
		ret = DecodeLbxDelta (client);
 | 
						|
		DBG(DBG_DELTA,
 | 
						|
		    (stderr,"delta decompressed msg %d, len = %d\n",
 | 
						|
		     (unsigned)((unsigned char *)client->requestBuffer)[0],
 | 
						|
		     ret));
 | 
						|
		break;
 | 
						|
	    case X_LbxEndLargeRequest:
 | 
						|
		if (!isblocked)
 | 
						|
		    ret = PrepareLargeReqBuffer(client);
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	if (cacheable && DELTA_CACHEABLE(&proxy->indeltas, ret)) {
 | 
						|
	    DBG(DBG_DELTA,
 | 
						|
		(stderr, "caching msg %d, len = %d, index = %d\n",
 | 
						|
		 (unsigned)((unsigned char *)client->requestBuffer)[0],
 | 
						|
		 ret, proxy->indeltas.nextDelta));
 | 
						|
	    LBXAddDeltaIn(&proxy->indeltas, client->requestBuffer, ret);
 | 
						|
	}
 | 
						|
	if (client->swapped != masterClient->swapped) {
 | 
						|
	    char        n;
 | 
						|
	    /* put length in client order */
 | 
						|
	    swaps(&((xReq *)client->requestBuffer)->length, n);
 | 
						|
	}
 | 
						|
	if (!isblocked)
 | 
						|
	    return ret;
 | 
						|
	DBG (DBG_BLOCK, (stderr, "Stashing %d bytes for %d\n", 
 | 
						|
			 ret, client->index));
 | 
						|
	AppendFakeRequest (client, client->requestBuffer, ret);
 | 
						|
	LbxSetForBlock(lbxClient);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static LbxClientPtr
 | 
						|
LbxInitClient (LbxProxyPtr	proxy,
 | 
						|
	       ClientPtr	client,
 | 
						|
	       CARD32		id)
 | 
						|
{
 | 
						|
    LbxClientPtr lbxClient;
 | 
						|
    int i;
 | 
						|
    
 | 
						|
    lbxClient = (LbxClientPtr) xalloc (sizeof (LbxClientRec));
 | 
						|
    if (!lbxClient)
 | 
						|
	return NULL;
 | 
						|
    lbxClient->id = id;
 | 
						|
    lbxClient->client = client;
 | 
						|
    lbxClient->proxy = proxy;
 | 
						|
    lbxClient->ignored = FALSE;
 | 
						|
    lbxClient->input_blocked = FALSE;
 | 
						|
    lbxClient->reqs_pending = 0;
 | 
						|
    lbxClient->bytes_in_reply = 0;
 | 
						|
    lbxClient->bytes_remaining = 0;
 | 
						|
    client->readRequest = LbxReadRequestFromClient;
 | 
						|
    bzero (lbxClient->drawableCache, sizeof (lbxClient->drawableCache));
 | 
						|
    bzero (lbxClient->gcontextCache, sizeof (lbxClient->gcontextCache));
 | 
						|
    lbxClients[client->index] = lbxClient;
 | 
						|
    for (i = 0; proxy->lbxClients[i]; i++)
 | 
						|
	;
 | 
						|
    if (i > proxy->maxIndex)
 | 
						|
	proxy->maxIndex = i;
 | 
						|
    proxy->lbxClients[i] = lbxClient;
 | 
						|
    proxy->numClients++;
 | 
						|
    lbxClient->gfx_buffer = (pointer) NULL;
 | 
						|
    lbxClient->gb_size = 0;
 | 
						|
    return lbxClient;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxFreeClient (ClientPtr client)
 | 
						|
{
 | 
						|
    LbxClientPtr    lbxClient = LbxClient(client);
 | 
						|
    LbxProxyPtr	    proxy = lbxClient->proxy;
 | 
						|
    int		    i;
 | 
						|
 | 
						|
    if (lbxClient != proxy->lbxClients[0]) {
 | 
						|
	if (lbxClient == proxy->curRecv)
 | 
						|
	    LbxSwitchRecv(proxy, NULL);
 | 
						|
	else if (lbxClient == proxy->curDix)
 | 
						|
	    LbxSwitchRecv(proxy, proxy->curRecv);
 | 
						|
    }
 | 
						|
	
 | 
						|
    --proxy->numClients;
 | 
						|
    lbxClients[client->index] = NULL;
 | 
						|
    for (i = 0; i <= proxy->maxIndex; i++) {
 | 
						|
	if (proxy->lbxClients[i] == lbxClient) {
 | 
						|
	    proxy->lbxClients[i] = NULL;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    while (proxy->maxIndex >= 0 && !proxy->lbxClients[proxy->maxIndex])
 | 
						|
	--proxy->maxIndex;
 | 
						|
    xfree(lbxClient->gfx_buffer);
 | 
						|
    client->readRequest = StandardReadRequestFromClient;
 | 
						|
    xfree (lbxClient);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxFreeProxy (LbxProxyPtr proxy)
 | 
						|
{
 | 
						|
    LbxProxyPtr *p;
 | 
						|
 | 
						|
    LBXFreeDeltaCache(&proxy->indeltas);
 | 
						|
    LBXFreeDeltaCache(&proxy->outdeltas);
 | 
						|
    LbxFreeOsBuffers(proxy);
 | 
						|
    if (proxy->iDeltaBuf)
 | 
						|
	xfree(proxy->iDeltaBuf);
 | 
						|
    if (proxy->replyBuf)
 | 
						|
	xfree(proxy->replyBuf);
 | 
						|
    if (proxy->oDeltaBuf)
 | 
						|
	xfree(proxy->oDeltaBuf);
 | 
						|
    if (proxy->compHandle)
 | 
						|
	proxy->streamOpts.streamCompFreeHandle(proxy->compHandle);
 | 
						|
    if (proxy->bitmapCompMethods)
 | 
						|
	xfree (proxy->bitmapCompMethods);
 | 
						|
    if (proxy->pixmapCompMethods)
 | 
						|
	xfree (proxy->pixmapCompMethods);
 | 
						|
    if (proxy->pixmapCompDepths)
 | 
						|
    {
 | 
						|
	int i;
 | 
						|
	for (i = 0; i < proxy->numPixmapCompMethods; i++)
 | 
						|
	    xfree (proxy->pixmapCompDepths[i]);
 | 
						|
	xfree (proxy->pixmapCompDepths);
 | 
						|
    }
 | 
						|
 | 
						|
    for (p = &proxyList; *p; p = &(*p)->next) {
 | 
						|
	if (*p == proxy) {
 | 
						|
	    *p = proxy->next;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (!proxyList)
 | 
						|
	DeleteCallback(&ReplyCallback, LbxReplyCallback, NULL);
 | 
						|
 | 
						|
    xfree (proxy);
 | 
						|
}
 | 
						|
 | 
						|
LbxProxyPtr
 | 
						|
LbxPidToProxy(int pid)
 | 
						|
{
 | 
						|
    LbxProxyPtr proxy;
 | 
						|
 | 
						|
    for (proxy = proxyList; proxy; proxy = proxy->next) {
 | 
						|
	if (proxy->pid == pid)
 | 
						|
	    return proxy;
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxShutdownProxy (LbxProxyPtr proxy)
 | 
						|
{
 | 
						|
    int		    i;
 | 
						|
    ClientPtr	    client;
 | 
						|
 | 
						|
    if (proxy->compHandle)
 | 
						|
	--lbxCompressWorkProcCount;
 | 
						|
    while (proxy->grabbedCmaps)
 | 
						|
	LbxReleaseCmap(proxy->grabbedCmaps, FALSE);
 | 
						|
    for (i = 0; i <= proxy->maxIndex; i++)
 | 
						|
    {
 | 
						|
	if (proxy->lbxClients[i])
 | 
						|
	{
 | 
						|
	    client = proxy->lbxClients[i]->client;
 | 
						|
	    if (!client->clientGone)
 | 
						|
		CloseDownClient (client);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    LbxFlushTags(proxy);
 | 
						|
    LbxFreeProxy(proxy);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxQueryVersion (ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxQueryVersionReq); */
 | 
						|
    xLbxQueryVersionReply rep;
 | 
						|
    register int n;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxQueryVersionReq);
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.majorVersion = LBX_MAJOR_VERSION;
 | 
						|
    rep.minorVersion = LBX_MINOR_VERSION;
 | 
						|
    rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
    	swaps(&rep.sequenceNumber, n);
 | 
						|
    	swapl(&rep.length, n);
 | 
						|
	swaps(&rep.majorVersion, n);
 | 
						|
	swaps(&rep.minorVersion, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(xLbxQueryVersionReply), (char *)&rep);
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
NextProxyID (void)
 | 
						|
{
 | 
						|
    LbxProxyPtr proxy;
 | 
						|
    int         id;
 | 
						|
 | 
						|
    for (id = 1; id < MAX_NUM_PROXIES; id++) {
 | 
						|
	for (proxy = proxyList; proxy && proxy->pid != id; proxy = proxy->next)
 | 
						|
	    ;
 | 
						|
	if (!proxy)
 | 
						|
	    return id;
 | 
						|
    }
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxStartProxy (ClientPtr	client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxStartProxyReq);
 | 
						|
    LbxProxyPtr	    proxy;
 | 
						|
    LbxClientPtr    lbxClient;
 | 
						|
    int		    reqlen;
 | 
						|
    int		    replylen;
 | 
						|
    xLbxStartReply  *replybuf;
 | 
						|
    LbxNegOptsRec   negopt;
 | 
						|
    register int    n;
 | 
						|
    pointer	    compHandle = NULL;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxStartProxyReq);
 | 
						|
    if (lbxClients[client->index])
 | 
						|
	return BadLbxClientCode;
 | 
						|
    proxy = (LbxProxyPtr) xalloc (sizeof (LbxProxyRec));
 | 
						|
    if (!proxy)
 | 
						|
	return BadAlloc;
 | 
						|
    bzero(proxy, sizeof (LbxProxyRec));
 | 
						|
    proxy->pid = NextProxyID();
 | 
						|
    if (proxy->pid < 0) {	/* too many proxies */
 | 
						|
	xfree(proxy);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
    proxy->uid = ++uid_seed;
 | 
						|
    if (!proxyList)
 | 
						|
	AddCallback(&ReplyCallback, LbxReplyCallback, NULL);
 | 
						|
 | 
						|
    if(!proxyList)
 | 
						|
	proxyList = proxy;
 | 
						|
    else{
 | 
						|
	proxy->next = proxyList;
 | 
						|
	proxyList = proxy;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Don't know exactly how big the reply will be, but it won't be
 | 
						|
     * bigger than the request
 | 
						|
     */
 | 
						|
    reqlen = client->req_len << 2;
 | 
						|
    replybuf = (xLbxStartReply *) xalloc(max(reqlen, sz_xLbxStartReply));
 | 
						|
    if (!replybuf) {
 | 
						|
	LbxFreeProxy(proxy);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    LbxOptionInit(&negopt);
 | 
						|
 | 
						|
    replylen = LbxOptionParse(&negopt,
 | 
						|
			      (unsigned char *)&stuff[1],
 | 
						|
			      reqlen - sz_xLbxStartProxyReq,
 | 
						|
			      (unsigned char *)&replybuf->optDataStart);
 | 
						|
    if (replylen < 0) {
 | 
						|
	/*
 | 
						|
	 * Didn't understand option format, so we'll just end up
 | 
						|
	 * using the defaults.  Set nopts so that the proxy will
 | 
						|
	 * be informed that we rejected the options because of
 | 
						|
	 * decoding problems.
 | 
						|
	 */
 | 
						|
	LbxOptionInit(&negopt);
 | 
						|
	negopt.nopts = 0xff;
 | 
						|
	replylen = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    if (LBXInitDeltaCache(&proxy->indeltas, negopt.proxyDeltaN,
 | 
						|
			  negopt.proxyDeltaMaxLen) < 0
 | 
						|
			||
 | 
						|
	LBXInitDeltaCache(&proxy->outdeltas, negopt.serverDeltaN,
 | 
						|
			  negopt.serverDeltaMaxLen) < 0) {
 | 
						|
	LbxFreeProxy(proxy);
 | 
						|
	xfree(replybuf);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    n = 0;
 | 
						|
    if (negopt.proxyDeltaN)
 | 
						|
	n = negopt.proxyDeltaMaxLen;
 | 
						|
    if (negopt.serverDeltaN && negopt.serverDeltaMaxLen > n)
 | 
						|
	n = negopt.serverDeltaMaxLen;
 | 
						|
    if (n &&
 | 
						|
	(!(proxy->iDeltaBuf = (char *)xalloc (n)) ||
 | 
						|
	 !(proxy->replyBuf = (char *)xalloc (n)) ||
 | 
						|
	 !(proxy->oDeltaBuf = (char *)xalloc (n)))) {
 | 
						|
	LbxFreeProxy(proxy);
 | 
						|
	xfree(replybuf);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
 | 
						|
    MakeClientGrabImpervious(client);	/* proxy needs to be grab-proof */
 | 
						|
    proxy->fd = ClientConnectionNumber(client);
 | 
						|
    if (negopt.streamOpts.streamCompInit) {
 | 
						|
	compHandle =
 | 
						|
	    (*negopt.streamOpts.streamCompInit)(proxy->fd, negopt.streamOpts.streamCompArg);
 | 
						|
	if (!compHandle) {
 | 
						|
	    LbxFreeProxy(proxy);
 | 
						|
	    xfree(replybuf);
 | 
						|
	    return BadAlloc;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    proxy->ofirst = NULL;
 | 
						|
    proxy->olast = NULL;
 | 
						|
    if (!LbxInitClient (proxy, client, 0))
 | 
						|
    {
 | 
						|
	LbxFreeProxy(proxy);
 | 
						|
	xfree(replybuf);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
    proxy->dosquishing = negopt.squish;
 | 
						|
    proxy->numBitmapCompMethods = negopt.numBitmapCompMethods;
 | 
						|
    proxy->bitmapCompMethods = negopt.bitmapCompMethods;
 | 
						|
    proxy->numPixmapCompMethods = negopt.numPixmapCompMethods;
 | 
						|
    proxy->pixmapCompMethods = negopt.pixmapCompMethods;
 | 
						|
    proxy->pixmapCompDepths = negopt.pixmapCompDepths;
 | 
						|
 | 
						|
    proxy->streamOpts = negopt.streamOpts;
 | 
						|
    proxy->useTags = negopt.useTags;
 | 
						|
 | 
						|
    proxy->grabbedCmaps = NULL;
 | 
						|
 | 
						|
    /* send reply */
 | 
						|
    replybuf->type = X_Reply;
 | 
						|
    replybuf->nOpts = negopt.nopts;
 | 
						|
    replybuf->sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    replylen += sz_xLbxStartReplyHdr;
 | 
						|
    if (replylen < sz_xLbxStartReply)
 | 
						|
	replylen = sz_xLbxStartReply;
 | 
						|
    replybuf->length = (replylen - sz_xLbxStartReply + 3) >> 2;
 | 
						|
    if (client->swapped) {
 | 
						|
	swaps(&replybuf->sequenceNumber, n);
 | 
						|
	swapl(&replybuf->length, n);
 | 
						|
    }
 | 
						|
    lbxClient = LbxClient(client);
 | 
						|
    WriteToClient(client, replylen, (char *)replybuf);
 | 
						|
 | 
						|
    LbxProxyConnection(client, proxy);
 | 
						|
    lbxClient = proxy->lbxClients[0];
 | 
						|
    proxy->curDix = lbxClient;
 | 
						|
    proxy->curRecv = lbxClient;
 | 
						|
    proxy->compHandle = compHandle;
 | 
						|
 | 
						|
    if (proxy->compHandle && !lbxCompressWorkProcCount++)
 | 
						|
	QueueWorkProc(LbxCheckCompressInput, NULL, NULL);
 | 
						|
 | 
						|
    xfree(replybuf);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxStopProxy(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxStopProxyReq); */
 | 
						|
    LbxProxyPtr	    proxy;
 | 
						|
    LbxClientPtr    lbxClient = LbxClient(client);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxStopProxyReq);
 | 
						|
 | 
						|
    if (!lbxClient)
 | 
						|
	return BadLbxClientCode;
 | 
						|
    if (lbxClient->id)
 | 
						|
	return BadLbxClientCode;
 | 
						|
    
 | 
						|
    proxy = lbxClient->proxy;
 | 
						|
    LbxFreeClient (client);
 | 
						|
    LbxShutdownProxy (proxy);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
    
 | 
						|
int
 | 
						|
ProcLbxSwitch(ClientPtr	client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxSwitchReq);
 | 
						|
    LbxProxyPtr	proxy = LbxMaybeProxy(client);
 | 
						|
    LbxClientPtr lbxClient;
 | 
						|
    int i;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxSwitchReq);
 | 
						|
    if (!proxy)
 | 
						|
	return BadLbxClientCode;
 | 
						|
    for (i = 0; i <= proxy->maxIndex; i++) {
 | 
						|
	lbxClient = proxy->lbxClients[i];
 | 
						|
	if (lbxClient && lbxClient->id == stuff->client) {
 | 
						|
	    LbxSwitchRecv (proxy, lbxClient);
 | 
						|
	    return Success;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    LbxSwitchRecv (proxy, NULL);
 | 
						|
    return BadLbxClientCode;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxBeginLargeRequest(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxBeginLargeRequestReq);
 | 
						|
 | 
						|
    client->sequence--;
 | 
						|
    REQUEST_SIZE_MATCH(xLbxBeginLargeRequestReq);
 | 
						|
    if (!AllocateLargeReqBuffer(client, stuff->largeReqLength << 2))
 | 
						|
	return BadAlloc;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxLargeRequestData(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxLargeRequestDataReq);
 | 
						|
 | 
						|
    client->sequence--;
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxLargeRequestDataReq);
 | 
						|
    if (!AddToLargeReqBuffer(client, (char *) (stuff + 1),
 | 
						|
			     (client->req_len - 1) << 2))
 | 
						|
	return BadAlloc;
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxEndLargeRequest(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xReq); */
 | 
						|
 | 
						|
    client->sequence--;
 | 
						|
    REQUEST_SIZE_MATCH(xReq);
 | 
						|
    return BadAlloc;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxInternAtoms(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxInternAtomsReq);
 | 
						|
    LbxClientPtr lbxClient = LbxClient(client);
 | 
						|
    xLbxInternAtomsReply *replyRet;
 | 
						|
    char *ptr = (char *) stuff + sz_xLbxInternAtomsReq;
 | 
						|
    Atom *atomsRet;
 | 
						|
    int replyLen, i;
 | 
						|
    char lenbuf[2];
 | 
						|
    CARD16 len;
 | 
						|
    char n;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxInternAtomsReq);
 | 
						|
 | 
						|
    if (!lbxClient)
 | 
						|
	return BadLbxClientCode;
 | 
						|
    if (lbxClient->id)
 | 
						|
	return BadLbxClientCode;
 | 
						|
 | 
						|
    replyLen = sz_xLbxInternAtomsReplyHdr + stuff->num * sizeof (Atom);
 | 
						|
    if (replyLen < sz_xLbxInternAtomsReply)
 | 
						|
	replyLen = sz_xLbxInternAtomsReply;
 | 
						|
 | 
						|
    if (!(replyRet = (xLbxInternAtomsReply *) xalloc (replyLen)))
 | 
						|
	return BadAlloc;
 | 
						|
 | 
						|
    atomsRet = (Atom *) ((char *) replyRet + sz_xLbxInternAtomsReplyHdr);
 | 
						|
 | 
						|
    for (i = 0; i < stuff->num; i++)
 | 
						|
    {
 | 
						|
	lenbuf[0] = ptr[0];
 | 
						|
	lenbuf[1] = ptr[1];
 | 
						|
	len = *((CARD16 *) lenbuf);
 | 
						|
	ptr += 2;
 | 
						|
 | 
						|
	if ((atomsRet[i] = MakeAtom (ptr, len, TRUE)) == BAD_RESOURCE)
 | 
						|
	{
 | 
						|
	    xfree (replyRet);
 | 
						|
	    return BadAlloc;
 | 
						|
	}	    
 | 
						|
 | 
						|
	ptr += len;
 | 
						|
    }
 | 
						|
 | 
						|
    if (client->swapped)
 | 
						|
	for (i = 0; i < stuff->num; i++)
 | 
						|
	    swapl (&atomsRet[i], n);
 | 
						|
 | 
						|
    replyRet->type = X_Reply;
 | 
						|
    replyRet->sequenceNumber = client->sequence;
 | 
						|
    replyRet->length = (replyLen - sz_xLbxInternAtomsReply + 3) >> 2;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
	swaps(&replyRet->sequenceNumber, n);
 | 
						|
	swapl(&replyRet->length, n);
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient (client, replyLen, (char *) replyRet);
 | 
						|
 | 
						|
    xfree (replyRet);
 | 
						|
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxGetWinAttrAndGeom(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxGetWinAttrAndGeomReq);
 | 
						|
    xGetWindowAttributesReply wa;
 | 
						|
    xGetGeometryReply wg;
 | 
						|
    xLbxGetWinAttrAndGeomReply reply;
 | 
						|
    WindowPtr pWin;
 | 
						|
    int status;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxGetWinAttrAndGeomReq);
 | 
						|
    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
 | 
						|
					   SecurityReadAccess);
 | 
						|
    if (!pWin)
 | 
						|
        return(BadWindow);
 | 
						|
    GetWindowAttributes(pWin, client, &wa);
 | 
						|
 | 
						|
    if ((status = GetGeometry(client, &wg)) != Success)
 | 
						|
	return status;
 | 
						|
 | 
						|
    reply.type = X_Reply;
 | 
						|
    reply.length = (sz_xLbxGetWinAttrAndGeomReply - 32) >> 2;
 | 
						|
    reply.sequenceNumber = client->sequence;
 | 
						|
 | 
						|
    reply.backingStore = wa.backingStore;
 | 
						|
    reply.visualID = wa.visualID;
 | 
						|
#if defined(__cplusplus) || defined(c_plusplus)
 | 
						|
    reply.c_class = wa.c_class;
 | 
						|
#else
 | 
						|
    reply.class = wa.class;
 | 
						|
#endif
 | 
						|
    reply.bitGravity = wa.bitGravity;
 | 
						|
    reply.winGravity = wa.winGravity;
 | 
						|
    reply.backingBitPlanes = wa.backingBitPlanes;
 | 
						|
    reply.backingPixel = wa.backingPixel;
 | 
						|
    reply.saveUnder = wa.saveUnder;
 | 
						|
    reply.mapInstalled = wa.mapInstalled;
 | 
						|
    reply.mapState = wa.mapState;
 | 
						|
    reply.override = wa.override;
 | 
						|
    reply.colormap = wa.colormap;
 | 
						|
    reply.allEventMasks = wa.allEventMasks;
 | 
						|
    reply.yourEventMask = wa.yourEventMask;
 | 
						|
    reply.doNotPropagateMask = wa.doNotPropagateMask;
 | 
						|
    reply.pad1 = 0;
 | 
						|
    reply.root = wg.root;
 | 
						|
    reply.x = wg.x;
 | 
						|
    reply.y = wg.y;
 | 
						|
    reply.width = wg.width;
 | 
						|
    reply.height = wg.height;
 | 
						|
    reply.borderWidth = wg.borderWidth;
 | 
						|
    reply.depth = wg.depth;
 | 
						|
    reply.pad2 = 0;
 | 
						|
 | 
						|
    if (client->swapped)
 | 
						|
    {
 | 
						|
	register char n;
 | 
						|
 | 
						|
	swaps(&reply.sequenceNumber, n);
 | 
						|
	swapl(&reply.length, n);
 | 
						|
	swapl(&reply.visualID, n);
 | 
						|
	swaps(&reply.class, n);
 | 
						|
	swapl(&reply.backingBitPlanes, n);
 | 
						|
	swapl(&reply.backingPixel, n);
 | 
						|
	swapl(&reply.colormap, n);
 | 
						|
	swapl(&reply.allEventMasks, n);
 | 
						|
	swapl(&reply.yourEventMask, n);
 | 
						|
	swaps(&reply.doNotPropagateMask, n);
 | 
						|
	swapl(&reply.root, n);
 | 
						|
	swaps(&reply.x, n);
 | 
						|
	swaps(&reply.y, n);
 | 
						|
	swaps(&reply.width, n);
 | 
						|
	swaps(&reply.height, n);
 | 
						|
	swaps(&reply.borderWidth, n);
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient(client, sizeof(xLbxGetWinAttrAndGeomReply), (char *)&reply);
 | 
						|
    return(client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxNewClient(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxNewClientReq);
 | 
						|
    ClientPtr	    newClient;
 | 
						|
    LbxProxyPtr	    proxy = LbxMaybeProxy(client);
 | 
						|
    CARD32	    id;
 | 
						|
    int		    len, i;
 | 
						|
    char	    *setupbuf;
 | 
						|
    LbxClientPtr    lbxClient;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxNewClientReq);
 | 
						|
 | 
						|
    /* save info before our request disappears */
 | 
						|
    id = stuff->client;
 | 
						|
    if (!proxy || !id)
 | 
						|
	return BadLbxClientCode;
 | 
						|
    if (proxy->numClients == MAX_LBX_CLIENTS)
 | 
						|
	return BadAlloc;
 | 
						|
    for (i = 1; i <= proxy->maxIndex; i++) {
 | 
						|
	if (proxy->lbxClients[i] && proxy->lbxClients[i]->id == id)
 | 
						|
	    return BadLbxClientCode;
 | 
						|
    }
 | 
						|
    len = (client->req_len << 2) - sizeof(xLbxNewClientReq);
 | 
						|
    setupbuf = (char *)xalloc (len);
 | 
						|
    if (!setupbuf)
 | 
						|
	return BadAlloc;
 | 
						|
    memcpy (setupbuf, (char *)&stuff[1], len);
 | 
						|
 | 
						|
    newClient = AllocLbxClientConnection (client, proxy);
 | 
						|
    if (!newClient)
 | 
						|
	return BadAlloc;
 | 
						|
    newClient->requestVector = LbxInitialVector;
 | 
						|
    lbxClient = LbxInitClient (proxy, newClient, id);
 | 
						|
    if (!lbxClient)
 | 
						|
    {
 | 
						|
	CloseDownClient (newClient);
 | 
						|
	return BadAlloc;
 | 
						|
    }
 | 
						|
    
 | 
						|
    AppendFakeRequest (newClient, setupbuf, len);
 | 
						|
    xfree (setupbuf);
 | 
						|
    LbxSetForBlock(lbxClient);
 | 
						|
 | 
						|
    DBG (DBG_CLIENT, (stderr, "lbxNewClient X %d\n", newClient->index));
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxEstablishConnection(ClientPtr client)
 | 
						|
{
 | 
						|
    char *reason = NULL;
 | 
						|
    char *auth_proto, *auth_string;
 | 
						|
    register xConnClientPrefix *prefix;
 | 
						|
    REQUEST(xReq);
 | 
						|
 | 
						|
    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
 | 
						|
    auth_proto = (char *)prefix + sz_xConnClientPrefix;
 | 
						|
    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
 | 
						|
    if ((prefix->majorVersion != X_PROTOCOL) ||
 | 
						|
	(prefix->minorVersion != X_PROTOCOL_REVISION))
 | 
						|
	reason = "Protocol version mismatch";
 | 
						|
    else
 | 
						|
	reason = ClientAuthorized(client,
 | 
						|
				  prefix->nbytesAuthProto,
 | 
						|
				  auth_proto,
 | 
						|
				  prefix->nbytesAuthString,
 | 
						|
				  auth_string);
 | 
						|
 | 
						|
    if (client->clientState == ClientStateCheckingSecurity ||
 | 
						|
	client->clientState == ClientStateAuthenticating)
 | 
						|
	return (client->noClientException = -1); /* XXX some day */
 | 
						|
    return(LbxSendConnSetup(client, reason));
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxCloseClient (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxCloseClientReq);
 | 
						|
    LbxClientPtr lbxClient = LbxClient(client);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxCloseClientReq);
 | 
						|
    if (!lbxClient || lbxClient->id != stuff->client)
 | 
						|
	return BadLbxClientCode;
 | 
						|
 | 
						|
    /* this will cause the client to be closed down back in Dispatch() */
 | 
						|
    return(client->noClientException = CloseLbxClient);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxModifySequence (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxModifySequenceReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxModifySequenceReq);
 | 
						|
    client->sequence += (stuff->adjust - 1);	/* Dispatch() adds 1 */
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxAllowMotion (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxAllowMotionReq);
 | 
						|
 | 
						|
    client->sequence--;
 | 
						|
    REQUEST_SIZE_MATCH(xLbxAllowMotionReq);
 | 
						|
    LbxAllowMotion(client, stuff->num);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
DecodeLbxDelta (ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxDeltaReq);
 | 
						|
    LbxClientPtr    lbxClient = LbxClient(client);
 | 
						|
    LbxProxyPtr	    proxy = lbxClient->proxy;
 | 
						|
    int		    len;
 | 
						|
    unsigned char  *buf;
 | 
						|
 | 
						|
    /* Note that LBXDecodeDelta decodes and adds current msg to the cache */
 | 
						|
    len = LBXDecodeDelta(&proxy->indeltas, 
 | 
						|
			 (xLbxDiffItem *)(((char *)stuff) + sz_xLbxDeltaReq),
 | 
						|
			 stuff->diffs, stuff->cindex, &buf);
 | 
						|
    /*
 | 
						|
     * Some requests, such as FillPoly, result in the protocol input
 | 
						|
     * buffer being modified.  So we need to copy the request
 | 
						|
     * into a temporary buffer where a write would be harmless.
 | 
						|
     * Maybe some day do this copying on a case by case basis,
 | 
						|
     * since not all requests are guilty of this.
 | 
						|
     */
 | 
						|
    memcpy(proxy->iDeltaBuf, buf, len);
 | 
						|
 | 
						|
    client->requestBuffer = proxy->iDeltaBuf;
 | 
						|
    client->req_len = len >> 2;
 | 
						|
    return len;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxGetModifierMapping(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxGetModifierMappingReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxGetModifierMappingReq);
 | 
						|
    return LbxGetModifierMapping(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxGetKeyboardMapping(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxGetKeyboardMappingReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
 | 
						|
    return LbxGetKeyboardMapping(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxQueryFont(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxQueryFontReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxQueryFontReq);
 | 
						|
    return LbxQueryFont(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxChangeProperty(ClientPtr	client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxChangePropertyReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
 | 
						|
    return LbxChangeProperty(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxGetProperty(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xLbxGetPropertyReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
 | 
						|
    return LbxGetProperty(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxTagData(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxTagDataReq);
 | 
						|
 | 
						|
    client->sequence--;		/* not a counted request */
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxTagDataReq);
 | 
						|
 | 
						|
    return LbxTagData(client, stuff->tag, stuff->real_length,
 | 
						|
    		 (pointer)&stuff[1]);	/* better not give any errors */
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxInvalidateTag(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxInvalidateTagReq);
 | 
						|
 | 
						|
    client->sequence--;
 | 
						|
    REQUEST_SIZE_MATCH(xLbxInvalidateTagReq);
 | 
						|
    return LbxInvalidateTag(client, stuff->tag);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyPoint(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyPoint, LbxDecodePoints);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyLine(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyLine, LbxDecodePoints);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolySegment(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolySegment, LbxDecodeSegment);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyRectangle(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyRectangle, LbxDecodeRectangle);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyArc(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyArc, LbxDecodeArc);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxFillPoly(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodeFillPoly(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyFillRectangle(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyFillRectangle, LbxDecodeRectangle);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyFillArc(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePoly(client, X_PolyFillArc, LbxDecodeArc);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxCopyArea(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodeCopyArea(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxCopyPlane(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodeCopyPlane(client);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPolyText(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePolyText(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxImageText(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodeImageText(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxQueryExtension(ClientPtr	client)
 | 
						|
{
 | 
						|
    REQUEST(xLbxQueryExtensionReq);
 | 
						|
    char	*ename;
 | 
						|
 | 
						|
    REQUEST_AT_LEAST_SIZE(xLbxQueryExtensionReq);
 | 
						|
    ename = (char *) &stuff[1];
 | 
						|
    return LbxQueryExtension(client, ename, stuff->nbytes);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxPutImage(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodePutImage(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxGetImage(ClientPtr client)
 | 
						|
{
 | 
						|
    return LbxDecodeGetImage(client);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxSync(ClientPtr client)
 | 
						|
{
 | 
						|
    xLbxSyncReply reply;
 | 
						|
 | 
						|
    client->sequence--;		/* not a counted request */
 | 
						|
 | 
						|
#ifdef COLOR_DEBUG
 | 
						|
    fprintf (stderr, "Got LBX sync, seq = 0x%x\n", client->sequence);
 | 
						|
#endif
 | 
						|
 | 
						|
    reply.type = X_Reply;
 | 
						|
    reply.length = 0;
 | 
						|
    reply.sequenceNumber = client->sequence;
 | 
						|
    reply.pad0 = reply.pad1 = reply.pad2 = reply.pad3 = reply.pad4 = 
 | 
						|
        reply.pad5 = reply.pad6 = 0;
 | 
						|
 | 
						|
    if (client->swapped)
 | 
						|
    {
 | 
						|
	register char n;
 | 
						|
	swaps (&reply.sequenceNumber, n);
 | 
						|
    }
 | 
						|
 | 
						|
    WriteToClient (client, sz_xLbxSyncReply, (char *)&reply);
 | 
						|
 | 
						|
    return (client->noClientException);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
ProcLbxDispatch(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xReq);
 | 
						|
    switch (stuff->data)
 | 
						|
    {
 | 
						|
    case X_LbxQueryVersion:
 | 
						|
	return ProcLbxQueryVersion(client);
 | 
						|
    case X_LbxStartProxy:
 | 
						|
	return ProcLbxStartProxy(client);
 | 
						|
    case X_LbxStopProxy:
 | 
						|
	return ProcLbxStopProxy(client);
 | 
						|
    case X_LbxNewClient:
 | 
						|
	return ProcLbxNewClient(client);
 | 
						|
    case X_LbxCloseClient:
 | 
						|
	return ProcLbxCloseClient(client);
 | 
						|
    case X_LbxModifySequence:
 | 
						|
	return ProcLbxModifySequence(client);
 | 
						|
    case X_LbxAllowMotion:
 | 
						|
	return ProcLbxAllowMotion(client);
 | 
						|
    case X_LbxIncrementPixel:
 | 
						|
	return ProcLbxIncrementPixel(client);
 | 
						|
    case X_LbxGrabCmap:
 | 
						|
	return ProcLbxGrabCmap(client);
 | 
						|
    case X_LbxReleaseCmap:
 | 
						|
	return ProcLbxReleaseCmap(client);
 | 
						|
    case X_LbxAllocColor:
 | 
						|
	return ProcLbxAllocColor(client);
 | 
						|
    case X_LbxGetModifierMapping:
 | 
						|
	return ProcLbxGetModifierMapping(client);
 | 
						|
    case X_LbxGetKeyboardMapping:
 | 
						|
	return ProcLbxGetKeyboardMapping(client);
 | 
						|
    case X_LbxInvalidateTag:
 | 
						|
	return ProcLbxInvalidateTag(client);
 | 
						|
    case X_LbxPolyPoint:
 | 
						|
	return ProcLbxPolyPoint (client);
 | 
						|
    case X_LbxPolyLine:
 | 
						|
	return ProcLbxPolyLine (client);
 | 
						|
    case X_LbxPolySegment:
 | 
						|
	return ProcLbxPolySegment (client);
 | 
						|
    case X_LbxPolyRectangle:
 | 
						|
	return ProcLbxPolyRectangle (client);
 | 
						|
    case X_LbxPolyArc:
 | 
						|
	return ProcLbxPolyArc (client);
 | 
						|
    case X_LbxFillPoly:
 | 
						|
	return ProcLbxFillPoly (client);
 | 
						|
    case X_LbxPolyFillRectangle:
 | 
						|
	return ProcLbxPolyFillRectangle (client);
 | 
						|
    case X_LbxPolyFillArc:
 | 
						|
	return ProcLbxPolyFillArc (client);
 | 
						|
    case X_LbxQueryFont:
 | 
						|
	return ProcLbxQueryFont (client);
 | 
						|
    case X_LbxChangeProperty:
 | 
						|
	return ProcLbxChangeProperty (client);
 | 
						|
    case X_LbxGetProperty:
 | 
						|
	return ProcLbxGetProperty (client);
 | 
						|
    case X_LbxTagData:
 | 
						|
	return ProcLbxTagData (client);
 | 
						|
    case X_LbxCopyArea:
 | 
						|
	return ProcLbxCopyArea (client);
 | 
						|
    case X_LbxCopyPlane:
 | 
						|
	return ProcLbxCopyPlane (client);
 | 
						|
    case X_LbxPolyText8:
 | 
						|
    case X_LbxPolyText16:
 | 
						|
	return ProcLbxPolyText (client);
 | 
						|
    case X_LbxImageText8:
 | 
						|
    case X_LbxImageText16:
 | 
						|
	return ProcLbxImageText (client);
 | 
						|
    case X_LbxQueryExtension:
 | 
						|
	return ProcLbxQueryExtension (client);
 | 
						|
    case X_LbxPutImage:
 | 
						|
	return ProcLbxPutImage (client);
 | 
						|
    case X_LbxGetImage:
 | 
						|
	return ProcLbxGetImage (client);
 | 
						|
    case X_LbxInternAtoms:
 | 
						|
	return ProcLbxInternAtoms(client);
 | 
						|
    case X_LbxGetWinAttrAndGeom:
 | 
						|
	return ProcLbxGetWinAttrAndGeom(client);
 | 
						|
    case X_LbxSync:
 | 
						|
	return ProcLbxSync(client);
 | 
						|
    case X_LbxBeginLargeRequest:
 | 
						|
	return ProcLbxBeginLargeRequest(client);
 | 
						|
    case X_LbxLargeRequestData:
 | 
						|
	return ProcLbxLargeRequestData(client);
 | 
						|
    case X_LbxEndLargeRequest:
 | 
						|
	return ProcLbxLargeRequestData(client);
 | 
						|
    default:
 | 
						|
	return BadRequest;
 | 
						|
    }
 | 
						|
}
 |