xserver-multidpi/lbx/lbxmain.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;
}
}