(file) Return to lbxmain.c CVS log (file) (dir) Up to [XFree86 CVS] / xc / programs / Xserver / lbx

   1 dawes 1.6 /* $TOG: lbxmain.c /main/74 1998/02/09 14:32:18 kaleb $ */
   2           /*
   3           
   4           Copyright 1996, 1998  The Open Group
   5           
   6           All Rights Reserved.
   7           
   8           The above copyright notice and this permission notice shall be included in
   9           all copies or substantial portions of the Software.
  10           
  11           THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12           IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13           FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  14           OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  15           AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16           CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17           
  18           Except as contained in this notice, the name of The Open Group shall not be
  19           used in advertising or otherwise to promote the sale, use or other dealings
  20           in this Software without prior written authorization from The Open Group.
  21           
  22 dawes 1.6 */
  23 dawes 1.1 /*
  24            * Copyright 1992 Network Computing Devices
  25            *
  26            * Permission to use, copy, modify, distribute, and sell this software and its
  27            * documentation for any purpose is hereby granted without fee, provided that
  28            * the above copyright notice appear in all copies and that both that
  29            * copyright notice and this permission notice appear in supporting
  30            * documentation, and that the name of NCD. not be used in advertising or
  31            * publicity pertaining to distribution of the software without specific,
  32            * written prior permission.  NCD. makes no representations about the
  33            * suitability of this software for any purpose.  It is provided "as is"
  34            * without express or implied warranty.
  35            *
  36            * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  37            * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
  38            * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  39            * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  40            * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  41            * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  42            *
  43            */
  44 dawes 1.6 /* $XFree86: xc/programs/Xserver/lbx/lbxmain.c,v 1.5 1997/01/18 06:57:51 dawes Exp $ */
  45 dawes 1.1  
  46           #include <sys/types.h>
  47           #define NEED_REPLIES
  48           #define NEED_EVENTS
  49           #include "X.h"
  50           #include "Xproto.h"
  51           #include "Xos.h"
  52           #include "misc.h"
  53           #include "os.h"
  54           #include "dixstruct.h"
  55           #include "resource.h"
  56           #include "scrnintstr.h"
  57           #include "windowstr.h"
  58           #include "pixmapstr.h"
  59           #include "gcstruct.h"
  60           #include "extnsionst.h"
  61           #include "servermd.h"
  62           #include "lbxdeltastr.h"
  63           #define _XLBX_SERVER_
  64           #include "lbxstr.h"
  65           #include "lbxserve.h"
  66 dawes 1.1 #include "lbximage.h"
  67           #include "lbxsrvopts.h"
  68           #include "Xfuncproto.h"
  69           #include <errno.h>
  70           #ifdef X_NOT_STDC_ENV
  71           extern int errno;
  72           #endif
  73 dawes 1.5 #ifndef Lynx
  74 dawes 1.1 #include <sys/uio.h>
  75 dawes 1.5 #else
  76           #include <uio.h>
  77           #endif
  78 dawes 1.1 #include <stdio.h>
  79           
  80           #ifndef X_NOT_POSIX
  81           #include <unistd.h>
  82           #endif
  83           
  84           #define CloseLbxClient	0xff
  85           
  86           #define MAXBYTESDIFF	8
  87           
  88           extern void	LbxAllowMotion();
  89           extern int	LbxDecodePoints();
  90           extern int	LbxDecodeSegment();
  91           extern int	LbxDecodeRectangle();
  92           extern int	LbxDecodeArc();
  93           
  94           extern int	GrabInProgress;
  95           
  96           int LbxWhoAmI = 1;		/*
  97           				 * for lbx zlib library to know who we are
  98           				 * server = 1
  99 dawes 1.1 				 * proxy = 0
 100           				 */
 101           
 102           int ProcLbxDispatch();
 103           extern int SProcLbxDispatch();
 104           static void LbxResetProc();
 105           static int DecodeLbxDelta();
 106           static void LbxFreeClient ();
 107           static void LbxShutdownProxy ();
 108           
 109           static LbxProxyPtr proxyList;
 110           unsigned char LbxReqCode;
 111           int 	LbxEventCode;
 112           static int BadLbxClientCode;
 113           static int	uid_seed;
 114           
 115           static int	lbxCompressWorkProcCount;
 116           
 117           LbxClientPtr	lbxClients[MAXCLIENTS];
 118           
 119           extern xConnSetupPrefix connSetupPrefix;
 120 dawes 1.1 extern char *ConnectionInfo;
 121           extern int  (*LbxInitialVector[3])();
 122           
 123           #ifdef DEBUG
 124           int lbxDebug = 0;
 125           #endif
 126           
 127           
 128           void
 129           LbxExtensionInit()
 130           {
 131               ExtensionEntry *extEntry;
 132           
 133               lbxCompressWorkProcCount = 0;
 134               proxyList = NULL;
 135               uid_seed = 0;
 136               if ((extEntry = AddExtension(LBXNAME, LbxNumberEvents, LbxNumberErrors,
 137           				 ProcLbxDispatch, SProcLbxDispatch,
 138           				 LbxResetProc, StandardMinorOpcode)))
 139               {
 140           	LbxReqCode = (unsigned char)extEntry->base;
 141 dawes 1.1 	LbxEventCode = extEntry->eventBase;
 142           	BadLbxClientCode = extEntry->errorBase + BadLbxClient;
 143                   LbxDixInit();
 144           
 145           	LbxCmapInit ();
 146           	DeclareExtensionSecurity(LBXNAME, TRUE); 
 147               }
 148           }
 149           
 150           /*ARGSUSED*/
 151           static void
 152           LbxResetProc (extEntry)
 153           ExtensionEntry	*extEntry;
 154           {
 155              LbxResetTags();
 156              uid_seed = 0;
 157           }
 158           
 159           void
 160           LbxCloseClient (client)
 161               ClientPtr	client;
 162 dawes 1.1 {
 163               xLbxCloseEvent  closeEvent;
 164               ClientPtr	    master;
 165               LbxProxyPtr	    proxy;
 166               LbxClientPtr    lbxClient = LbxClient(client);
 167               CARD32	    id;
 168           
 169               if (!lbxClient)
 170           	return;
 171               id = lbxClient->id;
 172               proxy = lbxClient->proxy;
 173           
 174               DBG (DBG_CLIENT, (stderr, "Close client %d\n", client->index));
 175               LbxFreeClient (client);
 176               if (!id)
 177               {
 178           	isItTimeToYield = TRUE;
 179           	CloseDownFileDescriptor (client);
 180           	LbxShutdownProxy (proxy);
 181               } 
 182               else
 183 dawes 1.1     {
 184           	master = NULL;
 185           	if (proxy->lbxClients[0])
 186           	    master = LbxProxyClient(proxy);
 187           	if (master && !master->clientGone)
 188           	{
 189           	    closeEvent.type = LbxEventCode;
 190           	    closeEvent.lbxType = LbxCloseEvent;
 191           	    closeEvent.client = id;
 192           	    closeEvent.sequenceNumber = master->sequence;
 193           	    closeEvent.pad1 = closeEvent.pad2 = closeEvent.pad3 =
 194           		closeEvent.pad4 = closeEvent.pad5 = closeEvent.pad6 = 0;
 195           	    if (master->swapped) {
 196           		int	    n;
 197           
 198           		swaps(&closeEvent.sequenceNumber, n);
 199           		swapl(&closeEvent.client, n);
 200           	    }
 201           	    WriteToClient(master, sizeof (closeEvent), (char *)&closeEvent);
 202           	    LbxForceOutput(proxy);
 203           	}
 204 dawes 1.1     }
 205           }
 206           
 207           static int
 208           LbxReencodeEvent(client, proxy, buf)
 209               ClientPtr	client;
 210               LbxProxyPtr	proxy;
 211               char *buf;
 212           {
 213               xEvent *ev = (xEvent *)buf;
 214               int n;
 215               lbxMotionCache *motionCache = &proxy->motionCache;
 216               int motionDelta = 0;
 217               Bool swapCache;
 218               xEvent tev, *sev;
 219           
 220               if (ev->u.u.type != MotionNotify) {
 221           	if (proxy->dosquishing)
 222           	    return LbxSquishEvent(buf);
 223           	return 0;
 224               }
 225 dawes 1.1 
 226               /*
 227                * Check if we can generate a motion delta event.
 228                *
 229                * The motion cache contains the last motion event the server sent.
 230                *
 231                * The following are always stored in the cache in the server's
 232                * byte order:
 233                *     sequenceNumber, time, rootX, rootY, eventX, eventY
 234                * This is because when determining if we can do a delta, all
 235                * arithmetic must be done using the server's byte order.
 236                *
 237                * The following are stored in the byte order of the latest client
 238                * receiving a motion event (indicated by motionCache->swapped):
 239                *     root, event, child, state
 240                * These fields do not need to be stored in the server's byte order
 241                * because we only use the '==' operator on them.
 242                */
 243           
 244               if (!proxy->motion_allowed_events) {
 245           	DBG(DBG_CLIENT, (stderr, "throttling motion event for client %d\n", client->index));
 246 dawes 1.1 	return sz_xEvent;
 247               }
 248               proxy->motion_allowed_events--;
 249           
 250               motionCache = &proxy->motionCache;
 251           
 252               if (!client->swapped)
 253               {
 254           	swapCache = motionCache->swapped;
 255           	sev = ev;
 256               }
 257               else
 258               {
 259           	swapCache = !motionCache->swapped;
 260           	sev = &tev;
 261           	cpswaps (ev->u.keyButtonPointer.rootX,
 262           		 sev->u.keyButtonPointer.rootX);
 263           	cpswaps (ev->u.keyButtonPointer.rootY,
 264           		 sev->u.keyButtonPointer.rootY);
 265           	cpswaps (ev->u.keyButtonPointer.eventX,
 266           		 sev->u.keyButtonPointer.eventX);
 267 dawes 1.1 	cpswaps (ev->u.keyButtonPointer.eventY,
 268           		 sev->u.keyButtonPointer.eventY);
 269           	cpswaps (ev->u.u.sequenceNumber,
 270           		 sev->u.u.sequenceNumber);
 271           	cpswapl (ev->u.keyButtonPointer.time,
 272           		 sev->u.keyButtonPointer.time);
 273               }
 274           
 275               if (swapCache)
 276               {
 277           	swapl (&motionCache->root, n);
 278           	swapl (&motionCache->event, n);
 279           	swapl (&motionCache->child, n);
 280           	swaps (&motionCache->state, n);
 281           
 282           	motionCache->swapped = !motionCache->swapped;
 283               }
 284           
 285               motionDelta = 0;
 286           
 287               if (ev->u.u.detail == motionCache->detail &&
 288 dawes 1.1 	ev->u.keyButtonPointer.root == motionCache->root &&
 289           	ev->u.keyButtonPointer.event == motionCache->event &&
 290           	ev->u.keyButtonPointer.child == motionCache->child &&
 291           	ev->u.keyButtonPointer.state == motionCache->state &&
 292           	ev->u.keyButtonPointer.sameScreen == motionCache->sameScreen) {
 293           
 294           	int root_delta_x =
 295           	    sev->u.keyButtonPointer.rootX - motionCache->rootX;
 296           	int root_delta_y =
 297           	    sev->u.keyButtonPointer.rootY - motionCache->rootY;
 298           	int event_delta_x =
 299           	    sev->u.keyButtonPointer.eventX - motionCache->eventX;
 300           	int event_delta_y =
 301           	    sev->u.keyButtonPointer.eventY - motionCache->eventY;
 302           	unsigned long sequence_delta =
 303           	    sev->u.u.sequenceNumber - motionCache->sequenceNumber;
 304           	unsigned long time_delta =
 305           	    sev->u.keyButtonPointer.time - motionCache->time;
 306           
 307           	if (root_delta_x == event_delta_x &&
 308           	    event_delta_x >= -128 && event_delta_x < 128 &&
 309 dawes 1.1 	    root_delta_y == event_delta_y &&
 310           	    event_delta_y >= -128 && event_delta_y < 128) {
 311           
 312           	    if (sequence_delta == 0 && time_delta < 256) {
 313           
 314           		lbxQuickMotionDeltaEvent *mev =
 315           		    (lbxQuickMotionDeltaEvent *)(buf + sz_xEvent -
 316           						 sz_lbxQuickMotionDeltaEvent);
 317           
 318           		mev->type = LbxEventCode + LbxQuickMotionDeltaEvent;
 319           		mev->deltaTime = time_delta;
 320           		mev->deltaX = event_delta_x;
 321           		mev->deltaY = event_delta_y;
 322           
 323           		motionDelta = sz_xEvent - sz_lbxQuickMotionDeltaEvent;
 324           
 325           	    } else if (sequence_delta < 65536 && time_delta < 65536) {
 326           
 327           		lbxMotionDeltaEvent *mev =
 328           		    (lbxMotionDeltaEvent *)(buf + sz_xEvent -
 329           					    sz_lbxMotionDeltaEvent);
 330 dawes 1.1 
 331           		mev->type = LbxEventCode;
 332           		mev->lbxType = LbxMotionDeltaEvent;
 333           		mev->deltaTime = time_delta;
 334           		mev->deltaSequence = sequence_delta;
 335           		mev->deltaX = event_delta_x;
 336           		mev->deltaY = event_delta_y;
 337           
 338           		if (LbxProxyClient(proxy)->swapped)
 339           		{
 340           		    swaps (&mev->deltaTime, n);
 341           		    swaps (&mev->deltaSequence, n);
 342           		}
 343           
 344           		motionDelta = sz_xEvent - sz_lbxMotionDeltaEvent;
 345           	    }
 346           	}
 347               }
 348           
 349               motionCache->sequenceNumber = sev->u.u.sequenceNumber;
 350               motionCache->time = sev->u.keyButtonPointer.time;
 351 dawes 1.1     motionCache->rootX = sev->u.keyButtonPointer.rootX;
 352               motionCache->rootY = sev->u.keyButtonPointer.rootY;
 353               motionCache->eventX = sev->u.keyButtonPointer.eventX;
 354               motionCache->eventY = sev->u.keyButtonPointer.eventY;
 355           
 356               if (motionDelta)
 357           	return motionDelta;
 358           
 359               ev->u.keyButtonPointer.pad1 = 0;
 360               motionCache->detail = ev->u.u.detail;
 361               motionCache->root = ev->u.keyButtonPointer.root;
 362               motionCache->event = ev->u.keyButtonPointer.event;
 363               motionCache->child = ev->u.keyButtonPointer.child;
 364               motionCache->state = ev->u.keyButtonPointer.state;
 365               motionCache->sameScreen = ev->u.keyButtonPointer.sameScreen;
 366               return 0;
 367           }
 368           
 369           static int
 370           LbxComposeDelta(proxy, reply, len, buf)
 371               LbxProxyPtr	 proxy;
 372 dawes 1.1     char	 *reply;
 373               int		 len;
 374               char	 *buf;
 375           {
 376               int		 diffs;
 377               int		 cindex;
 378               int		 n;
 379               xLbxDeltaReq *p = (xLbxDeltaReq *)buf;
 380           
 381               diffs = LBXDeltaMinDiffs(&proxy->outdeltas, reply, len,
 382           			     min(MAXBYTESDIFF, (len - sz_xLbxDeltaReq) >> 1),
 383           			     &cindex);
 384               if (diffs < 0) {
 385           	LBXAddDeltaOut(&proxy->outdeltas, reply, len);
 386           	return 0;
 387               }
 388               LBXEncodeDelta(&proxy->outdeltas, reply, diffs, cindex,
 389           		   &buf[sz_xLbxDeltaReq]);
 390               LBXAddDeltaOut(&proxy->outdeltas, reply, len);
 391               p->reqType = LbxEventCode;
 392               p->lbxReqType = LbxDeltaEvent;
 393 dawes 1.1     p->diffs = diffs;
 394               p->cindex = cindex;
 395               len = (sz_xLbxDeltaReq + sz_xLbxDiffItem * diffs + 3) & ~3;
 396               p->length = len >> 2;
 397               if (LbxProxyClient(proxy)->swapped) {
 398           	swaps(&p->length, n);
 399               }
 400               return len;
 401           }
 402           
 403           void
 404           LbxReencodeOutput(client, pbuf, pcount, cbuf, ccount)
 405               ClientPtr client;
 406               char *pbuf;
 407               int *pcount;
 408               char *cbuf;
 409               int *ccount;
 410           {
 411               LbxClientPtr lbxClient = LbxClient(client);
 412               LbxProxyPtr proxy = lbxClient->proxy;
 413               CARD32 len;
 414 dawes 1.1     int n;
 415               int count = *ccount;
 416               char *obuf = cbuf;
 417           
 418               if (client->clientState != ClientStateRunning) {
 419           	if (DELTA_CACHEABLE(&proxy->outdeltas, count) &&
 420           	    (n = LbxComposeDelta(proxy, cbuf, count, proxy->oDeltaBuf))) {
 421           	    memcpy(obuf, proxy->oDeltaBuf, n);
 422           	    *ccount -= (count - n);
 423           	}
 424           	return;
 425               }
 426               if (lbxClient->bytes_remaining) {
 427           	if (count < lbxClient->bytes_remaining) {
 428           	    lbxClient->bytes_remaining -= count;
 429           	    return;
 430           	}
 431           	if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply)) {
 432           	    len = lbxClient->bytes_in_reply - lbxClient->bytes_remaining;
 433           	    pbuf += (*pcount - len);
 434           	    memcpy(proxy->replyBuf, pbuf, len);
 435 dawes 1.1 	    memcpy(proxy->replyBuf + len, cbuf, lbxClient->bytes_remaining);
 436           	    n = LbxComposeDelta(proxy, proxy->replyBuf,
 437           				lbxClient->bytes_in_reply, proxy->oDeltaBuf);
 438           	    if (!n)
 439           		obuf += lbxClient->bytes_remaining;
 440           	    else if (n <= len) {
 441           		memcpy(pbuf, proxy->oDeltaBuf, n);
 442           		*pcount -= (len - n);
 443           		*ccount -= lbxClient->bytes_remaining;
 444           	    } else {
 445           		memcpy(pbuf, proxy->oDeltaBuf, len);
 446           		memcpy(obuf, proxy->oDeltaBuf + len, n - len);
 447           		*ccount -= lbxClient->bytes_remaining - (n - len);
 448           		obuf += n - len;
 449           	    }
 450           	} else
 451           	    obuf += lbxClient->bytes_remaining;
 452           	cbuf += lbxClient->bytes_remaining;
 453           	count -= lbxClient->bytes_remaining;
 454           	lbxClient->bytes_remaining = 0;
 455               }
 456 dawes 1.1     while (count) {
 457           	lbxClient->bytes_in_reply = sz_xEvent;
 458           	if (((xGenericReply *)cbuf)->type == X_Reply) {
 459           	    len = ((xGenericReply *)cbuf)->length;
 460           	    if (client->swapped) {
 461           		swapl(&len, n);
 462                       }
 463           	    lbxClient->bytes_in_reply += (len << 2);
 464           	    if (LbxProxyClient(proxy)->swapped != client->swapped) {
 465           		swapl(&((xGenericReply *)cbuf)->length, n);
 466           	    }
 467           	    if (count < lbxClient->bytes_in_reply) {
 468           		lbxClient->bytes_remaining = lbxClient->bytes_in_reply - count;
 469           		if (obuf != cbuf)
 470           		    memmove(obuf, cbuf, count);
 471           		return;
 472           	    }
 473           	} else if (((xGenericReply *)cbuf)->type > X_Reply &&
 474           		   ((xGenericReply *)cbuf)->type < LASTEvent &&
 475           		   (n = LbxReencodeEvent(client, proxy, cbuf))) {
 476           	    cbuf += n;
 477 dawes 1.1 	    *ccount -= n;
 478           	    count -= n;
 479           	    if (n == sz_xEvent)
 480           		continue;
 481           	    lbxClient->bytes_in_reply -= n;
 482           	}
 483           	if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply) &&
 484           	    (n = LbxComposeDelta(proxy, cbuf, lbxClient->bytes_in_reply,
 485           				 proxy->oDeltaBuf))) {
 486           	    memcpy(obuf, proxy->oDeltaBuf, n);
 487           	    obuf += n;
 488           	    *ccount -= (lbxClient->bytes_in_reply - n);
 489           	} else {
 490           	    if (obuf != cbuf)
 491           		memmove(obuf, cbuf, lbxClient->bytes_in_reply);
 492           	    obuf += lbxClient->bytes_in_reply;
 493           	}
 494           	cbuf += lbxClient->bytes_in_reply;
 495           	count -= lbxClient->bytes_in_reply;
 496               }
 497           }
 498 dawes 1.1 
 499           /*ARGSUSED*/
 500           static void
 501           LbxReplyCallback(pcbl, nulldata, calldata)
 502               CallbackListPtr *pcbl;
 503               pointer nulldata;
 504               pointer calldata;
 505           {
 506               ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
 507               ClientPtr client = pri->client;
 508               LbxClientPtr lbxClient;
 509               REQUEST(xReq);
 510           
 511               if (!pri->startOfReply || stuff->reqType > 127)
 512           	return;
 513               lbxClient = LbxClient(client);
 514               if (lbxClient)
 515           	ZeroReplyPadBytes(pri->replyData, stuff->reqType);
 516           }
 517           
 518           /*
 519 dawes 1.1  * XXX If you think this is moronic, you're in good company,
 520            * but things definitely hang if we don't have this.
 521            */
 522           /* ARGSUSED */
 523           static Bool
 524           LbxCheckCompressInput (dummy1, dummy2)
 525 dawes 1.2     ClientPtr dummy1;
 526 dawes 1.1     pointer dummy2;
 527           {
 528               LbxProxyPtr	    proxy;
 529           
 530               if (!lbxCompressWorkProcCount)
 531           	return TRUE;
 532           
 533               for (proxy = proxyList; proxy; proxy = proxy->next) {
 534           	if (proxy->compHandle &&
 535           	    proxy->streamOpts.streamCompInputAvail(proxy->fd))
 536           	    AvailableClientInput (LbxProxyClient(proxy));
 537               }
 538               return FALSE;
 539           }
 540           
 541           static Bool
 542 dawes 1.2 LbxIsClientBlocked (lbxClient)
 543               LbxClientPtr	lbxClient;
 544 dawes 1.1 {
 545               LbxProxyPtr		proxy = lbxClient->proxy;
 546               
 547               return (lbxClient->ignored ||
 548 dawes 1.2 	    (GrabInProgress && lbxClient->client->index != GrabInProgress &&
 549 dawes 1.1 	     lbxClient != proxy->lbxClients[0]));
 550           }
 551           
 552           static void
 553           LbxSwitchRecv (proxy, lbxClient)
 554               LbxProxyPtr		proxy;
 555               LbxClientPtr	lbxClient;
 556           {
 557               ClientPtr	client;
 558               
 559               proxy->curRecv = lbxClient;
 560               if (!lbxClient || lbxClient->client->clientGone)
 561               {
 562           	DBG(DBG_CLIENT, (stderr, "switching to dispose input\n"));
 563           	lbxClient = proxy->lbxClients[0];
 564                   if (!lbxClient)
 565                       return;
 566               }
 567               client = lbxClient->client;
 568               DBG (DBG_SWITCH, (stderr, "switching input to client %d\n", client->index));
 569           
 570 dawes 1.1     SwitchClientInput (client, FALSE);
 571               proxy->curDix = lbxClient;
 572           }
 573           
 574           /* ARGSUSED */
 575           static Bool
 576           LbxWaitForUnblocked (client, closure)
 577               ClientPtr	client;
 578               pointer	closure;
 579           {
 580               LbxClientPtr    lbxClient;
 581               LbxProxyPtr	    proxy;
 582           
 583               if (client->clientGone)
 584           	return TRUE;
 585               lbxClient = LbxClient(client);
 586               if (!lbxClient)
 587           	return TRUE;
 588               proxy = lbxClient->proxy;
 589 dawes 1.2     if (LbxIsClientBlocked (lbxClient) ||
 590 dawes 1.1 	((lbxClient != proxy->curDix) && proxy->curDix->reqs_pending &&
 591           	 !LbxIsClientBlocked(proxy->curDix)))
 592           	return FALSE;
 593               lbxClient->input_blocked = FALSE;
 594               DBG (DBG_BLOCK, (stderr, "client %d no longer blocked, switching\n",
 595           		     client->index));
 596               SwitchClientInput (client, TRUE);
 597               proxy->curDix = lbxClient;
 598               return TRUE;
 599           }
 600           
 601           void
 602           LbxSetForBlock(lbxClient)
 603               LbxClientPtr lbxClient;
 604           {
 605               lbxClient->reqs_pending++;
 606               if (!lbxClient->input_blocked)
 607               {
 608           	lbxClient->input_blocked = TRUE;
 609           	QueueWorkProc(LbxWaitForUnblocked, lbxClient->client, NULL);
 610               }
 611 dawes 1.1 }
 612           
 613           /* ARGSUSED */
 614           static int
 615           LbxWaitForUngrab (client, closure)
 616               ClientPtr	client;
 617               pointer	closure;
 618           {
 619               LbxClientPtr lbxClient = LbxClient(client);
 620               LbxProxyPtr  proxy;
 621               xLbxListenToAllEvent ungrabEvent;
 622           
 623               if (client->clientGone || !lbxClient)
 624           	return TRUE;
 625               if (GrabInProgress)
 626           	return FALSE;
 627               proxy = lbxClient->proxy;
 628               proxy->grabClient = 0;
 629               ungrabEvent.type = LbxEventCode;
 630               ungrabEvent.lbxType = LbxListenToAll;
 631               ungrabEvent.pad1 = ungrabEvent.pad2 = ungrabEvent.pad3 =
 632 dawes 1.1 	ungrabEvent.pad4 = ungrabEvent.pad5 = ungrabEvent.pad6 =
 633           	ungrabEvent.pad7 = 0;
 634               WriteToClient (client,
 635           		   sizeof(xLbxListenToAllEvent), (char *)&ungrabEvent);
 636               LbxForceOutput(proxy);
 637               return TRUE;
 638           }
 639           
 640           static void
 641           LbxServerGrab(proxy)
 642               LbxProxyPtr proxy;
 643           {
 644               LbxClientPtr	grabbingLbxClient;
 645               xLbxListenToOneEvent grabEvent;
 646           
 647               /*
 648                * If the current grabbing client has changed, then we need
 649                * to send a message to update the proxy.
 650                */
 651           
 652               grabEvent.type = LbxEventCode;
 653 dawes 1.1     grabEvent.lbxType = LbxListenToOne;
 654               if (!(grabbingLbxClient = lbxClients[GrabInProgress]) ||
 655           	grabbingLbxClient->proxy != proxy)
 656           	grabEvent.client = 0xffffffff; /* client other than a proxy client */
 657               else
 658           	grabEvent.client = grabbingLbxClient->id;
 659               grabEvent.pad1 = grabEvent.pad2 = grabEvent.pad3 =
 660           	grabEvent.pad4 = grabEvent.pad5 = grabEvent.pad6 = 0;
 661               if (LbxProxyClient(proxy)->swapped) {
 662           	int n;
 663           	swapl(&grabEvent.client, n);
 664               }
 665               WriteToClient(LbxProxyClient(proxy),
 666           		  sizeof(xLbxListenToOneEvent), (char *)&grabEvent);
 667               LbxForceOutput(proxy);
 668               if (!proxy->grabClient)
 669           	QueueWorkProc(LbxWaitForUngrab, LbxProxyClient(proxy), NULL);
 670               proxy->grabClient = GrabInProgress;
 671           }
 672           
 673           #define MAJOROP(client) ((xReq *)client->requestBuffer)->reqType
 674 dawes 1.1 #define MINOROP(client) ((xReq *)client->requestBuffer)->data
 675           
 676           static Bool lbxCacheable[] = {
 677           	FALSE,	/* LbxQueryVersion	  0 */
 678           	FALSE,	/* LbxStartProxy	  1 */
 679           	TRUE,	/* LbxStopProxy		  2 */
 680           	FALSE,	/* LbxSwitch		  3 */
 681           	FALSE,	/* LbxNewClient		  4 */
 682           	TRUE,	/* LbxCloseClient	  5 */
 683           	TRUE,	/* LbxModifySequence	  6 */
 684           	FALSE,	/* LbxAllowMotion	  7 */
 685           	TRUE,	/* LbxIncrementPixel	  8 */
 686           	FALSE,	/* LbxDelta		  9 */
 687           	TRUE,	/* LbxGetModifierMapping 10 */
 688           	FALSE,	/* nothing		 11 */
 689           	TRUE,	/* LbxInvalidateTag	 12 */
 690           	TRUE,	/* LbxPolyPoint		 13 */
 691           	TRUE,	/* LbxPolyLine		 14 */
 692           	TRUE,	/* LbxPolySegment	 15 */
 693           	TRUE,	/* LbxPolyRectangle	 16 */
 694           	TRUE,	/* LbxPolyArc		 17 */
 695 dawes 1.1 	TRUE,	/* LbxFillPoly		 18 */
 696           	TRUE,	/* LbxPolyFillRectangle	 19 */
 697           	TRUE,	/* LbxPolyFillArc	 20 */
 698           	TRUE,	/* LbxGetKeyboardMapping 21 */
 699           	TRUE,	/* LbxQueryFont		 22 */
 700           	TRUE,	/* LbxChangeProperty	 23 */
 701           	TRUE,	/* LbxGetProperty	 24 */
 702           	TRUE,	/* LbxTagData		 25 */
 703           	TRUE,	/* LbxCopyArea		 26 */
 704           	TRUE,	/* LbxCopyPlane		 27 */
 705           	TRUE,	/* LbxPolyText8		 28 */
 706           	TRUE,	/* LbxPolyText16	 29 */
 707           	TRUE,	/* LbxImageText8	 30 */
 708           	TRUE,	/* LbxImageText16	 31 */
 709           	FALSE,	/* LbxQueryExtension	 32 */
 710           	TRUE,	/* LbxPutImage		 33 */
 711           	TRUE,	/* LbxGetImage		 34 */
 712           	FALSE,	/* LbxBeginLargeRequest	 35 */
 713           	FALSE,	/* LbxLargeRequestData	 36 */
 714           	FALSE,	/* LbxEndLargeRequest	 37 */
 715           	FALSE,	/* LbxInternAtoms	 38 */
 716 dawes 1.1 	TRUE,	/* LbxGetWinAttrAndGeom  39 */
 717           	TRUE,	/* LbxGrabCmap		 40 */
 718           	TRUE,	/* LbxReleaseCmap	 41 */
 719           	TRUE,	/* LbxAllocColor	 42 */
 720           	TRUE,	/* LbxSync		 43 */
 721           };
 722           
 723           #define NUM(a)	(sizeof (a) / sizeof (a[0]))
 724           
 725           static int
 726           LbxReadRequestFromClient (client)
 727               ClientPtr	client;
 728           {
 729               int		    ret;
 730               LbxClientPtr    lbxClient = LbxClient(client);
 731               LbxProxyPtr	    proxy = lbxClient->proxy;
 732               ClientPtr	    masterClient = LbxProxyClient(proxy);
 733               Bool	    isblocked;
 734               Bool	    cacheable;
 735           
 736               DBG (DBG_READ_REQ, (stderr, "Reading request from client %d\n", client->index));
 737 dawes 1.1 
 738               if (GrabInProgress && (proxy->grabClient != GrabInProgress))
 739           	LbxServerGrab(proxy);
 740 dawes 1.2     isblocked = LbxIsClientBlocked(lbxClient);
 741 dawes 1.1 
 742               if (lbxClient->reqs_pending && !isblocked) {
 743           	ret = StandardReadRequestFromClient(client);
 744           	if (ret > 0 && (MAJOROP(client) == LbxReqCode) &&
 745           	    (MINOROP(client) == X_LbxEndLargeRequest))
 746           	    ret = PrepareLargeReqBuffer(client);
 747 dawes 1.4 	if (!--lbxClient->reqs_pending && (lbxClient != proxy->curRecv))
 748           	    LbxSwitchRecv (proxy, proxy->curRecv);
 749 dawes 1.1 	return ret;
 750               }
 751               while (1) {
 752           	ret = StandardReadRequestFromClient(masterClient);
 753           	if (ret <= 0)
 754           	    return ret;
 755           	client->requestBuffer = masterClient->requestBuffer;
 756           	client->req_len = masterClient->req_len;
 757           	cacheable = client->clientState == ClientStateRunning;
 758           	if (cacheable && (MAJOROP(client) == LbxReqCode)) {
 759           	    /* Check to see if this request is delta cached */
 760           	    if (MINOROP(client) < NUM(lbxCacheable))
 761           		cacheable = lbxCacheable[MINOROP(client)];
 762           	    switch (MINOROP(client)) {
 763           	    case X_LbxSwitch:
 764           		/* Switch is sent by proxy */
 765           		if (masterClient->swapped)
 766           		    SProcLbxSwitch (client);
 767           		else
 768           		    ProcLbxSwitch (client);
 769           		return 0;
 770 dawes 1.1 	    case X_LbxDelta:
 771           		ret = DecodeLbxDelta (client);
 772           		DBG(DBG_DELTA,
 773           		    (stderr,"delta decompressed msg %d, len = %d\n",
 774           		     (unsigned)((unsigned char *)client->requestBuffer)[0],
 775           		     ret));
 776           		break;
 777           	    case X_LbxEndLargeRequest:
 778           		if (!isblocked)
 779           		    ret = PrepareLargeReqBuffer(client);
 780           		break;
 781           	    }
 782           	}
 783           	if (cacheable && DELTA_CACHEABLE(&proxy->indeltas, ret)) {
 784           	    DBG(DBG_DELTA,
 785           		(stderr, "caching msg %d, len = %d, index = %d\n",
 786           		 (unsigned)((unsigned char *)client->requestBuffer)[0],
 787           		 ret, proxy->indeltas.nextDelta));
 788           	    LBXAddDeltaIn(&proxy->indeltas, client->requestBuffer, ret);
 789           	}
 790           	if (client->swapped != masterClient->swapped) {
 791 dawes 1.1 	    char        n;
 792           	    /* put length in client order */
 793           	    swaps(&((xReq *)client->requestBuffer)->length, n);
 794           	}
 795           	if (!isblocked)
 796           	    return ret;
 797           	DBG (DBG_BLOCK, (stderr, "Stashing %d bytes for %d\n", 
 798           			 ret, client->index));
 799           	AppendFakeRequest (client, client->requestBuffer, ret);
 800           	LbxSetForBlock(lbxClient);
 801               }
 802           }
 803           
 804           static LbxClientPtr
 805           LbxInitClient (proxy, client, id)
 806               LbxProxyPtr	proxy;
 807               ClientPtr	client;
 808               CARD32	id;
 809           {
 810               LbxClientPtr lbxClient;
 811               int i;
 812 dawes 1.1     
 813               lbxClient = (LbxClientPtr) xalloc (sizeof (LbxClientRec));
 814               if (!lbxClient)
 815           	return NULL;
 816               lbxClient->id = id;
 817               lbxClient->client = client;
 818               lbxClient->proxy = proxy;
 819               lbxClient->ignored = FALSE;
 820               lbxClient->input_blocked = FALSE;
 821               lbxClient->reqs_pending = 0;
 822               lbxClient->bytes_in_reply = 0;
 823               lbxClient->bytes_remaining = 0;
 824               client->readRequest = LbxReadRequestFromClient;
 825               bzero (lbxClient->drawableCache, sizeof (lbxClient->drawableCache));
 826               bzero (lbxClient->gcontextCache, sizeof (lbxClient->gcontextCache));
 827               lbxClients[client->index] = lbxClient;
 828               for (i = 0; proxy->lbxClients[i]; i++)
 829           	;
 830               if (i > proxy->maxIndex)
 831           	proxy->maxIndex = i;
 832               proxy->lbxClients[i] = lbxClient;
 833 dawes 1.1     proxy->numClients++;
 834               lbxClient->gfx_buffer = (pointer) NULL;
 835               lbxClient->gb_size = 0;
 836               return lbxClient;
 837           }
 838           
 839           static void
 840           LbxFreeClient (client)
 841               ClientPtr	client;
 842           {
 843               LbxClientPtr    lbxClient = LbxClient(client);
 844               LbxProxyPtr	    proxy = lbxClient->proxy;
 845               int		    i;
 846           
 847               if (lbxClient != proxy->lbxClients[0]) {
 848           	if (lbxClient == proxy->curRecv)
 849           	    LbxSwitchRecv(proxy, NULL);
 850           	else if (lbxClient == proxy->curDix)
 851           	    LbxSwitchRecv(proxy, proxy->curRecv);
 852               }
 853           	
 854 dawes 1.1     --proxy->numClients;
 855               lbxClients[client->index] = NULL;
 856               for (i = 0; i <= proxy->maxIndex; i++) {
 857           	if (proxy->lbxClients[i] == lbxClient) {
 858           	    proxy->lbxClients[i] = NULL;
 859           	    break;
 860           	}
 861               }
 862               while (proxy->maxIndex >= 0 && !proxy->lbxClients[proxy->maxIndex])
 863           	--proxy->maxIndex;
 864               xfree(lbxClient->gfx_buffer);
 865               client->readRequest = StandardReadRequestFromClient;
 866               xfree (lbxClient);
 867           }
 868           
 869           static void
 870           LbxFreeProxy (proxy)
 871               LbxProxyPtr proxy;
 872           {
 873               LbxProxyPtr *p;
 874           
 875 dawes 1.1     LBXFreeDeltaCache(&proxy->indeltas);
 876               LBXFreeDeltaCache(&proxy->outdeltas);
 877               LbxFreeOsBuffers(proxy);
 878               if (proxy->iDeltaBuf)
 879           	xfree(proxy->iDeltaBuf);
 880               if (proxy->replyBuf)
 881           	xfree(proxy->replyBuf);
 882               if (proxy->oDeltaBuf)
 883           	xfree(proxy->oDeltaBuf);
 884               if (proxy->compHandle)
 885           	proxy->streamOpts.streamCompFreeHandle(proxy->compHandle);
 886               if (proxy->bitmapCompMethods)
 887           	xfree (proxy->bitmapCompMethods);
 888               if (proxy->pixmapCompMethods)
 889           	xfree (proxy->pixmapCompMethods);
 890               if (proxy->pixmapCompDepths)
 891               {
 892           	int i;
 893           	for (i = 0; i < proxy->numPixmapCompMethods; i++)
 894           	    xfree (proxy->pixmapCompDepths[i]);
 895           	xfree (proxy->pixmapCompDepths);
 896 dawes 1.1     }
 897           
 898               for (p = &proxyList; *p; p = &(*p)->next) {
 899           	if (*p == proxy) {
 900           	    *p = proxy->next;
 901           	    break;
 902           	}
 903               }
 904               if (!proxyList)
 905           	DeleteCallback(&ReplyCallback, LbxReplyCallback, NULL);
 906           
 907               xfree (proxy);
 908           }
 909           
 910           LbxProxyPtr
 911           LbxPidToProxy(pid)
 912               int         pid;
 913           {
 914               LbxProxyPtr proxy;
 915           
 916               for (proxy = proxyList; proxy; proxy = proxy->next) {
 917 dawes 1.1 	if (proxy->pid == pid)
 918           	    return proxy;
 919               }
 920               return NULL;
 921           }
 922           
 923           static void
 924           LbxShutdownProxy (proxy)
 925               LbxProxyPtr	proxy;
 926           {
 927               int		    i;
 928               ClientPtr	    client;
 929           
 930               if (proxy->compHandle)
 931           	--lbxCompressWorkProcCount;
 932               while (proxy->grabbedCmaps)
 933           	LbxReleaseCmap(proxy->grabbedCmaps, FALSE);
 934               for (i = 0; i <= proxy->maxIndex; i++)
 935               {
 936           	if (proxy->lbxClients[i])
 937           	{
 938 dawes 1.1 	    client = proxy->lbxClients[i]->client;
 939           	    if (!client->clientGone)
 940           		CloseDownClient (client);
 941           	}
 942               }
 943               LbxFlushTags(proxy);
 944               LbxFreeProxy(proxy);
 945           }
 946           
 947           
 948           int
 949           ProcLbxQueryVersion(client)
 950               register ClientPtr client;
 951           {
 952               REQUEST(xLbxQueryVersionReq);
 953               xLbxQueryVersionReply rep;
 954               register int n;
 955           
 956               REQUEST_SIZE_MATCH(xLbxQueryVersionReq);
 957               rep.type = X_Reply;
 958               rep.length = 0;
 959 dawes 1.1     rep.sequenceNumber = client->sequence;
 960               rep.majorVersion = LBX_MAJOR_VERSION;
 961               rep.minorVersion = LBX_MINOR_VERSION;
 962               rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
 963           
 964               if (client->swapped) {
 965               	swaps(&rep.sequenceNumber, n);
 966               	swapl(&rep.length, n);
 967           	swaps(&rep.majorVersion, n);
 968           	swaps(&rep.minorVersion, n);
 969               }
 970               WriteToClient(client, sizeof(xLbxQueryVersionReply), (char *)&rep);
 971               return (client->noClientException);
 972           }
 973           
 974           static int
 975           NextProxyID()
 976           {
 977               LbxProxyPtr proxy;
 978               int         id;
 979           
 980 dawes 1.1     for (id = 1; id < MAX_NUM_PROXIES; id++) {
 981           	for (proxy = proxyList; proxy && proxy->pid != id; proxy = proxy->next)
 982           	    ;
 983           	if (!proxy)
 984           	    return id;
 985               }
 986               return -1;
 987           }
 988           
 989           int
 990           ProcLbxStartProxy(client)
 991               register ClientPtr	client;
 992           {
 993               REQUEST(xLbxStartProxyReq);
 994               LbxProxyPtr	    proxy;
 995               LbxClientPtr    lbxClient;
 996               int		    reqlen;
 997               int		    replylen;
 998               xLbxStartReply  *replybuf;
 999               LbxNegOptsRec   negopt;
1000               register int    n;
1001 dawes 1.1     pointer	    compHandle = NULL;
1002           
1003               REQUEST_AT_LEAST_SIZE(xLbxStartProxyReq);
1004               if (lbxClients[client->index])
1005           	return BadLbxClientCode;
1006               proxy = (LbxProxyPtr) xalloc (sizeof (LbxProxyRec));
1007               if (!proxy)
1008           	return BadAlloc;
1009               bzero(proxy, sizeof (LbxProxyRec));
1010               proxy->pid = NextProxyID();
1011               if (proxy->pid < 0) {	/* too many proxies */
1012           	xfree(proxy);
1013           	return BadAlloc;
1014               }
1015               proxy->uid = ++uid_seed;
1016               if (!proxyList)
1017           	AddCallback(&ReplyCallback, LbxReplyCallback, NULL);
1018           
1019               if(!proxyList)
1020           	proxyList = proxy;
1021               else{
1022 dawes 1.1 	proxy->next = proxyList;
1023           	proxyList = proxy;
1024               }
1025           
1026               /*
1027                * Don't know exactly how big the reply will be, but it won't be
1028                * bigger than the request
1029                */
1030               reqlen = client->req_len << 2;
1031               replybuf = (xLbxStartReply *) xalloc(max(reqlen, sz_xLbxStartReply));
1032               if (!replybuf) {
1033           	LbxFreeProxy(proxy);
1034           	return BadAlloc;
1035               }
1036           
1037               LbxOptionInit(&negopt);
1038           
1039               replylen = LbxOptionParse(&negopt,
1040           			      &stuff[1],
1041           			      reqlen - sz_xLbxStartProxyReq,
1042           			      &replybuf->optDataStart);
1043 dawes 1.1     if (replylen < 0) {
1044           	/*
1045           	 * Didn't understand option format, so we'll just end up
1046           	 * using the defaults.  Set nopts so that the proxy will
1047           	 * be informed that we rejected the options because of
1048           	 * decoding problems.
1049           	 */
1050           	LbxOptionInit(&negopt);
1051           	negopt.nopts = 0xff;
1052           	replylen = 0;
1053               }
1054           
1055               if (LBXInitDeltaCache(&proxy->indeltas, negopt.proxyDeltaN,
1056           			  negopt.proxyDeltaMaxLen) < 0
1057           			||
1058           	LBXInitDeltaCache(&proxy->outdeltas, negopt.serverDeltaN,
1059           			  negopt.serverDeltaMaxLen) < 0) {
1060           	LbxFreeProxy(proxy);
1061           	xfree(replybuf);
1062           	return BadAlloc;
1063               }
1064 dawes 1.1 
1065               n = 0;
1066               if (negopt.proxyDeltaN)
1067           	n = negopt.proxyDeltaMaxLen;
1068               if (negopt.serverDeltaN && negopt.serverDeltaMaxLen > n)
1069           	n = negopt.serverDeltaMaxLen;
1070               if (n &&
1071           	(!(proxy->iDeltaBuf = (char *)xalloc (n)) ||
1072           	 !(proxy->replyBuf = (char *)xalloc (n)) ||
1073           	 !(proxy->oDeltaBuf = (char *)xalloc (n)))) {
1074           	LbxFreeProxy(proxy);
1075           	xfree(replybuf);
1076           	return BadAlloc;
1077               }
1078           
1079               MakeClientGrabImpervious(client);	/* proxy needs to be grab-proof */
1080               proxy->fd = ClientConnectionNumber(client);
1081               if (negopt.streamOpts.streamCompInit) {
1082           	compHandle =
1083           	    (*negopt.streamOpts.streamCompInit)(proxy->fd, negopt.streamOpts.streamCompArg);
1084           	if (!compHandle) {
1085 dawes 1.1 	    LbxFreeProxy(proxy);
1086           	    xfree(replybuf);
1087           	    return BadAlloc;
1088           	}
1089               }
1090               proxy->ofirst = NULL;
1091               proxy->olast = NULL;
1092               if (!LbxInitClient (proxy, client, 0))
1093               {
1094           	LbxFreeProxy(proxy);
1095           	xfree(replybuf);
1096           	return BadAlloc;
1097               }
1098               proxy->dosquishing = negopt.squish;
1099               proxy->numBitmapCompMethods = negopt.numBitmapCompMethods;
1100               proxy->bitmapCompMethods = negopt.bitmapCompMethods;
1101               proxy->numPixmapCompMethods = negopt.numPixmapCompMethods;
1102               proxy->pixmapCompMethods = negopt.pixmapCompMethods;
1103               proxy->pixmapCompDepths = negopt.pixmapCompDepths;
1104           
1105               proxy->streamOpts = negopt.streamOpts;
1106 dawes 1.1     proxy->useTags = negopt.useTags;
1107           
1108               proxy->grabbedCmaps = NULL;
1109           
1110               /* send reply */
1111               replybuf->type = X_Reply;
1112               replybuf->nOpts = negopt.nopts;
1113               replybuf->sequenceNumber = client->sequence;
1114           
1115               replylen += sz_xLbxStartReplyHdr;
1116               if (replylen < sz_xLbxStartReply)
1117           	replylen = sz_xLbxStartReply;
1118               replybuf->length = (replylen - sz_xLbxStartReply + 3) >> 2;
1119               if (client->swapped) {
1120           	swaps(&replybuf->sequenceNumber, n);
1121           	swapl(&replybuf->length, n);
1122               }
1123               lbxClient = LbxClient(client);
1124               WriteToClient(client, replylen, (char *)replybuf);
1125           
1126               LbxProxyConnection(client, proxy);
1127 dawes 1.1     lbxClient = proxy->lbxClients[0];
1128               proxy->curDix = lbxClient;
1129               proxy->curRecv = lbxClient;
1130               proxy->compHandle = compHandle;
1131           
1132               if (proxy->compHandle && !lbxCompressWorkProcCount++)
1133           	QueueWorkProc(LbxCheckCompressInput, NULL, NULL);
1134           
1135               xfree(replybuf);
1136               return Success;
1137           }
1138           
1139           int
1140           ProcLbxStopProxy(client)
1141               register ClientPtr	client;
1142           {
1143               REQUEST(xLbxStopProxyReq);
1144               LbxProxyPtr	    proxy;
1145               LbxClientPtr    lbxClient = LbxClient(client);
1146           
1147               REQUEST_SIZE_MATCH(xLbxStopProxyReq);
1148 dawes 1.1 
1149               if (!lbxClient)
1150           	return BadLbxClientCode;
1151               if (lbxClient->id)
1152           	return BadLbxClientCode;
1153               
1154               proxy = lbxClient->proxy;
1155               LbxFreeClient (client);
1156               LbxShutdownProxy (proxy);
1157               return Success;
1158           }
1159               
1160           int
1161           ProcLbxSwitch(client)
1162               register ClientPtr	client;
1163           {
1164               REQUEST(xLbxSwitchReq);
1165               LbxProxyPtr	proxy = LbxMaybeProxy(client);
1166               LbxClientPtr lbxClient;
1167               int i;
1168           
1169 dawes 1.1     REQUEST_SIZE_MATCH(xLbxSwitchReq);
1170               if (!proxy)
1171           	return BadLbxClientCode;
1172               for (i = 0; i <= proxy->maxIndex; i++) {
1173           	lbxClient = proxy->lbxClients[i];
1174           	if (lbxClient && lbxClient->id == stuff->client) {
1175           	    LbxSwitchRecv (proxy, lbxClient);
1176           	    return Success;
1177           	}
1178               }
1179               LbxSwitchRecv (proxy, NULL);
1180               return BadLbxClientCode;
1181           }
1182           
1183           int
1184           ProcLbxBeginLargeRequest(client)
1185               register ClientPtr	client;
1186           {
1187               REQUEST(xLbxBeginLargeRequestReq);
1188           
1189               client->sequence--;
1190 dawes 1.1     REQUEST_SIZE_MATCH(xLbxBeginLargeRequestReq);
1191               if (!AllocateLargeReqBuffer(client, stuff->largeReqLength << 2))
1192           	return BadAlloc;
1193               return Success;
1194           }
1195           
1196           
1197           int
1198           ProcLbxLargeRequestData(client)
1199               register ClientPtr	client;
1200           {
1201               REQUEST(xLbxLargeRequestDataReq);
1202           
1203               client->sequence--;
1204               REQUEST_AT_LEAST_SIZE(xLbxLargeRequestDataReq);
1205               if (!AddToLargeReqBuffer(client, (char *) (stuff + 1),
1206           			     (client->req_len - 1) << 2))
1207           	return BadAlloc;
1208               return Success;
1209           }
1210           
1211 dawes 1.1 
1212           int
1213           ProcLbxEndLargeRequest(client)
1214               register ClientPtr	client;
1215           {
1216               REQUEST(xReq);
1217           
1218               client->sequence--;
1219               REQUEST_SIZE_MATCH(xReq);
1220               return BadAlloc;
1221           }
1222           
1223           
1224           int
1225           ProcLbxInternAtoms(client)
1226               register ClientPtr	client;
1227           {
1228               REQUEST(xLbxInternAtomsReq);
1229               LbxClientPtr lbxClient = LbxClient(client);
1230               xLbxInternAtomsReply *replyRet;
1231               char *ptr = (char *) stuff + sz_xLbxInternAtomsReq;
1232 dawes 1.1     Atom *atomsRet;
1233               int replyLen, i;
1234               char lenbuf[2];
1235               CARD16 len;
1236               char n;
1237           
1238               REQUEST_AT_LEAST_SIZE(xLbxInternAtomsReq);
1239           
1240               if (!lbxClient)
1241           	return BadLbxClientCode;
1242               if (lbxClient->id)
1243           	return BadLbxClientCode;
1244           
1245               replyLen = sz_xLbxInternAtomsReplyHdr + stuff->num * sizeof (Atom);
1246               if (replyLen < sz_xLbxInternAtomsReply)
1247           	replyLen = sz_xLbxInternAtomsReply;
1248           
1249               if (!(replyRet = (xLbxInternAtomsReply *) xalloc (replyLen)))
1250           	return BadAlloc;
1251           
1252               atomsRet = (Atom *) ((char *) replyRet + sz_xLbxInternAtomsReplyHdr);
1253 dawes 1.1 
1254               for (i = 0; i < stuff->num; i++)
1255               {
1256           	lenbuf[0] = ptr[0];
1257           	lenbuf[1] = ptr[1];
1258           	len = *((CARD16 *) lenbuf);
1259           	ptr += 2;
1260           
1261           	if ((atomsRet[i] = MakeAtom (ptr, len, TRUE)) == BAD_RESOURCE)
1262           	{
1263           	    xfree (replyRet);
1264           	    return BadAlloc;
1265           	}	    
1266           
1267           	ptr += len;
1268               }
1269           
1270               if (client->swapped)
1271           	for (i = 0; i < stuff->num; i++)
1272           	    swapl (&atomsRet[i], n);
1273           
1274 dawes 1.1     replyRet->type = X_Reply;
1275               replyRet->sequenceNumber = client->sequence;
1276               replyRet->length = (replyLen - sz_xLbxInternAtomsReply + 3) >> 2;
1277           
1278               if (client->swapped) {
1279           	swaps(&replyRet->sequenceNumber, n);
1280           	swapl(&replyRet->length, n);
1281               }
1282           
1283               WriteToClient (client, replyLen, (char *) replyRet);
1284           
1285               xfree (replyRet);
1286           
1287               return Success;
1288           }
1289           
1290           
1291           int
1292           ProcLbxGetWinAttrAndGeom(client)
1293               register ClientPtr	client;
1294           {
1295 dawes 1.1     REQUEST(xLbxGetWinAttrAndGeomReq);
1296               xGetWindowAttributesReply wa;
1297               xGetGeometryReply wg;
1298               xLbxGetWinAttrAndGeomReply reply;
1299               WindowPtr pWin;
1300               int status;
1301           
1302               REQUEST_SIZE_MATCH(xLbxGetWinAttrAndGeomReq);
1303               pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
1304           					   SecurityReadAccess);
1305               if (!pWin)
1306                   return(BadWindow);
1307               GetWindowAttributes(pWin, client, &wa);
1308           
1309               if ((status = GetGeometry(client, &wg)) != Success)
1310           	return status;
1311           
1312               reply.type = X_Reply;
1313               reply.length = (sz_xLbxGetWinAttrAndGeomReply - 32) >> 2;
1314               reply.sequenceNumber = client->sequence;
1315           
1316 dawes 1.1     reply.backingStore = wa.backingStore;
1317               reply.visualID = wa.visualID;
1318           #if defined(__cplusplus) || defined(c_plusplus)
1319               reply.c_class = wa.c_class;
1320           #else
1321               reply.class = wa.class;
1322           #endif
1323               reply.bitGravity = wa.bitGravity;
1324               reply.winGravity = wa.winGravity;
1325               reply.backingBitPlanes = wa.backingBitPlanes;
1326               reply.backingPixel = wa.backingPixel;
1327               reply.saveUnder = wa.saveUnder;
1328               reply.mapInstalled = wa.mapInstalled;
1329               reply.mapState = wa.mapState;
1330               reply.override = wa.override;
1331               reply.colormap = wa.colormap;
1332               reply.allEventMasks = wa.allEventMasks;
1333               reply.yourEventMask = wa.yourEventMask;
1334               reply.doNotPropagateMask = wa.doNotPropagateMask;
1335               reply.pad1 = 0;
1336               reply.root = wg.root;
1337 dawes 1.1     reply.x = wg.x;
1338               reply.y = wg.y;
1339               reply.width = wg.width;
1340               reply.height = wg.height;
1341               reply.borderWidth = wg.borderWidth;
1342               reply.depth = wg.depth;
1343               reply.pad2 = 0;
1344           
1345               if (client->swapped)
1346               {
1347           	register char n;
1348           
1349           	swaps(&reply.sequenceNumber, n);
1350           	swapl(&reply.length, n);
1351           	swapl(&reply.visualID, n);
1352           	swaps(&reply.class, n);
1353           	swapl(&reply.backingBitPlanes, n);
1354           	swapl(&reply.backingPixel, n);
1355           	swapl(&reply.colormap, n);
1356           	swapl(&reply.allEventMasks, n);
1357           	swapl(&reply.yourEventMask, n);
1358 dawes 1.1 	swaps(&reply.doNotPropagateMask, n);
1359           	swapl(&reply.root, n);
1360           	swaps(&reply.x, n);
1361           	swaps(&reply.y, n);
1362           	swaps(&reply.width, n);
1363           	swaps(&reply.height, n);
1364           	swaps(&reply.borderWidth, n);
1365               }
1366           
1367               WriteToClient(client, sizeof(xLbxGetWinAttrAndGeomReply), (char *)&reply);
1368               return(client->noClientException);
1369           }
1370           
1371           int
1372           ProcLbxNewClient(client)
1373               register ClientPtr client;
1374           {
1375               REQUEST(xLbxNewClientReq);
1376               ClientPtr	    newClient;
1377               LbxProxyPtr	    proxy = LbxMaybeProxy(client);
1378               CARD32	    id;
1379 dawes 1.1     int		    len, i;
1380               char	    *setupbuf;
1381               LbxClientPtr    lbxClient;
1382           
1383               REQUEST_AT_LEAST_SIZE(xLbxNewClientReq);
1384           
1385               /* save info before our request disappears */
1386               id = stuff->client;
1387               if (!proxy || !id)
1388           	return BadLbxClientCode;
1389               if (proxy->numClients == MAX_LBX_CLIENTS)
1390           	return BadAlloc;
1391               for (i = 1; i <= proxy->maxIndex; i++) {
1392           	if (proxy->lbxClients[i] && proxy->lbxClients[i]->id == id)
1393           	    return BadLbxClientCode;
1394               }
1395               len = (client->req_len << 2) - sizeof(xLbxNewClientReq);
1396               setupbuf = (char *)xalloc (len);
1397               if (!setupbuf)
1398           	return BadAlloc;
1399               memcpy (setupbuf, (char *)&stuff[1], len);
1400 dawes 1.1 
1401               newClient = AllocLbxClientConnection (client, proxy);
1402               if (!newClient)
1403           	return BadAlloc;
1404 dawes 1.2     newClient->requestVector = LbxInitialVector;
1405 dawes 1.1     lbxClient = LbxInitClient (proxy, newClient, id);
1406               if (!lbxClient)
1407               {
1408           	CloseDownClient (newClient);
1409           	return BadAlloc;
1410               }
1411               
1412               AppendFakeRequest (newClient, setupbuf, len);
1413               xfree (setupbuf);
1414               LbxSetForBlock(lbxClient);
1415           
1416               DBG (DBG_CLIENT, (stderr, "lbxNewClient X %d\n", newClient->index));
1417               return Success;
1418           }
1419           
1420           int
1421           ProcLbxEstablishConnection(client)
1422               register ClientPtr client;
1423           {
1424               char *reason = NULL;
1425               char *auth_proto, *auth_string;
1426 dawes 1.1     register xConnClientPrefix *prefix;
1427               REQUEST(xReq);
1428           
1429               prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
1430               auth_proto = (char *)prefix + sz_xConnClientPrefix;
1431               auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
1432               if ((prefix->majorVersion != X_PROTOCOL) ||
1433           	(prefix->minorVersion != X_PROTOCOL_REVISION))
1434           	reason = "Protocol version mismatch";
1435               else
1436           	reason = ClientAuthorized(client,
1437           				  prefix->nbytesAuthProto,
1438           				  auth_proto,
1439           				  prefix->nbytesAuthString,
1440           				  auth_string);
1441           
1442               if (client->clientState == ClientStateCheckingSecurity ||
1443           	client->clientState == ClientStateAuthenticating)
1444           	return (client->noClientException = -1); /* XXX some day */
1445               return(LbxSendConnSetup(client, reason));
1446           }
1447 dawes 1.1 
1448           int
1449           ProcLbxCloseClient (client)
1450               register ClientPtr	client;
1451           {
1452               REQUEST(xLbxCloseClientReq);
1453               LbxClientPtr lbxClient = LbxClient(client);
1454           
1455               REQUEST_SIZE_MATCH(xLbxCloseClientReq);
1456               if (!lbxClient || lbxClient->id != stuff->client)
1457           	return BadLbxClientCode;
1458           
1459               /* this will cause the client to be closed down back in Dispatch() */
1460               return(client->noClientException = CloseLbxClient);
1461           }
1462           
1463           int
1464           ProcLbxModifySequence (client)
1465               register ClientPtr	client;
1466           {
1467               REQUEST(xLbxModifySequenceReq);
1468 dawes 1.1 
1469               REQUEST_SIZE_MATCH(xLbxModifySequenceReq);
1470               client->sequence += (stuff->adjust - 1);	/* Dispatch() adds 1 */
1471               return Success;
1472           }
1473           
1474           int
1475           ProcLbxAllowMotion (client)
1476               register ClientPtr	client;
1477           {
1478               REQUEST(xLbxAllowMotionReq);
1479           
1480               client->sequence--;
1481               REQUEST_SIZE_MATCH(xLbxAllowMotionReq);
1482               LbxAllowMotion(client, stuff->num);
1483               return Success;
1484           }
1485           
1486           
1487           static int
1488           DecodeLbxDelta(client)
1489 dawes 1.1     register ClientPtr	client;
1490           {
1491               REQUEST(xLbxDeltaReq);
1492               LbxClientPtr    lbxClient = LbxClient(client);
1493               LbxProxyPtr	    proxy = lbxClient->proxy;
1494               int		    len;
1495               char	    *buf;
1496           
1497               /* Note that LBXDecodeDelta decodes and adds current msg to the cache */
1498               len = LBXDecodeDelta(&proxy->indeltas, ((char *)stuff) + sz_xLbxDeltaReq,
1499           			 stuff->diffs, stuff->cindex, &buf);
1500               /*
1501                * Some requests, such as FillPoly, result in the protocol input
1502                * buffer being modified.  So we need to copy the request
1503                * into a temporary buffer where a write would be harmless.
1504                * Maybe some day do this copying on a case by case basis,
1505                * since not all requests are guilty of this.
1506                */
1507               memcpy(proxy->iDeltaBuf, buf, len);
1508           
1509               client->requestBuffer = proxy->iDeltaBuf;
1510 dawes 1.1     client->req_len = len >> 2;
1511               return len;
1512           }
1513           
1514           int
1515           ProcLbxGetModifierMapping(client)
1516               ClientPtr	client;
1517           {
1518               REQUEST(xLbxGetModifierMappingReq);
1519           
1520               REQUEST_SIZE_MATCH(xLbxGetModifierMappingReq);
1521               return LbxGetModifierMapping(client);
1522           }
1523           
1524           int
1525           ProcLbxGetKeyboardMapping(client)
1526               ClientPtr	client;
1527           {
1528               REQUEST(xLbxGetKeyboardMappingReq);
1529           
1530               REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
1531 dawes 1.1     return LbxGetKeyboardMapping(client);
1532           }
1533           
1534           int
1535           ProcLbxQueryFont(client)
1536               ClientPtr	client;
1537           {
1538               REQUEST(xLbxQueryFontReq);
1539           
1540               REQUEST_SIZE_MATCH(xLbxQueryFontReq);
1541               return LbxQueryFont(client);
1542           }
1543           
1544           int
1545           ProcLbxChangeProperty(client)
1546               ClientPtr	client;
1547           {
1548               REQUEST(xLbxChangePropertyReq);
1549           
1550               REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
1551               return LbxChangeProperty(client);
1552 dawes 1.1 }
1553           
1554           int
1555           ProcLbxGetProperty(client)
1556               ClientPtr	client;
1557           {
1558               REQUEST(xLbxGetPropertyReq);
1559           
1560               REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
1561               return LbxGetProperty(client);
1562           }
1563           
1564           int
1565           ProcLbxTagData(client)
1566               ClientPtr	client;
1567           {
1568               REQUEST(xLbxTagDataReq);
1569           
1570               client->sequence--;		/* not a counted request */
1571               REQUEST_AT_LEAST_SIZE(xLbxTagDataReq);
1572           
1573 dawes 1.1     return LbxTagData(client, stuff->tag, stuff->real_length,
1574               		 (pointer)&stuff[1]);	/* better not give any errors */
1575           }
1576           
1577           int
1578           ProcLbxInvalidateTag(client)
1579               ClientPtr	client;
1580           {
1581               REQUEST(xLbxInvalidateTagReq);
1582           
1583               client->sequence--;
1584               REQUEST_SIZE_MATCH(xLbxInvalidateTagReq);
1585               return LbxInvalidateTag(client, stuff->tag);
1586           }
1587           
1588           int
1589           ProcLbxPolyPoint(client)
1590               register ClientPtr	client;
1591           {
1592               return LbxDecodePoly(client, X_PolyPoint, LbxDecodePoints);
1593           }
1594 dawes 1.1 
1595           int
1596           ProcLbxPolyLine(client)
1597               register ClientPtr	client;
1598           {
1599               return LbxDecodePoly(client, X_PolyLine, LbxDecodePoints);
1600           }
1601           
1602           int
1603           ProcLbxPolySegment(client)
1604               register ClientPtr	client;
1605           {
1606               return LbxDecodePoly(client, X_PolySegment, LbxDecodeSegment);
1607           }
1608           
1609           int
1610           ProcLbxPolyRectangle(client)
1611               register ClientPtr	client;
1612           {
1613               return LbxDecodePoly(client, X_PolyRectangle, LbxDecodeRectangle);
1614           }
1615 dawes 1.1 
1616           int
1617           ProcLbxPolyArc(client)
1618               register ClientPtr	client;
1619           {
1620               return LbxDecodePoly(client, X_PolyArc, LbxDecodeArc);
1621           }
1622           
1623           int
1624           ProcLbxFillPoly(client)
1625               register ClientPtr	client;
1626           {
1627               return LbxDecodeFillPoly(client);
1628           }
1629           
1630           int
1631           ProcLbxPolyFillRectangle(client)
1632               register ClientPtr	client;
1633           {
1634               return LbxDecodePoly(client, X_PolyFillRectangle, LbxDecodeRectangle);
1635           }
1636 dawes 1.1 
1637           int
1638           ProcLbxPolyFillArc(client)
1639               register ClientPtr	client;
1640           {
1641               return LbxDecodePoly(client, X_PolyFillArc, LbxDecodeArc);
1642           }
1643           
1644           int
1645           ProcLbxCopyArea (client)
1646               register ClientPtr	client;
1647           {
1648               return LbxDecodeCopyArea(client);
1649           }
1650           
1651           int
1652           ProcLbxCopyPlane (client)
1653               register ClientPtr	client;
1654           {
1655               return LbxDecodeCopyPlane(client);
1656           }
1657 dawes 1.1 
1658           
1659           int
1660           ProcLbxPolyText (client)
1661               register ClientPtr	client;
1662           {
1663               return LbxDecodePolyText(client);
1664           }
1665           
1666           int
1667           ProcLbxImageText (client)
1668               register ClientPtr	client;
1669           {
1670               return LbxDecodeImageText(client);
1671           }
1672           
1673           int
1674           ProcLbxQueryExtension(client)
1675               ClientPtr	client;
1676           {
1677               REQUEST(xLbxQueryExtensionReq);
1678 dawes 1.1     char	*ename;
1679           
1680               REQUEST_AT_LEAST_SIZE(xLbxQueryExtensionReq);
1681               ename = (char *) &stuff[1];
1682               return LbxQueryExtension(client, ename, stuff->nbytes);
1683           }
1684           
1685           int
1686           ProcLbxPutImage(client)
1687               register ClientPtr	client;
1688           {
1689               return LbxDecodePutImage(client);
1690           }
1691           
1692           int
1693           ProcLbxGetImage(client)
1694               register ClientPtr	client;
1695           {
1696               return LbxDecodeGetImage(client);
1697           }
1698           
1699 dawes 1.1 
1700           int
1701           ProcLbxSync(client)
1702               register ClientPtr	client;
1703           {
1704               xLbxSyncReply reply;
1705           
1706               client->sequence--;		/* not a counted request */
1707           
1708           #ifdef COLOR_DEBUG
1709               fprintf (stderr, "Got LBX sync, seq = 0x%x\n", client->sequence);
1710           #endif
1711           
1712               reply.type = X_Reply;
1713               reply.length = 0;
1714               reply.sequenceNumber = client->sequence;
1715               reply.pad0 = reply.pad1 = reply.pad2 = reply.pad3 = reply.pad4 = 
1716                   reply.pad5 = reply.pad6 = 0;
1717           
1718               if (client->swapped)
1719               {
1720 dawes 1.1 	register char n;
1721           	swaps (&reply.sequenceNumber, n);
1722               }
1723           
1724               WriteToClient (client, sz_xLbxSyncReply, (char *)&reply);
1725           
1726               return (client->noClientException);
1727           }
1728           
1729           
1730           int
1731           ProcLbxDispatch (client)
1732               register ClientPtr	client;
1733           {
1734               REQUEST(xReq);
1735               switch (stuff->data)
1736               {
1737               case X_LbxQueryVersion:
1738           	return ProcLbxQueryVersion(client);
1739               case X_LbxStartProxy:
1740           	return ProcLbxStartProxy(client);
1741 dawes 1.1     case X_LbxStopProxy:
1742           	return ProcLbxStopProxy(client);
1743               case X_LbxNewClient:
1744           	return ProcLbxNewClient(client);
1745               case X_LbxCloseClient:
1746           	return ProcLbxCloseClient(client);
1747               case X_LbxModifySequence:
1748           	return ProcLbxModifySequence(client);
1749               case X_LbxAllowMotion:
1750           	return ProcLbxAllowMotion(client);
1751               case X_LbxIncrementPixel:
1752           	return ProcLbxIncrementPixel(client);
1753               case X_LbxGrabCmap:
1754           	return ProcLbxGrabCmap(client);
1755               case X_LbxReleaseCmap:
1756           	return ProcLbxReleaseCmap(client);
1757               case X_LbxAllocColor:
1758           	return ProcLbxAllocColor(client);
1759               case X_LbxGetModifierMapping:
1760           	return ProcLbxGetModifierMapping(client);
1761               case X_LbxGetKeyboardMapping:
1762 dawes 1.1 	return ProcLbxGetKeyboardMapping(client);
1763               case X_LbxInvalidateTag:
1764           	return ProcLbxInvalidateTag(client);
1765               case X_LbxPolyPoint:
1766           	return ProcLbxPolyPoint (client);
1767               case X_LbxPolyLine:
1768           	return ProcLbxPolyLine (client);
1769               case X_LbxPolySegment:
1770           	return ProcLbxPolySegment (client);
1771               case X_LbxPolyRectangle:
1772           	return ProcLbxPolyRectangle (client);
1773               case X_LbxPolyArc:
1774           	return ProcLbxPolyArc (client);
1775               case X_LbxFillPoly:
1776           	return ProcLbxFillPoly (client);
1777               case X_LbxPolyFillRectangle:
1778           	return ProcLbxPolyFillRectangle (client);
1779               case X_LbxPolyFillArc:
1780           	return ProcLbxPolyFillArc (client);
1781               case X_LbxQueryFont:
1782           	return ProcLbxQueryFont (client);
1783 dawes 1.1     case X_LbxChangeProperty:
1784           	return ProcLbxChangeProperty (client);
1785               case X_LbxGetProperty:
1786           	return ProcLbxGetProperty (client);
1787               case X_LbxTagData:
1788           	return ProcLbxTagData (client);
1789               case X_LbxCopyArea:
1790           	return ProcLbxCopyArea (client);
1791               case X_LbxCopyPlane:
1792           	return ProcLbxCopyPlane (client);
1793               case X_LbxPolyText8:
1794               case X_LbxPolyText16:
1795           	return ProcLbxPolyText (client);
1796               case X_LbxImageText8:
1797               case X_LbxImageText16:
1798           	return ProcLbxImageText (client);
1799               case X_LbxQueryExtension:
1800           	return ProcLbxQueryExtension (client);
1801               case X_LbxPutImage:
1802           	return ProcLbxPutImage (client);
1803               case X_LbxGetImage:
1804 dawes 1.1 	return ProcLbxGetImage (client);
1805               case X_LbxInternAtoms:
1806           	return ProcLbxInternAtoms(client);
1807               case X_LbxGetWinAttrAndGeom:
1808           	return ProcLbxGetWinAttrAndGeom(client);
1809               case X_LbxSync:
1810           	return ProcLbxSync(client);
1811               case X_LbxBeginLargeRequest:
1812           	return ProcLbxBeginLargeRequest(client);
1813               case X_LbxLargeRequestData:
1814           	return ProcLbxLargeRequestData(client);
1815               case X_LbxEndLargeRequest:
1816           	return ProcLbxLargeRequestData(client);
1817               default:
1818           	return BadRequest;
1819               }
1820           }

Powered by
ViewCVS 0.9.2