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 }
|