summaryrefslogtreecommitdiff
path: root/lbx
diff options
context:
space:
mode:
Diffstat (limited to 'lbx')
-rw-r--r--lbx/lbxcmap.c1148
-rw-r--r--lbx/lbxdata.h44
-rw-r--r--lbx/lbxdix.c887
-rw-r--r--lbx/lbxexts.c270
-rw-r--r--lbx/lbxgfx.c867
-rw-r--r--lbx/lbxmain.c1819
-rw-r--r--lbx/lbxopts.c817
-rw-r--r--lbx/lbxprop.c552
-rw-r--r--lbx/lbxserve.h173
-rw-r--r--lbx/lbxsquish.c152
-rw-r--r--lbx/lbxsrvopts.h78
-rw-r--r--lbx/lbxswap.c858
-rw-r--r--lbx/lbxtables.c33
-rw-r--r--lbx/lbxtags.c238
-rw-r--r--lbx/lbxtags.h119
-rw-r--r--lbx/lbxzerorep.c416
16 files changed, 8471 insertions, 0 deletions
diff --git a/lbx/lbxcmap.c b/lbx/lbxcmap.c
new file mode 100644
index 000000000..6af20b03b
--- /dev/null
+++ b/lbx/lbxcmap.c
@@ -0,0 +1,1148 @@
+/* $Xorg: lbxcmap.c,v 1.4 2001/02/09 02:05:16 xorgcvs Exp $ */
+
+/*
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+*/
+
+#include <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "Xfuncproto.h"
+#include <stdio.h>
+
+static int lbxScreenPrivIndex; /* lbx screen private index */
+static int lbxColormapPrivIndex; /* lbx colormap private index */
+
+typedef struct { /* lbx screen private */
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+} LbxScreenPriv;
+
+typedef struct _LbxStalled {
+ XID id;
+ struct _LbxStalled *next;
+} LbxStalled;
+
+typedef struct _LbxColormapPriv { /* lbx colormap private */
+ char grab_status;
+ char smart_grab;
+ LbxProxyPtr grabber;
+ int last_grabber; /* uid, not pid */
+ LbxStalled *stalled_clients;
+ ColormapPtr next; /* proxy chain */
+} LbxColormapPriv;
+
+#define CMAP_NOT_GRABBED 0
+#define CMAP_GRABBED 1
+#define CMAP_WAITING_FOR_UNGRAB 2
+
+static int LbxUnstallClient();
+void LbxReleaseCmap();
+
+static RESTYPE StalledResType;
+
+/*
+ * Initialize the fields in the colormap private allocated for LBX.
+ */
+
+static LbxColormapPriv *
+LbxColormapPrivInit (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv;
+
+ cmapPriv = (LbxColormapPriv *) xalloc (sizeof (LbxColormapPriv));
+ if (!cmapPriv)
+ return cmapPriv;
+
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = (pointer) cmapPriv;
+
+ cmapPriv->grab_status = CMAP_NOT_GRABBED;
+ cmapPriv->grabber = NULL;
+ cmapPriv->last_grabber = 0;
+ cmapPriv->smart_grab = FALSE;
+ cmapPriv->stalled_clients = NULL;
+ cmapPriv->next = NULL;
+
+ return cmapPriv;
+}
+
+
+static int
+LbxDefCmapPrivInit (pmap)
+ ColormapPtr pmap;
+{
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
+ return 1;
+}
+
+static Bool
+LbxCreateColormap (pmap)
+ ColormapPtr pmap;
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ Bool ret;
+
+ pScreen->CreateColormap = ((LbxScreenPriv *) (pScreen->devPrivates[
+ lbxScreenPrivIndex].ptr))->CreateColormap;
+
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
+ ret = (*pScreen->CreateColormap) (pmap);
+
+ pScreen->CreateColormap = LbxCreateColormap;
+
+ return ret;
+}
+
+static void
+LbxDestroyColormap (pmap)
+ ColormapPtr pmap;
+{
+ ScreenPtr pScreen = pmap->pScreen;
+
+ LbxReleaseCmap(pmap, FALSE);
+ pScreen->DestroyColormap = ((LbxScreenPriv *) (pScreen->devPrivates[
+ lbxScreenPrivIndex].ptr))->DestroyColormap;
+ (*pScreen->DestroyColormap) (pmap);
+ if (pmap->devPrivates && pmap->devPrivates[lbxColormapPrivIndex].ptr)
+ xfree(pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ pScreen->DestroyColormap = LbxDestroyColormap;
+}
+
+/*
+ * Initialize LBX colormap private.
+ */
+
+int
+LbxCmapInit ()
+
+{
+ LbxScreenPriv *pScreenPriv;
+ ScreenPtr pScreen;
+ int i;
+
+ StalledResType = CreateNewResourceType(LbxUnstallClient);
+
+ lbxScreenPrivIndex = AllocateScreenPrivateIndex ();
+ if (lbxScreenPrivIndex < 0)
+ return 0;
+
+ lbxColormapPrivIndex = AllocateColormapPrivateIndex (LbxDefCmapPrivInit);
+ if (lbxColormapPrivIndex < 0)
+ return 0;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+
+ pScreenPriv = (LbxScreenPriv *) xalloc (sizeof (LbxScreenPriv));
+ if (!pScreenPriv)
+ return 0;
+
+ pScreenPriv->CreateColormap = pScreen->CreateColormap;
+ pScreen->CreateColormap = LbxCreateColormap;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreen->DestroyColormap = LbxDestroyColormap;
+ pScreen->devPrivates[lbxScreenPrivIndex].ptr = (pointer) pScreenPriv;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Return the number of allocated cells in the PSEUDO colormap.
+ */
+
+static int
+NumAllocatedCells (pent, size)
+ EntryPtr pent;
+ int size;
+{
+ Pixel pixel;
+ int count = 0;
+
+ for (pixel = 0; pixel < size; pixel++)
+ {
+ if (pent[pixel].refcnt != 0 && pent[pixel].refcnt != AllocTemporary)
+ count++;
+ }
+
+ return count;
+}
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+
+#define PIX_OUT(ptr,is2,val) \
+ if (is2) *ptr++ = (val) >> 8; \
+ *ptr++ = (val)
+#define RGB_OUT(ptr,is2,shift,val) \
+ *ptr++ = (val) >> shift; \
+ if (is2) *ptr++ = (val)
+
+/*
+ * Return the list of allocated cells in the channel in
+ * the format required by LbxGrabCmapReply.
+ */
+
+static CARD8 *
+OutputChannel(pmap, chan, size, ptr, flags, channels)
+ ColormapPtr pmap;
+ EntryPtr chan;
+ int size;
+ CARD8 *ptr;
+ CARD8 flags;
+ CARD8 channels;
+{
+ Bool px2;
+ Bool rgb2;
+ int shift;
+ int rgb_sz;
+ Pixel pixel;
+ EntryPtr pent;
+ CARD8 *pixel_private_range_ptr = NULL;
+ CARD8 *pixel_shared_range_ptr = NULL;
+ int allocpriv;
+
+ px2 = (flags & LBX_2BYTE_PIXELS) != 0;
+ rgb2 = (flags & LBX_RGB_BITS_MASK) > 7;
+ if (rgb2)
+ shift = 8;
+ else
+ shift = 15 - (flags & LBX_RGB_BITS_MASK);
+ rgb_sz = rgb2 + 1;
+ if (channels == DoRed|DoGreen|DoBlue)
+ rgb_sz *= 3;
+ /* kinda gross, but ddxen use AllocAll on static maps */
+ allocpriv = (pmap->pVisual->class & DynamicClass) ? AllocPrivate : 0;
+ for (pixel = 0; pixel < size; pixel++)
+ {
+ pent = (EntryPtr) &chan[pixel];
+
+ if (pent->refcnt == 0 || pent->refcnt == AllocTemporary)
+ {
+ /*
+ * A free pixel. This disrupts all ranges.
+ */
+
+ pixel_private_range_ptr = pixel_shared_range_ptr = NULL;
+
+ continue;
+ }
+ else if (pent->refcnt == allocpriv)
+ {
+ /*
+ * A private pixel. This disrupts any PIXEL_SHARED_RANGE.
+ */
+
+ pixel_shared_range_ptr = NULL;
+
+ if (!pixel_private_range_ptr)
+ {
+ pixel_private_range_ptr = ptr;
+
+ *ptr++ = LBX_PIXEL_PRIVATE;
+ PIX_OUT(ptr, px2, pixel);
+ }
+ else
+ {
+ CARD8 *pos = pixel_private_range_ptr + 2 + px2;
+ if (*pixel_private_range_ptr == LBX_PIXEL_PRIVATE) {
+ *pixel_private_range_ptr = LBX_PIXEL_RANGE_PRIVATE;
+ ptr += 1 + px2;
+ }
+ PIX_OUT(pos, px2, pixel);
+ }
+ }
+ else
+ {
+ /*
+ * A shared pixel. This disrupts any PIXEL_PRIVATE_RANGE.
+ */
+
+ pixel_private_range_ptr = NULL;
+
+ if (!pixel_shared_range_ptr)
+ {
+ pixel_shared_range_ptr = ptr;
+
+ *ptr++ = LBX_PIXEL_SHARED;
+ PIX_OUT(ptr, px2, pixel);
+ }
+ else
+ {
+ CARD8 *pos = pixel_shared_range_ptr + 2 + px2;
+ if (*pixel_shared_range_ptr == LBX_PIXEL_SHARED)
+ {
+ *pixel_shared_range_ptr = LBX_PIXEL_RANGE_SHARED;
+ memmove (pos + 1 + px2, pos, rgb_sz);
+ ptr += 1 + px2;
+ }
+ PIX_OUT(pos, px2, pixel);
+ }
+
+ if (channels & DoRed) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.red);
+ }
+ if (channels & DoGreen) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.green);
+ }
+ if (channels & DoBlue) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.blue);
+ }
+ }
+ }
+ return ptr;
+}
+
+static void
+GetAllocatedCells (pmap, flags, buf, bytes)
+ ColormapPtr pmap;
+ CARD8 *flags;
+ CARD8 *buf;
+ int *bytes;
+{
+ CARD8 *ptr;
+
+ *flags = pmap->pVisual->bitsPerRGBValue - 1;
+ if (pmap->pVisual->ColormapEntries > 256)
+ *flags |= LBX_2BYTE_PIXELS;
+ if (!(pmap->pVisual->class & DynamicClass))
+ *flags |= LBX_AUTO_RELEASE;
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
+ *flags |= LBX_3CHANNELS;
+ ptr = OutputChannel(pmap, pmap->red, NUMRED(pmap->pVisual),
+ buf, *flags, DoRed);
+ *ptr++ = LBX_NEXT_CHANNEL;
+ ptr = OutputChannel(pmap, pmap->green, NUMGREEN(pmap->pVisual),
+ ptr, *flags, DoGreen);
+ *ptr++ = LBX_NEXT_CHANNEL;
+ ptr = OutputChannel(pmap, pmap->blue, NUMBLUE(pmap->pVisual),
+ ptr, *flags, DoBlue);
+ } else
+ ptr = OutputChannel(pmap, pmap->red, pmap->pVisual->ColormapEntries,
+ buf, *flags, DoRed|DoGreen|DoBlue);
+ *ptr++ = LBX_LIST_END;
+ *bytes = ptr - buf;
+}
+
+
+/*
+ * Send an LbxReleaseCmapEvent to a proxy.
+ */
+
+static void
+SendReleaseCmapEvent (proxy, cmap)
+ LbxProxyPtr proxy;
+ Colormap cmap;
+{
+ xLbxReleaseCmapEvent ev;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+ int n;
+
+ lbxcp = proxy->lbxClients[0];
+
+ if (lbxcp && (client = lbxcp->client))
+ {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxReleaseCmapEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.colormap = cmap;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = ev.pad6 = 0;
+
+ if (client->swapped)
+ {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.colormap, n);
+ }
+
+ WriteToClient(client, sz_xLbxReleaseCmapEvent, (char *) &ev);
+ LbxForceOutput(proxy);
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Sent LbxReleaseCmapEvent to proxy %d, seq = 0x%x, cmap = 0x%x\n",
+ proxy->pid, client->sequence, cmap);
+#endif
+ }
+}
+
+
+/*
+ * WaitForServerCmapControl checks if the colormap is grabbed by a proxy,
+ * and if so, sends an LbxReleaseCmapEvent to the proxy. It then suspends
+ * the current request until the server gets the ReleaseCmap message from
+ * the proxy.
+ */
+
+static Bool
+WaitForServerCmapControl (client, pmap)
+ register ClientPtr client;
+ register ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ LbxStalled *stalled;
+
+ if (cmapPriv->grab_status == CMAP_GRABBED)
+ {
+ /*
+ * Send an LbxReleaseCmapEvent to the proxy that has the grab.
+ */
+
+ SendReleaseCmapEvent (cmapPriv->grabber, pmap->mid);
+ cmapPriv->grab_status = CMAP_WAITING_FOR_UNGRAB;
+ }
+
+ stalled = (LbxStalled *)xalloc(sizeof(LbxStalled));
+ if (!stalled)
+ return FALSE;
+ stalled->id = FakeClientID(client->index);
+ stalled->next = cmapPriv->stalled_clients;
+ cmapPriv->stalled_clients = stalled;
+ return AddResource(stalled->id, StalledResType, (pointer)cmapPriv);
+}
+
+
+/*
+ * When the X server gets any of the requests that allocate color cells,
+ * it calls LbxCheckColorRequest on the request. This function will check
+ * if the colormap is grabbed by a proxy, and if so, will suspend the
+ * current request and wait for the proxy to release the colormap.
+ */
+
+Bool
+LbxCheckColorRequest (client, pmap, req)
+ ClientPtr client;
+ ColormapPtr pmap;
+ xReq *req;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ if (!cmapPriv)
+ return FALSE;
+
+ if (cmapPriv->grab_status != CMAP_NOT_GRABBED)
+ {
+ /*
+ * The colormap is grabbed by a proxy. Reset this request, and
+ * process it after the server gets back control of the colormap.
+ * Before we reset the request, we must put it back in the
+ * client's byte order.
+ */
+
+ if (!WaitForServerCmapControl (client, pmap))
+ return FALSE;
+
+ if (client->swapped)
+ {
+ register int n;
+
+ switch (req->reqType)
+ {
+ case X_AllocColor:
+ {
+ xAllocColorReq *stuff = (xAllocColorReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ break;
+ }
+ case X_AllocNamedColor:
+ {
+ xAllocNamedColorReq *stuff = (xAllocNamedColorReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->nbytes, n);
+ break;
+ }
+ case X_AllocColorCells:
+ {
+ xAllocColorCellsReq *stuff = (xAllocColorCellsReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->planes, n);
+ break;
+ }
+ case X_AllocColorPlanes:
+ {
+ xAllocColorPlanesReq *stuff = (xAllocColorPlanesReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+
+ return TRUE;
+ }
+
+ if (!LbxClient(client) ||
+ LbxProxy(client)->uid != cmapPriv->last_grabber)
+ {
+ /*
+ * Next time the proxy for this client does a colormap grab, it
+ * will have to get the colormap state (a non-smart grab).
+ */
+
+ cmapPriv->smart_grab = FALSE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+LbxGrabbedByClient (client, pmap)
+ ClientPtr client;
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ return (cmapPriv &&
+ (cmapPriv->grab_status != CMAP_NOT_GRABBED) &&
+ (cmapPriv->grabber == LbxProxy(client)));
+}
+
+/*
+ * Check if a colormap is grabbed by a proxy.
+ */
+
+int
+LbxCheckCmapGrabbed (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ return (cmapPriv && (cmapPriv->grab_status == CMAP_GRABBED));
+}
+
+
+/*
+ * Disable a smart grab on the specified colormap.
+ */
+
+void
+LbxDisableSmartGrab (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ if (cmapPriv)
+ cmapPriv->smart_grab = FALSE;
+}
+
+
+/*
+ * Send an LbxFreeCellsEvent to the specified proxy.
+ */
+
+static void
+SendFreeCellsEvent (proxy, cmap, pixel_start, pixel_end)
+ LbxProxyPtr proxy;
+ Colormap cmap;
+ Pixel pixel_start;
+ Pixel pixel_end;
+{
+ xLbxFreeCellsEvent ev;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+ int n;
+
+ lbxcp = proxy->lbxClients[0];
+
+ if (lbxcp && (client = lbxcp->client))
+ {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxFreeCellsEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.colormap = cmap;
+ ev.pixelStart = pixel_start;
+ ev.pixelEnd = pixel_end;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = 0;
+
+ if (client->swapped)
+ {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.colormap, n);
+ swapl(&ev.pixelStart, n);
+ swapl(&ev.pixelEnd, n);
+ }
+
+ WriteToClient(client, sz_xLbxFreeCellsEvent, (char *) &ev);
+ LbxForceOutput(proxy);
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Sent LbxFreeCellsEvent to proxy %d, seq = 0x%x\n",
+ proxy->pid, client->sequence);
+ fprintf (stderr, " cmap = 0x%x, pixelStart = %d, pixelEnd = %d\n",
+ cmap, pixel_start, pixel_end);
+#endif
+ }
+}
+
+/* XXX use of globals like this is gross */
+static long pixel_start;
+static long pixel_end;
+
+
+/*
+ * LbxFreeCellsEvent generation functions.
+ */
+
+/*ARGSUSED*/
+void
+LbxBeginFreeCellsEvent (pmap)
+ ColormapPtr pmap;
+{
+ pixel_start = -1;
+ pixel_end = -1;
+}
+
+
+void
+LbxAddFreeCellToEvent (pmap, pixel)
+ ColormapPtr pmap;
+ Pixel pixel;
+{
+ /*
+ * We must notify the proxy that has this colormap
+ * grabbed which cells are being freed (their refcount
+ * has reached zero).
+ */
+
+ if (pixel_start == -1)
+ pixel_start = pixel;
+ else
+ {
+ if (pixel_end == -1)
+ pixel_end = pixel;
+ else
+ {
+ if (pixel_end + 1 == pixel)
+ pixel_end = pixel;
+ else if (pixel > pixel_end + 1)
+ {
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ SendFreeCellsEvent (cmapPriv->grabber,
+ pmap->mid, pixel_start, pixel_end);
+
+ pixel_start = pixel;
+ pixel_end = -1;
+ }
+ }
+ }
+}
+
+void
+LbxEndFreeCellsEvent (pmap)
+ ColormapPtr pmap;
+{
+ /*
+ * Check if there is an LbxFreeCellEvent we need to write.
+ */
+
+ if (pixel_start != -1)
+ {
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ SendFreeCellsEvent (cmapPriv->grabber,
+ pmap->mid, pixel_start,
+ pixel_end == -1 ? pixel_start : pixel_end);
+ }
+}
+
+
+/*
+ * Sort the specified pixel list. This optimizes generation
+ * of LbxFreeCellsEvent.
+ */
+
+void
+LbxSortPixelList (pixels, count)
+ Pixel *pixels;
+ int count;
+{
+ int i, j;
+
+ for (i = 0; i <= count - 2; i++)
+ for (j = count - 1; j > i; j--)
+ if (pixels[j - 1] > pixels[j])
+ {
+ Pixel temp = pixels[j - 1];
+ pixels[j - 1] = pixels[j];
+ pixels[j] = temp;
+ }
+}
+
+
+/*
+ * Handle a colormap grab request from a proxy.
+ */
+
+int
+ProcLbxGrabCmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxGrabCmapReq);
+ xLbxGrabCmapReply *reply;
+ Bool smartGrab;
+ LbxColormapPriv *cmapPriv;
+ ColormapPtr pmap;
+ int bytes, n;
+ LbxProxyPtr proxy = LbxProxy(client);
+
+ client->sequence--; /* not a counted request */
+
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+ if (!pmap)
+ {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ if (!cmapPriv)
+ {
+ cmapPriv = LbxColormapPrivInit (pmap);
+ if (!cmapPriv)
+ return BadAlloc;
+ }
+
+
+ /*
+ * We have a SMART GRAB if since this proxy last ungrabbed the
+ * colormap, no color cell was alloc'd by an entity other than
+ * this proxy (this includes other proxies as well as clients
+ * directly connected to the X server without a proxy).
+ *
+ * We want to optimize this special case because a proxy may give
+ * up a grab because it got a request that it could not handle
+ * (e.g. AllocNamedColor or LookupColor). When it asks back for
+ * the grab, there is no need for the server to send the colormap
+ * state, because the proxy is already up to date on the state of
+ * the colormap.
+ *
+ * In order for this to work, the following assumptions are made
+ * about the proxy:
+ *
+ * - the proxy is kept up to date on all cell allocations made on its
+ * behalf resulting from the following requests: AllocNamedColor,
+ * AllocColorCells, AllocColorPlanes
+ * - the proxy is kept up to date on all cells freed by any client
+ * via the LbxFreeCell event.
+ */
+
+ /* if proxy is this confused, give it full info */
+ if (cmapPriv->grab_status == CMAP_GRABBED && cmapPriv->grabber == proxy)
+ LbxReleaseCmap(pmap, FALSE);
+
+ if (proxy->uid != cmapPriv->last_grabber)
+ cmapPriv->smart_grab = FALSE;
+ smartGrab = cmapPriv->smart_grab;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "\nGot colormap grab request, ");
+ fprintf (stderr, "seq = 0x%x, proxy = %d, client = %d, cmap = 0x%x\n",
+ client->sequence, proxy->pid, client->index, stuff->cmap);
+
+ if (cmapPriv->grab_status == CMAP_NOT_GRABBED)
+ {
+ fprintf (stderr, "cmap 0x%x is not grabbed by any proxy\n",
+ stuff->cmap);
+ if (smartGrab)
+ fprintf (stderr, "This is a smart grab\n");
+ }
+ else if (cmapPriv->grab_status == CMAP_GRABBED)
+ {
+ if (cmapPriv->grabber == proxy)
+ {
+ fprintf (stderr, "cmap 0x%x is already grabbed by proxy %d\n",
+ stuff->cmap, proxy->pid);
+ }
+ else
+ {
+ fprintf (stderr, "cmap 0x%x is currently grabbed by proxy %d\n",
+ stuff->cmap, cmapPriv->grabber->pid);
+ }
+ }
+ else if (cmapPriv->grab_status == CMAP_WAITING_FOR_UNGRAB)
+ {
+ fprintf (stderr,
+ "Already waiting for cmap 0x%x to be ungrabbed by proxy %d\n",
+ stuff->cmap, cmapPriv->grabber->pid);
+ }
+#endif
+
+ if (cmapPriv->grab_status != CMAP_NOT_GRABBED &&
+ cmapPriv->grabber != proxy)
+ {
+ /*
+ * The colormap is grabbed by a proxy other than the one that
+ * is requesting this grab. Reset this grab request, and process
+ * it after the server gets back control of the colormap. Before
+ * we reset the request, we must put it back in the client's byte
+ * order.
+ */
+
+ if (!WaitForServerCmapControl (client, pmap))
+ return BadAlloc;
+
+ if (client->swapped)
+ {
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ }
+
+ ResetCurrentRequest(client);
+ IgnoreClient(client);
+
+ return Success;
+ }
+
+ if (pmap->pVisual->class & DynamicClass) {
+ cmapPriv->grabber = proxy;
+ cmapPriv->grab_status = CMAP_GRABBED;
+ cmapPriv->next = proxy->grabbedCmaps;
+ proxy->grabbedCmaps = pmap;
+ } else
+ smartGrab = FALSE;
+
+ /*
+ * For an smart grab (see comments above), there is no information
+ * sent about the colormap cells because the proxy is all up to date.
+ * Otherwise, the server sends the proxy the state of all allocated
+ * cells in the colormap. All cells not specified are assumed free.
+ */
+
+ bytes = 0;
+ if (!smartGrab) {
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
+ bytes = NumAllocatedCells(pmap->red,
+ NUMRED(pmap->pVisual)) * 9;
+ bytes += NumAllocatedCells(pmap->green,
+ NUMGREEN(pmap->pVisual)) * 9;
+ bytes += NumAllocatedCells(pmap->blue,
+ NUMBLUE(pmap->pVisual)) * 9;
+ bytes += 2;
+ } else
+ bytes = NumAllocatedCells(pmap->red,
+ pmap->pVisual->ColormapEntries) * 9;
+ }
+ bytes += sz_xLbxGrabCmapReply + 1;
+ reply = (xLbxGrabCmapReply *) xalloc (bytes);
+ bzero (reply, sz_xLbxGrabCmapReply);
+
+ if (smartGrab)
+ {
+ reply->flags = LBX_SMART_GRAB;
+ reply->length = 0;
+ }
+ else
+ {
+ GetAllocatedCells (pmap, &reply->flags,
+ (CARD8 *) reply + sz_xLbxGrabCmapReplyHdr, &bytes);
+ if (bytes <= (sz_xLbxGrabCmapReply - sz_xLbxGrabCmapReplyHdr))
+ reply->length = 0;
+ else
+ reply->length = (sz_xLbxGrabCmapReplyHdr +
+ bytes - sz_xLbxGrabCmapReply + 3) >> 2;
+ }
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+
+ bytes = sz_xLbxGrabCmapReply + (reply->length << 2);
+
+ if (client->swapped)
+ {
+ register char n;
+
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ }
+
+ WriteToClient (client, bytes, (char *)reply);
+
+ xfree (reply);
+
+ return (client->noClientException);
+}
+
+static int
+LbxUnstallClient(data, id)
+ pointer data;
+ XID id;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)data;
+ LbxStalled **prev;
+ ClientPtr client;
+
+ for (prev = &cmapPriv->stalled_clients; *prev && (*prev)->id != id; )
+ prev = &(*prev)->next;
+ *prev = (*prev)->next;
+ client = clients[CLIENT_ID(id)];
+ if (!client->clientGone)
+ AttendClient(client);
+ return 0;
+}
+
+void
+LbxReleaseCmap(pmap, smart)
+ ColormapPtr pmap;
+ Bool smart;
+{
+ LbxColormapPriv *cmapPriv;
+ ColormapPtr *prev;
+
+ if (!pmap->devPrivates)
+ return;
+ cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ if (!cmapPriv || (cmapPriv->grab_status == CMAP_NOT_GRABBED))
+ return;
+
+ for (prev = &cmapPriv->grabber->grabbedCmaps; *prev && *prev != pmap; )
+ prev = &((LbxColormapPriv *)
+ (*prev)->devPrivates[lbxColormapPrivIndex].ptr)->next;
+ if (*prev == pmap)
+ *prev = cmapPriv->next;
+
+ while (cmapPriv->stalled_clients)
+ FreeResource(cmapPriv->stalled_clients->id, 0);
+
+ cmapPriv->grab_status = CMAP_NOT_GRABBED;
+ cmapPriv->last_grabber = smart ? cmapPriv->grabber->uid : 0;
+ cmapPriv->grabber = NULL;
+ cmapPriv->smart_grab = smart;
+}
+
+/*
+ * Handle a colormap release request from a proxy.
+ */
+
+int
+ProcLbxReleaseCmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxReleaseCmapReq);
+ ColormapPtr pmap;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Got colormap release request, ");
+ fprintf (stderr, "seq = 0x%x, proxy = %d, client = %d, cmap = 0x%x\n",
+ client->sequence, LbxProxyID(client), client->index, stuff->cmap);
+#endif
+
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+ if (!pmap)
+ {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ if (LbxGrabbedByClient(client, pmap))
+ LbxReleaseCmap(pmap, TRUE);
+ return Success;
+}
+
+
+/*
+ * Handle an LbxAllocColor request. The proxy did the alloc and
+ * is telling the server what rgb and pixel value to use.
+ */
+
+int
+ProcLbxAllocColor(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxAllocColorReq);
+ ColormapPtr pmap;
+ CARD32 pixel = stuff->pixel;
+
+ REQUEST_SIZE_MATCH (xLbxAllocColorReq);
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Got LBX alloc color: seq = 0x%x, proxy = %d, client = %d\n",
+ client->sequence, LbxProxyID(client), client->index);
+ fprintf (stderr, " cmap = 0x%x, pixel = %d, rgb = (%d,%d,%d)\n",
+ stuff->cmap, stuff->pixel, stuff->red, stuff->green, stuff->blue);
+#endif
+
+ if (pmap)
+ {
+ int status;
+ if (!LbxGrabbedByClient(client, pmap))
+ return BadAccess;
+
+ status = AllocColor (pmap,
+ &stuff->red, &stuff->green, &stuff->blue,
+ &pixel, client->index);
+
+ if (status == Success && pixel != stuff->pixel)
+ {
+ /*
+ * Internal error - Proxy allocated different pixel from server
+ */
+#ifdef COLOR_DEBUG
+ fprintf(stderr, "got pixel %d (%d, %d, %d), expected %d\n",
+ pixel, stuff->red, stuff->green, stuff->blue, stuff->pixel);
+#endif
+ FreeColors (pmap, client->index, 1, &pixel, 0L);
+ return BadAlloc;
+ }
+
+ return status;
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+
+/*
+ * The proxy sends an LbxIncrementPixel request when it short circuits
+ * an AllocColor. The server must bump up the reference count the
+ * specified amount.
+ */
+
+int
+ProcLbxIncrementPixel(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxIncrementPixelReq);
+ ColormapPtr pmap;
+ EntryPtr pent;
+ Pixel pixel;
+ unsigned short red, green, blue;
+ VisualPtr pVisual;
+ int status;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Got LBX increment pixel: seq = 0x%x, proxy = %d, client = %d\n",
+ client->sequence, LbxProxyID(client), client->index);
+ fprintf (stderr, " cmap = 0x%x, pixel = %d\n",
+ stuff->cmap, stuff->pixel);
+#endif
+
+ /*
+ * Looks up the color associated with the pixel, and then call
+ * AllocColor() - a bit round-about, but it should work.
+ */
+
+ pmap = (ColormapPtr) SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+ if (!pmap) {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ pixel = stuff->pixel;
+
+ switch (pmap->class) {
+ case StaticColor:
+ case StaticGray:
+ red = pmap->red[pixel].co.local.red;
+ green = pmap->red[pixel].co.local.green;
+ blue = pmap->red[pixel].co.local.blue;
+ break;
+ case GrayScale:
+ case PseudoColor:
+ pent = pmap->red + pixel;
+ red = pent->co.local.red;
+ green = pent->co.local.green;
+ blue = pent->co.local.blue;
+ break;
+ default:
+ pVisual = pmap->pVisual;
+ red = pmap->red[(pixel & pVisual->redMask) >> pVisual->offsetRed].co.local.red;
+ green = pmap->green[(pixel & pVisual->greenMask) >> pVisual->offsetGreen].co.local.green;
+ blue = pmap->blue[(pixel & pVisual->blueMask) >> pVisual->offsetBlue].co.local.blue;
+ break;
+ }
+
+ status = AllocColor(pmap, &red, &green, &blue, &pixel, client->index);
+
+ if (status == Success && pixel != stuff->pixel)
+ {
+ /*
+ * Internal error - Proxy allocated different pixel from server
+ */
+#ifdef COLOR_DEBUG
+ fprintf(stderr, "got pixel %d, expected %d\n", pixel, stuff->pixel);
+#endif
+ FreeColors (pmap, client->index, 1, &pixel, 0L);
+ return BadAlloc;
+ }
+
+ return status;
+}
diff --git a/lbx/lbxdata.h b/lbx/lbxdata.h
new file mode 100644
index 000000000..d5240f7ea
--- /dev/null
+++ b/lbx/lbxdata.h
@@ -0,0 +1,44 @@
+/* $Xorg: lbxdata.h,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBXDATA_H_
+#define _LBXDATA_H_
+#define NEED_REPLIES
+#include "X.h"
+#include "Xproto.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "dixfontstr.h"
+
+extern int lbx_font_private;
+
+typedef struct _fonttaginfo {
+ XID tid;
+ FontPtr pfont;
+ unsigned long size;
+ int compression;
+ xLbxFontInfo *fontinfo;
+} FontTagInfoRec, *FontTagInfoPtr;
+
+#endif /* _LBXDATA_H_ */
diff --git a/lbx/lbxdix.c b/lbx/lbxdix.c
new file mode 100644
index 000000000..e4822f190
--- /dev/null
+++ b/lbx/lbxdix.c
@@ -0,0 +1,887 @@
+/* $Xorg: lbxdix.c,v 1.4 2001/02/09 02:05:16 xorgcvs Exp $ */
+/*
+
+Copyright 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "inputstr.h"
+#include "servermd.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "lbxdata.h"
+#include "Xfuncproto.h"
+
+extern void CopySwap32Write();
+extern int (*ProcVector[256]) ();
+extern int (*SwappedProcVector[256]) ();
+extern void (*ReplySwapVector[256]) ();
+
+extern void LbxWriteSConnSetupPrefix();
+
+int lbx_font_private;
+
+void
+LbxDixInit()
+{
+ TagInit();
+ lbx_font_private = AllocateFontPrivateIndex();
+}
+
+/* ARGSUSED */
+void
+LbxAllowMotion(client, num)
+ ClientPtr client;
+ int num;
+{
+ LbxProxyPtr proxy = LbxProxy(client);
+ proxy->motion_allowed_events += num;
+}
+
+extern WindowPtr *WindowTable;
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+
+int
+LbxSendConnSetup(client, reason)
+ ClientPtr client;
+ char *reason;
+{
+ int dlength;
+ int i, ndex, lim, wndex;
+ CARD32 dataBuf[16];
+ xLbxConnSetupPrefix csp;
+ NewClientInfoRec nci;
+ LbxProxyPtr proxy = LbxProxy(client);
+
+ if (reason) {
+ SendConnSetup(client, reason);
+ LbxForceOutput(proxy); /* expedient to avoid another state variable */
+ return (client->noClientException);
+ }
+
+ IncrementClientCount();
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+ dataBuf[0] = client->clientAsMask;
+
+ csp.success = TRUE;
+ csp.majorVersion = connSetupPrefix.majorVersion;
+ csp.minorVersion = connSetupPrefix.minorVersion;
+ csp.tag = 0;
+#ifdef XAPPGROUP
+ if (!client->appgroup) {
+#endif
+ csp.changeType = 1; /* LbxNormalDeltas */
+ csp.length = 2 + /* tag + resource-id-base */
+ screenInfo.numScreens; /* input-mask per screen */
+ wndex = 0; ndex = 1; lim = screenInfo.numScreens;
+#ifdef XAPPGROUP
+ } else {
+ csp.changeType = 2; /* LbxAppGroupDeltas */
+ csp.length = 7 + /* tag, res-id-base, root, visual, colormap, b&w-pix */
+ 1 + screenInfo.numScreens - screenInfo.numVideoScreens;
+ XagGetDeltaInfo (client, &dataBuf[1]);
+ for (i = 0; i < MAXSCREENS; i++) {
+ if ((CARD32) WindowTable[i]->drawable.id == dataBuf[1]) {
+ dataBuf[6] = WindowTable[i]->eventMask | wOtherEventMasks(WindowTable[i]);
+ break;
+ }
+ }
+ wndex = screenInfo.numVideoScreens;
+ ndex = 7;
+ lim = screenInfo.numScreens - screenInfo.numVideoScreens;
+ }
+#endif
+ for (i = 0; i < lim; i++, ndex++, wndex++) {
+ dataBuf[ndex] =
+ WindowTable[wndex]->eventMask | wOtherEventMasks(WindowTable[wndex]);
+ }
+ dlength = (csp.length - 1) << 2;
+
+ if (LbxProxyClient(proxy)->swapped) {
+ swaps(&csp.length, i);
+ }
+
+ if (client->swapped) {
+ LbxWriteSConnSetupPrefix(client, &csp);
+ SwapLongs(dataBuf, (1 + screenInfo.numScreens));
+ WriteToClient(client, dlength, (pointer) dataBuf);
+ } else {
+ WriteToClient(client, sizeof(xLbxConnSetupPrefix), (char *) &csp);
+ WriteToClient(client, dlength, (pointer) dataBuf);
+ }
+
+ LbxForceOutput(proxy); /* expedient to avoid another state variable */
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback) {
+ if (LbxProxyClient(proxy)->swapped != client->swapped) {
+ swaps(&csp.length, i);
+ }
+ nci.client = client;
+ nci.prefix = (xConnSetupPrefix*) &csp;
+ nci.setup = (xConnSetup *) ConnectionInfo;
+ CallCallbacks(&ClientStateCallback, (pointer) &nci);
+ }
+
+ return client->noClientException;
+}
+
+extern InputInfo inputInfo;
+
+static XID modifier_map_tag;
+
+int
+LbxGetModifierMapping(client)
+ ClientPtr client;
+{
+ TagData td;
+ pointer tagdata;
+ xLbxGetModifierMappingReply rep;
+ register KeyClassPtr keyc = inputInfo.keyboard->key;
+ int dlength = keyc->maxKeysPerModifier << 3;
+ Bool tag_known = FALSE,
+ send_data;
+ int n;
+
+ if (!modifier_map_tag) {
+ tagdata = (pointer) keyc->modifierKeyMap;
+ TagSaveTag(LbxTagTypeModmap, dlength, tagdata, &modifier_map_tag);
+ } else {
+ td = TagGetTag(modifier_map_tag);
+ tagdata = td->tdata;
+ tag_known = TagProxyMarked(modifier_map_tag, LbxProxyID(client));
+ }
+ if (modifier_map_tag)
+ TagMarkProxy(modifier_map_tag, LbxProxyID(client));
+
+ send_data = (!modifier_map_tag || !tag_known);
+
+ rep.type = X_Reply;
+ rep.keyspermod = keyc->maxKeysPerModifier;
+ rep.sequenceNumber = client->sequence;
+ rep.tag = modifier_map_tag;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (send_data)
+ rep.length = dlength >> 2;
+ else
+ rep.length = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetModifierMappingReply), (char *)&rep);
+
+ if (send_data)
+ WriteToClient(client, dlength, (char *) tagdata);
+
+ return client->noClientException;
+}
+
+void
+LbxFlushModifierMapTag()
+{
+
+ if (modifier_map_tag)
+ TagDeleteTag(modifier_map_tag);
+}
+
+static XID keyboard_map_tag;
+
+int
+LbxGetKeyboardMapping(client)
+ ClientPtr client;
+{
+ TagData td;
+ pointer tagdata;
+ xLbxGetKeyboardMappingReply rep;
+
+ REQUEST(xLbxGetKeyboardMappingReq);
+ KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ int dlength;
+ Bool tag_known = FALSE,
+ send_data;
+ int n;
+
+ REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
+
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if (stuff->firstKeyCode + stuff->count > curKeySyms->maxKeyCode + 1) {
+ client->errorValue = stuff->count;
+ return BadValue;
+ }
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.keysperkeycode = curKeySyms->mapWidth;
+ /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+
+ if (!keyboard_map_tag) {
+ tagdata = (pointer) &curKeySyms->map[(stuff->firstKeyCode -
+ curKeySyms->minKeyCode) * curKeySyms->mapWidth];
+ dlength = (curKeySyms->mapWidth * stuff->count);
+ TagSaveTag(LbxTagTypeKeymap, dlength, tagdata, &keyboard_map_tag);
+ } else {
+ td = TagGetTag(keyboard_map_tag);
+ tagdata = td->tdata;
+ tag_known = TagProxyMarked(keyboard_map_tag, LbxProxyID(client));
+ }
+ if (keyboard_map_tag)
+ TagMarkProxy(keyboard_map_tag, LbxProxyID(client));
+
+ send_data = (!keyboard_map_tag || !tag_known);
+ rep.type = X_Reply;
+ rep.keysperkeycode = curKeySyms->mapWidth;
+ rep.sequenceNumber = client->sequence;
+ rep.tag = keyboard_map_tag;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (send_data)
+ rep.length = (curKeySyms->mapWidth * stuff->count);
+ else
+ rep.length = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetKeyboardMappingReply), (char *)&rep);
+
+ if (send_data) {
+ client->pSwapReplyFunc = CopySwap32Write;
+ WriteSwappedDataToClient(client,
+ curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
+ &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
+ curKeySyms->mapWidth]);
+ }
+ return client->noClientException;
+}
+
+void
+LbxFlushKeyboardMapTag()
+{
+ if (keyboard_map_tag)
+ TagDeleteTag(keyboard_map_tag);
+}
+
+/* counts number of bits needed to hold value */
+static int
+_bitsize(val)
+ int val;
+{
+ int bits = 1; /* always need one for sign bit */
+
+ if (val == 0)
+ return (bits);
+
+ if (val < 0) {
+ val = -val;
+ }
+ while (val) {
+ bits++;
+ val >>= 1;
+ }
+
+ return bits;
+
+}
+
+/*
+ * squashes the font (if possible), returning the new length and
+ * a pointer to the new data (which has been allocated). if it can't
+ * squish, it just returns a 0 and the data is sent in raw form.
+ */
+int _lbx_fi_junklen = sizeof(BYTE) * 2 + sizeof(CARD16) + sizeof(CARD32);
+
+static int
+squish_font_info(qfr, rlen, sqrep)
+ xQueryFontReply *qfr;
+ int rlen;
+ xLbxFontInfo **sqrep;
+{
+ int len,
+ hlen;
+ xLbxFontInfo *new;
+ xCharInfo *minb,
+ *maxb,
+ *ci,
+ bbox;
+ int i;
+ char *t;
+ xLbxCharInfo *chars;
+ int num_chars;
+
+ num_chars = qfr->nCharInfos;
+
+ if (num_chars == 0)
+ return 0;
+
+ minb = &qfr->minBounds;
+ maxb = &qfr->maxBounds;
+ /*
+ * first do the quick check -- if the attribute fields aren't all the
+ * same, punt
+ */
+
+ if (minb->attributes != maxb->attributes)
+ return 0;
+
+#define compute(field) \
+ bbox.field = max(_bitsize(minb->field), _bitsize(maxb->field))
+
+ compute(characterWidth);
+ compute(leftSideBearing);
+ compute(rightSideBearing);
+ compute(ascent);
+ compute(descent);
+
+#undef compute
+
+ /* make sure it fits */
+ if (!((bbox.characterWidth <= LBX_WIDTH_BITS) &&
+ (bbox.leftSideBearing <= LBX_LEFT_BITS) &&
+ (bbox.rightSideBearing <= LBX_RIGHT_BITS) &&
+ (bbox.ascent <= LBX_ASCENT_BITS) &&
+ (bbox.descent <= LBX_DESCENT_BITS))) {
+ return 0;
+ }
+
+ hlen = sizeof(xLbxFontInfo) + qfr->nFontProps * sizeof(xFontProp);
+
+ len = hlen + (num_chars * sizeof(xLbxCharInfo));
+
+ new = (xLbxFontInfo *) xalloc(len);
+ if (!new)
+ return 0;
+
+ /* gross hack to avoid copying all the fields */
+ t = (char *) qfr;
+ t += _lbx_fi_junklen;
+
+ /* copy all but the char infos */
+ memcpy((char *) new, (char *) t, hlen);
+
+ t = (char *) new;
+ t += hlen;
+ chars = (xLbxCharInfo *) t;
+
+ t = (char *) qfr;
+ t += sizeof(xQueryFontReply) + qfr->nFontProps * sizeof(xFontProp);
+ ci = (xCharInfo *) t;
+
+ /* now copy & pack the charinfos */
+ for (i = 0; i < num_chars; i++, chars++, ci++) {
+ chars->metrics = 0;
+ chars->metrics |= (LBX_MASK_BITS(ci->characterWidth, LBX_WIDTH_BITS)
+ << LBX_WIDTH_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->leftSideBearing, LBX_LEFT_BITS)
+ << LBX_LEFT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->rightSideBearing, LBX_RIGHT_BITS)
+ << LBX_RIGHT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->ascent, LBX_ASCENT_BITS)
+ << LBX_ASCENT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->descent, LBX_DESCENT_BITS)
+ << LBX_DESCENT_SHIFT);
+ }
+
+ *sqrep = new;
+ return len;
+}
+
+int
+LbxQueryFont(client)
+ ClientPtr client;
+{
+ xQueryFontReply *reply;
+ xLbxQueryFontReply lbxrep;
+ FontPtr pFont;
+ register GC *pGC;
+ Bool send_data = FALSE;
+ Bool free_data = FALSE;
+ int rlength = 0;
+ FontTagInfoPtr ftip;
+ int sqlen = 0;
+ xLbxFontInfo *sqrep,
+ *sreply = NULL;
+
+ REQUEST(xLbxQueryFontReq);
+
+ REQUEST_SIZE_MATCH(xLbxQueryFontReq);
+
+ client->errorValue = stuff->fid; /* EITHER font or gc */
+ pFont = (FontPtr) SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont) {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC || !pGC->font) { /* catch a non-existent builtin font */
+ client->errorValue = stuff->fid;
+ return (BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ /* get tag (if any) */
+ ftip = (FontTagInfoPtr) FontGetPrivate(pFont, lbx_font_private);
+
+ if (!ftip) {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = (xQueryFontReply *) xalloc(rlength);
+ if (!reply) {
+ return (BadAlloc);
+ }
+ free_data = TRUE;
+ send_data = TRUE;
+ QueryFont(pFont, reply, nprotoxcistructs);
+
+ sqlen = squish_font_info(reply, rlength, &sqrep);
+ if (!sqlen) { /* if it failed to squish, send it raw */
+ char *t;
+
+ lbxrep.compression = 0;
+
+ sqlen = rlength - _lbx_fi_junklen;
+ t = (char *) reply;
+ sqrep = (xLbxFontInfo *) (t + _lbx_fi_junklen);
+ } else {
+ lbxrep.compression = 1;
+ xfree(reply); /* no longer needed */
+ }
+ } else { /* just get data from tag */
+ sqrep = ftip->fontinfo;
+ sqlen = ftip->size;
+ lbxrep.compression = ftip->compression;
+ }
+
+ if (!ftip) {
+ /* data allocation is done when font is first queried */
+ ftip = (FontTagInfoPtr) xalloc(sizeof(FontTagInfoRec));
+ if (ftip &&
+ TagSaveTag(LbxTagTypeFont, sqlen, (pointer) ftip, &ftip->tid)) {
+ FontSetPrivate(pFont, lbx_font_private, (pointer) ftip);
+ ftip->pfont = pFont;
+ ftip->size = sqlen;
+ ftip->fontinfo = sqrep;
+ ftip->compression = lbxrep.compression;
+ free_data = FALSE;
+ } else {
+ xfree(ftip);
+ }
+ }
+ if (ftip) {
+ if (!TagProxyMarked(ftip->tid, LbxProxyID(client)))
+ send_data = TRUE;
+ TagMarkProxy(ftip->tid, LbxProxyID(client));
+ lbxrep.tag = ftip->tid;
+ } else {
+ lbxrep.tag = 0;
+ send_data = TRUE;
+ }
+
+ lbxrep.type = X_Reply;
+ lbxrep.sequenceNumber = client->sequence;
+ lbxrep.pad0 = lbxrep.pad1 = lbxrep.pad2 = lbxrep.pad3 = lbxrep.pad4 = 0;
+
+ if (send_data)
+ lbxrep.length = sqlen >> 2;
+ else
+ lbxrep.length = 0;
+
+ if (client->swapped) {
+ int n;
+
+ swaps(&lbxrep.sequenceNumber, n);
+ swapl(&lbxrep.length, n);
+ swapl(&lbxrep.tag, n);
+ sreply = (xLbxFontInfo *) ALLOCATE_LOCAL(sqlen);
+ if (!sreply)
+ return BadAlloc;
+ memcpy((char *) sreply, (char *) sqrep, sqlen);
+ LbxSwapFontInfo(sreply, lbxrep.compression);
+ sqrep = sreply;
+ }
+ WriteToClient(client, sizeof(xLbxQueryFontReply), (char *) &lbxrep);
+ if (send_data)
+ WriteToClient(client, sqlen, (char *)sqrep);
+ if (free_data)
+ xfree(sqrep);
+ if (sreply)
+ DEALLOCATE_LOCAL(sreply);
+ return (client->noClientException);
+}
+
+void
+LbxFreeFontTag(pfont)
+ FontPtr pfont;
+{
+ FontTagInfoPtr ftip;
+
+ ftip = (FontTagInfoPtr) FontGetPrivate(pfont, lbx_font_private);
+ if (ftip)
+ TagDeleteTag(ftip->tid);
+}
+
+LbxInvalidateTag(client, tag)
+ ClientPtr client;
+ XID tag;
+{
+ TagClearProxy(tag, LbxProxyID(client));
+ return client->noClientException;
+}
+
+void
+LbxSendInvalidateTag(client, tag, tagtype)
+ ClientPtr client;
+ XID tag;
+ int tagtype;
+{
+ xLbxInvalidateTagEvent ev;
+ int n;
+
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxInvalidateTagEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.tag = tag;
+ ev.tagType = tagtype;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = 0;
+
+ if (client->swapped) {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.tag, n);
+ swapl(&ev.tagType, n);
+ }
+ DBG(DBG_CLIENT, (stderr, "Invalidating tag %d\n", tag));
+ WriteToClient(client, sizeof(xLbxInvalidateTagEvent), (char *) &ev);
+ LbxForceOutput(LbxProxy(client));
+}
+
+static void
+LbxSendSendTagData(pid, tag, tagtype)
+ int pid;
+ XID tag;
+ int tagtype;
+{
+ xLbxSendTagDataEvent ev;
+ int n;
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+
+ proxy = LbxPidToProxy(pid);
+ lbxcp = (proxy != NULL) ? proxy->lbxClients[0] : NULL;
+ if (lbxcp && (client = lbxcp->client)) {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxSendTagDataEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.tag = tag;
+ ev.tagType = tagtype;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = 0;
+
+ if (client->swapped) {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.tag, n);
+ swapl(&ev.tagType, n);
+ }
+ DBG(DBG_CLIENT, (stderr, "Requesting tag %d\n", tag));
+ WriteToClient(client, sizeof(xLbxSendTagDataEvent), (char *) &ev);
+ LbxForceOutput(proxy);
+ }
+}
+
+/*
+ * keep track of clients stalled waiting for tags to come back from
+ * a proxy. since multiple clinets can be waiting for the same tag,
+ * we have to keep a list of all of them.
+ */
+
+typedef struct _sendtagq {
+ XID tag;
+ int num_stalled;
+ ClientPtr *stalled_clients;
+ struct _sendtagq *next;
+} SendTagQRec, *SendTagQPtr;
+
+static SendTagQPtr queried_tags = NULL;
+
+#define LbxSendTagFailed -1
+#define LbxSendTagSendIt 0
+#define LbxSendTagAlreadySent 1
+
+static Bool
+LbxQueueSendTag(client, tag)
+ ClientPtr client;
+ XID tag;
+{
+ SendTagQPtr stqp, *prev, new;
+ ClientPtr *newlist;
+
+
+ /* see if we're asking for one already in the pipeline */
+ for (prev = &queried_tags; stqp = *prev; prev = &stqp->next) {
+ if (stqp->tag == tag) {
+ /* add new client to list */
+ newlist = (ClientPtr *) xrealloc(stqp->stalled_clients,
+ (sizeof(ClientPtr) * (stqp->num_stalled + 1)));
+ if (!newlist)
+ return LbxSendTagFailed;
+ newlist[stqp->num_stalled++] = client;
+ stqp->stalled_clients = newlist;
+ DBG(DBG_CLIENT, (stderr, "Additional client requesting tag %d\n", tag));
+ return LbxSendTagAlreadySent;
+ }
+ }
+
+ /* make new one */
+ new = (SendTagQPtr) xalloc(sizeof(SendTagQRec));
+ newlist = (ClientPtr *) xalloc(sizeof(ClientPtr));
+ if (!new || !newlist) {
+ xfree(new);
+ xfree(newlist);
+ return LbxSendTagFailed;
+ }
+ *newlist = client;
+ new->stalled_clients = newlist;
+ new->num_stalled = 1;
+ new->tag = tag;
+ new->next = NULL;
+
+ /* stick on end of list */
+ *prev = new;
+ return LbxSendTagSendIt;
+}
+
+SendTagQPtr
+LbxFindQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp;
+
+ for (stqp = queried_tags; stqp; stqp = stqp->next) {
+ if (stqp->tag == tag)
+ return stqp;
+ }
+ return NULL;
+}
+
+static void
+LbxFreeQTag(stqp)
+ SendTagQPtr stqp;
+{
+ xfree(stqp->stalled_clients);
+ xfree(stqp);
+}
+
+static void
+LbxRemoveQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp, *prev;
+
+ for (prev = &queried_tags; stqp = *prev; prev = &stqp->next) {
+ if (stqp->tag == tag) {
+ *prev = stqp->next;
+ LbxFreeQTag(stqp);
+ return;
+ }
+ }
+}
+
+Bool
+LbxFlushQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp;
+ ClientPtr *cp;
+
+ stqp = LbxFindQTag(tag);
+ if (!stqp)
+ return FALSE;
+ for (cp = stqp->stalled_clients; --stqp->num_stalled >= 0; cp++)
+ AttendClient(*cp);
+ LbxRemoveQTag(tag);
+ return TRUE;
+}
+
+void
+ProcessQTagZombies()
+{
+ SendTagQPtr stqp;
+ ClientPtr *out, *in;
+ int i;
+
+ for (stqp = queried_tags; stqp; stqp = stqp->next) {
+ out = stqp->stalled_clients;
+ for (in = out, i = stqp->num_stalled; --i >= 0; in++) {
+ if ((*in)->clientGone)
+ --stqp->num_stalled;
+ else
+ *out++ = *in;
+ }
+ }
+}
+
+/*
+ * server sends this
+ */
+
+void
+LbxQueryTagData(client, owner_pid, tag, tagtype)
+ ClientPtr client;
+ int owner_pid;
+ XID tag;
+ int tagtype;
+{
+ /* save the info and the client being stalled */
+ if (LbxQueueSendTag(client, tag) == LbxSendTagSendIt)
+ LbxSendSendTagData(owner_pid, tag, tagtype);
+}
+
+/*
+ * server recieves this
+ */
+int
+LbxTagData(client, tag, len, data)
+ ClientPtr client;
+ XID tag;
+ unsigned long len;
+ pointer data;
+{
+ TagData td;
+ PropertyPtr pProp;
+
+ td = TagGetTag(tag);
+ if (!td || td->data_type != LbxTagTypeProperty)
+ return Success;
+ if (!td->global) {
+ /* somebody changed contents while we were querying */
+ TagDeleteTag(tag);
+ return Success;
+ }
+ LbxFlushQTag(tag);
+ pProp = (PropertyPtr) td->tdata;
+ if (pProp->tag_id != tag || pProp->owner_pid != LbxProxyID(client))
+ return Success;
+ pProp->owner_pid = 0;
+ if (len != td->size)
+ pProp->size = len / (pProp->format >> 3);
+ pProp->data = xrealloc(pProp->data, len);
+ if (!pProp->data) {
+ pProp->size = 0;
+ return Success;
+ }
+ if (client->swapped) {
+ switch (pProp->format) {
+ case 32:
+ SwapLongs((CARD32 *) data, len >> 2);
+ break;
+ case 16:
+ SwapShorts((short *) data, len >> 1);
+ break;
+ default:
+ break;
+ }
+ }
+ memmove((char *) pProp->data, (char *) data, len);
+ return Success;
+}
+
+/* when server resets, need to reset global tags */
+void
+LbxResetTags()
+{
+ SendTagQPtr stqp;
+
+ modifier_map_tag = 0;
+ keyboard_map_tag = 0;
+
+ /* clean out any pending tag requests */
+ while (stqp = queried_tags) {
+ queried_tags = stqp->next;
+ LbxFreeQTag(stqp);
+ }
+}
diff --git a/lbx/lbxexts.c b/lbx/lbxexts.c
new file mode 100644
index 000000000..4ee5f87c6
--- /dev/null
+++ b/lbx/lbxexts.c
@@ -0,0 +1,270 @@
+/* $Xorg: lbxexts.c,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+typedef struct _lbxext {
+ char *name;
+ char **aliases;
+ int num_aliases;
+ int idx;
+ int opcode;
+ int ev_base;
+ int err_base;
+ int num_reqs;
+ CARD8 *rep_mask;
+ CARD8 *ev_mask;
+#ifdef XCSECURITY
+ Bool secure;
+#endif
+} LbxExtensionEntry;
+
+static LbxExtensionEntry **lbx_extensions = NULL;
+static int num_exts = 0;
+
+
+Bool
+LbxAddExtension(name, opcode, ev_base, err_base)
+ char *name;
+ int opcode;
+ int ev_base,
+ err_base;
+{
+ int i;
+ register LbxExtensionEntry *ext,
+ **newexts;
+
+ ext = (LbxExtensionEntry *) xalloc(sizeof(LbxExtensionEntry));
+ if (!ext)
+ return FALSE;
+ ext->name = (char *) xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **) NULL;
+ if (!ext->name) {
+ xfree(ext);
+ return FALSE;
+ }
+ strcpy(ext->name, name);
+ i = num_exts;
+ newexts = (LbxExtensionEntry **) xrealloc(lbx_extensions,
+ (i + 1) * sizeof(LbxExtensionEntry *));
+ if (!newexts) {
+ xfree(ext->name);
+ xfree(ext);
+ return FALSE;
+ }
+ num_exts++;
+ lbx_extensions = newexts;
+ lbx_extensions[i] = ext;
+ ext->idx = i;
+
+ ext->opcode = opcode;;
+ ext->ev_base = ev_base;;
+ ext->err_base = err_base;
+ ext->ev_mask = NULL;
+ ext->rep_mask = NULL;
+ ext->num_reqs = 0;
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+LbxAddExtensionAlias(idx, alias)
+ int idx;
+ char *alias;
+{
+ char *name;
+ char **aliases;
+ LbxExtensionEntry *ext = lbx_extensions[idx];
+
+ aliases = (char **) xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *) xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+ return TRUE;
+}
+
+static int
+LbxFindExtension(extname, len)
+ char *extname;
+ int len;
+{
+ int i, j;
+
+ for (i = 0; i < num_exts; i++) {
+ if ((strlen(lbx_extensions[i]->name) == len) &&
+ (strncmp(lbx_extensions[i]->name, extname, len) == 0))
+ return i;
+ for (j = lbx_extensions[i]->num_aliases; --j >= 0;) {
+ if ((strlen(lbx_extensions[i]->aliases[j]) == len) &&
+ (strncmp(lbx_extensions[i]->aliases[j], extname, len) == 0))
+ return i;
+ }
+ }
+ return -1;
+}
+
+void
+LbxDeclareExtensionSecurity(extname, secure)
+ char *extname;
+ Bool secure;
+{
+#ifdef XCSECURITY
+ int i = LbxFindExtension(extname, strlen(extname));
+ if (i >= 0)
+ lbx_extensions[i]->secure = secure;
+#endif
+}
+
+Bool
+LbxRegisterExtensionGenerationMasks(idx, num_reqs, rep_mask, ev_mask)
+ int idx;
+ int num_reqs;
+ char *rep_mask,
+ *ev_mask;
+{
+ LbxExtensionEntry *ext = lbx_extensions[idx];
+ CARD8 *nrm,
+ *nem;
+ int mlen = mlen = num_reqs / (8 * sizeof(CARD8)) + 1;
+
+ nrm = (CARD8 *) xalloc(sizeof(CARD8) * mlen);
+ nem = (CARD8 *) xalloc(sizeof(CARD8) * mlen);
+
+ if (!nrm || !nem) {
+ xfree(nrm);
+ xfree(nem);
+ return FALSE;
+ }
+ memcpy((char *) nrm, (char *) rep_mask, mlen);
+ memcpy((char *) nem, (char *) ev_mask, mlen);
+ ext->rep_mask = nrm;
+ ext->ev_mask = nem;
+ ext->num_reqs = num_reqs;
+
+ return TRUE;
+}
+
+int
+LbxQueryExtension(client, ename, nlen)
+ ClientPtr client;
+ char *ename;
+ int nlen;
+{
+ xLbxQueryExtensionReply rep;
+ int i;
+ int mlen = 0;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.major_opcode = 0;
+ rep.present = FALSE;
+ rep.length = 0;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ i = LbxFindExtension(ename, nlen);
+
+ if (i < 0
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !lbx_extensions[i]->secure)
+#endif
+ )
+ rep.present = FALSE;
+ else {
+ rep.present = TRUE;
+ rep.major_opcode = lbx_extensions[i]->opcode;
+ rep.first_event = lbx_extensions[i]->ev_base;
+ rep.first_error = lbx_extensions[i]->err_base;
+ rep.numReqs = lbx_extensions[i]->num_reqs;
+ if (lbx_extensions[i]->rep_mask) {
+ mlen = (lbx_extensions[i]->num_reqs + 7) >> 3;
+ rep.length = ((mlen + 3) >> 2) * 2;
+ }
+ }
+ if (client->swapped) {
+ char n;
+
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xLbxQueryExtensionReply), (char *)&rep);
+ if (mlen) {
+ WriteToClient(client, mlen, (char *)lbx_extensions[i]->rep_mask);
+ WriteToClient(client, mlen, (char *)lbx_extensions[i]->ev_mask);
+ }
+ return Success;
+}
+
+LbxCloseDownExtensions()
+{
+ int i;
+
+ for (i = 0; i < num_exts; i++) {
+ xfree(lbx_extensions[i]->name);
+ xfree(lbx_extensions[i]->aliases);
+ xfree(lbx_extensions[i]->rep_mask);
+ xfree(lbx_extensions[i]->ev_mask);
+ xfree(lbx_extensions[i]);
+ }
+ xfree(lbx_extensions);
+ lbx_extensions = NULL;
+ num_exts = 0;
+}
+
+void
+LbxSetReqMask(mask, req, on)
+ CARD8 *mask;
+ int req;
+ Bool on;
+{
+ int mword = req / (8 * sizeof(CARD8));
+
+ req = req % (8 * sizeof(CARD8));
+ if (on) {
+ mask[mword] |= (1 << req);
+ } else {
+ mask[mword] &= ~(1 << req);
+ }
+}
diff --git a/lbx/lbxgfx.c b/lbx/lbxgfx.c
new file mode 100644
index 000000000..25e87cc63
--- /dev/null
+++ b/lbx/lbxgfx.c
@@ -0,0 +1,867 @@
+/* $Xorg: lbxgfx.c,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "Xfuncproto.h"
+#include "lbximage.h"
+#include "lbxsrvopts.h"
+
+#define DrawableCache(client) (LbxClient(client)->drawableCache)
+#define GContextCache(client) (LbxClient(client)->gcontextCache)
+
+extern int (*ProcVector[256])();
+
+static void
+push (cache, xid)
+ XID cache[GFX_CACHE_SIZE];
+ XID xid;
+{
+ memmove (cache+1, cache, (GFX_CACHE_SIZE - 1) * sizeof (cache[0]));
+ cache[0] = xid;
+}
+
+static XID
+use (cache, i)
+ XID cache[GFX_CACHE_SIZE];
+ int i;
+{
+ XID tmp;
+
+ tmp = cache[i];
+ if (i != 0)
+ {
+ memmove (cache + 1, cache, i * sizeof (cache[0]));
+ cache[0] = tmp;
+ }
+ return tmp;
+}
+
+extern char *ConnectionInfo;
+
+int
+LbxDecodeGFXCache(client, cacheEnts, after, drawp, gcp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ Drawable *drawp;
+ GContext *gcp;
+{
+ int skip;
+ int dcache, gcache;
+
+ dcache = GFXdCacheEnt (cacheEnts);
+ gcache = GFXgCacheEnt (cacheEnts);
+ skip = 0;
+ if (dcache == GFXCacheNone)
+ {
+ memcpy (drawp, after, sizeof (Drawable));
+ push (DrawableCache(client), *drawp);
+ after += sizeof (Drawable);
+ skip += sizeof (Drawable);
+ }
+ else
+ *drawp = use (DrawableCache(client), dcache);
+ if (gcache == GFXCacheNone)
+ {
+ memcpy (gcp, after, sizeof (GContext));
+ push (GContextCache(client), *gcp);
+ skip += sizeof (GContext);
+ }
+ else
+ *gcp = use (GContextCache(client), gcache);
+ return skip;
+}
+
+int
+LbxDecodeDrawableCache(client, cacheEnts, after, drawp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ Drawable *drawp;
+{
+ int skip;
+ int dcache;
+
+ dcache = GFXdCacheEnt (cacheEnts);
+ skip = 0;
+ if (dcache == GFXCacheNone)
+ {
+ memcpy (drawp, after, sizeof (Drawable));
+ push (DrawableCache(client), *drawp);
+ after += sizeof (Drawable);
+ skip += sizeof (Drawable);
+ }
+ else
+ *drawp = use (DrawableCache(client), dcache);
+ return skip;
+}
+
+int
+LbxDecodeGCCache(client, cacheEnts, after, gcp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ GContext *gcp;
+{
+ int skip;
+ int gcache;
+
+ gcache = GFXgCacheEnt (cacheEnts);
+ skip = 0;
+ if (gcache == GFXCacheNone)
+ {
+ memcpy (gcp, after, sizeof (GContext));
+ push (GContextCache(client), *gcp);
+ after += sizeof (GContext);
+ skip += sizeof (GContext);
+ }
+ else
+ *gcp = use (GContextCache(client), gcache);
+ return skip;
+}
+
+#define GFX_GET_DRAWABLE_AND_GC(type,in,len) {\
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type);\
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &drawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_DST_DRAWABLE_AND_GC(type,in,len) {\
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type);\
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &dstDrawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_SRC_DST_DRAWABLE_AND_GC(type, in, len) { \
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type); \
+ skip = LbxDecodeDrawableCache(client, stuff->srcCache, in, \
+ &srcDrawable); \
+ in += skip; \
+ len -= skip; \
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &dstDrawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_GC(type, in, len) { \
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type); \
+ skip = LbxDecodeGCCache(client, stuff->gcCache, in, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+int
+LbxDecodePoly(client, xreqtype, decode_rtn)
+ register ClientPtr client;
+ CARD8 xreqtype;
+ int (*decode_rtn)();
+{
+ REQUEST(xLbxPolyPointReq);
+ char *in;
+ xPolyPointReq *xreq;
+ int len;
+ int retval;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxPolyPointReq, in, len);
+ if ((xreq = (xPolyPointReq *)
+ xalloc(sizeof(xPolyPointReq) + (len << 1))) == NULL)
+ return BadAlloc;
+ len = (*decode_rtn)(in, in + len - stuff->padBytes, &xreq[1]);
+ xreq->reqType = xreqtype;
+ xreq->coordMode = 1;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->length = client->req_len = (sizeof(xPolyPointReq) + len) >> 2;
+ client->requestBuffer = (pointer)xreq;
+
+ retval = (*ProcVector[xreqtype])(client);
+ xfree(xreq);
+ return retval;
+}
+
+int
+LbxDecodeFillPoly(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxFillPolyReq);
+ char *in;
+ xFillPolyReq *xreq;
+ int len;
+ int retval;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxFillPolyReq, in, len);
+ if ((xreq = (xFillPolyReq *)
+ xalloc(sizeof(xFillPolyReq) + (len << 1))) == NULL)
+ return BadAlloc;
+ len = LbxDecodePoints(in, in + len - stuff->padBytes, (short *) &xreq[1]);
+ xreq->reqType = X_FillPoly;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->shape = stuff->shape;
+ xreq->coordMode = 1;
+ xreq->length = client->req_len = (sizeof(xFillPolyReq) + len) >> 2;
+ client->requestBuffer = (pointer)xreq;
+
+ retval = (*ProcVector[X_FillPoly])(client);
+ xfree(xreq);
+ return retval;
+}
+
+/*
+ * Routines for decoding line drawing requests
+ */
+
+#define DECODE_PSHORT(in, val) \
+ if ((*(in) & 0xf0) != 0xf0) \
+ (val) = *(CARD8 *)(in)++; \
+ else { \
+ (val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
+ if ((val) >= 0xe00) \
+ (val) -= 0x1000; \
+ else \
+ (val) += 0xf0; \
+ (in) += 2; \
+ }
+
+#define DECODE_SHORT(in, val) \
+ if ((*(in) & 0xf0) != 0x80) \
+ (val) = *(INT8 *)(in)++; \
+ else { \
+ (val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
+ if ((val) & 0x0800) \
+ (val) = ((val) | 0xf000) - 0x70; \
+ else \
+ (val) += 0x80; \
+ (in) += 2; \
+ }
+
+#define DECODE_USHORT(in, val) \
+ if ((*(in) & 0xf0) != 0xf0) \
+ (val) = *(CARD8 *)(in)++; \
+ else { \
+ (val) = (((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1)) + 0xf0; \
+ (in) += 2; \
+ }
+
+#define DECODE_ANGLE(in, val) \
+ if (*(INT8 *)(in) >= 0x6e) \
+ (val) = (*(INT8 *)(in)++ - 0x67) * (15 << 6); \
+ else if (*(INT8 *)(in) >= 0x5a) \
+ (val) = (*(INT8 *)(in)++ - 0x5a) * (5 << 6); \
+ else if (*(INT8 *)(in) <= (INT8)0x91) \
+ (val) = (*(INT8 *)(in)++ - (INT8)0x98) * (15 << 6); \
+ else if (*(INT8 *)(in) <= (INT8)0xa5) \
+ (val) = (*(INT8 *)(in)++ - (INT8)0xa6) * (5 << 6); \
+ else { \
+ (val) = (*(CARD8 *)(in) << 8) | *(CARD8 *)((in) + 1); \
+ (in) += 2; \
+ }
+
+int
+LbxDecodePoints(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, *out);
+ out++;
+ DECODE_SHORT(in, *out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeSegment(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeRectangle(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeArc(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+
+ DECODE_ANGLE(in, *out);
+ out++;
+ DECODE_ANGLE(in, *out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeCopyArea (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxCopyAreaReq);
+ char *in;
+ xCopyAreaReq req;
+ int len;
+ Drawable srcDrawable, dstDrawable;
+ GContext gc;
+
+ GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyAreaReq, in, len);
+ req.reqType = X_CopyArea;
+ req.length = client->req_len = SIZEOF(xCopyAreaReq) >> 2;
+ req.srcDrawable = srcDrawable;
+ req.dstDrawable = dstDrawable;
+ req.gc = gc;
+ DECODE_PSHORT (in, req.srcX);
+ DECODE_PSHORT (in, req.srcY);
+ DECODE_PSHORT (in, req.dstX);
+ DECODE_PSHORT (in, req.dstY);
+ DECODE_USHORT (in, req.width);
+ DECODE_USHORT (in, req.height);
+ client->requestBuffer = (pointer) &req;
+ return (*ProcVector[X_CopyArea])(client);
+}
+
+int
+LbxDecodeCopyPlane (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxCopyPlaneReq);
+ char *in;
+ xCopyPlaneReq req;
+ int len;
+ Drawable srcDrawable, dstDrawable;
+ GContext gc;
+
+ GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyPlaneReq, in, len);
+ req.reqType = X_CopyPlane;
+ req.length = client->req_len = SIZEOF(xCopyPlaneReq) >> 2;
+ req.srcDrawable = srcDrawable;
+ req.dstDrawable = dstDrawable;
+ req.gc = gc;
+ DECODE_PSHORT (in, req.srcX);
+ DECODE_PSHORT (in, req.srcY);
+ DECODE_PSHORT (in, req.dstX);
+ DECODE_PSHORT (in, req.dstY);
+ DECODE_USHORT (in, req.width);
+ DECODE_USHORT (in, req.height);
+ req.bitPlane = stuff->bitPlane;
+ client->requestBuffer = (pointer) &req;
+ return (*ProcVector[X_CopyPlane])(client);
+}
+
+static pointer
+get_gfx_buffer(client, len)
+ ClientPtr client;
+ int len;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ pointer tmp;
+
+ /* XXX should probably shrink this sucker too */
+ if (len > lbxClient->gb_size) {
+ tmp = (pointer) xrealloc(lbxClient->gfx_buffer, len);
+ if (!tmp)
+ return (pointer) NULL;
+ lbxClient->gfx_buffer = tmp;
+ lbxClient->gb_size = len;
+ }
+ return lbxClient->gfx_buffer;
+}
+
+int
+LbxDecodePolyText (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxPolyTextReq);
+ char *in, *pos;
+ xPolyTextReq *xreq;
+ int len;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxPolyTextReq, in, len);
+ xreq = (xPolyTextReq *) get_gfx_buffer(client, sizeof (xPolyTextReq) + len);
+ if (!xreq)
+ return BadAlloc;
+ xreq->reqType = stuff->lbxReqType == X_LbxPolyText8? X_PolyText8 : X_PolyText16;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ pos = in;
+ DECODE_PSHORT(in, xreq->x);
+ DECODE_PSHORT(in, xreq->y);
+ len -= (in - pos);
+ memmove ((char *) (xreq + 1), in, len);
+ xreq->length = client->req_len = (sizeof (xPolyTextReq) + len) >> 2;
+ client->requestBuffer = (pointer) xreq;
+ return (*ProcVector[xreq->reqType])(client);
+}
+
+int
+LbxDecodeImageText (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxImageTextReq);
+ char *in, *pos;
+ xImageTextReq *xreq;
+ int len;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxImageTextReq, in, len);
+ xreq = (xImageTextReq *) get_gfx_buffer(client, sizeof (xImageTextReq) + len);
+ if (!xreq)
+ return BadAlloc;
+ xreq->reqType = stuff->lbxReqType == X_LbxImageText8? X_ImageText8 : X_ImageText16;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->nChars = stuff->nChars;
+ pos = in;
+ DECODE_PSHORT(in, xreq->x);
+ DECODE_PSHORT(in, xreq->y);
+ len -= (in - pos);
+ memmove ((char *) (xreq + 1), in, len);
+ xreq->length = client->req_len = (sizeof (xImageTextReq) + len) >> 2;
+ client->requestBuffer = (pointer) xreq;
+ return (*ProcVector[xreq->reqType])(client);
+}
+
+int
+LbxDecodePutImage (client)
+ register ClientPtr client;
+{
+ REQUEST (xLbxPutImageReq);
+ char *in, *data;
+ xPutImageReq xreq;
+ int ppl, bpl, nbytes;
+ int retval;
+ int n;
+
+ xreq.reqType = X_PutImage;
+
+ in = (char *) stuff + sz_xLbxPutImageReq;
+
+ if (stuff->bitPacked & 0x80) {
+ xreq.format = (stuff->bitPacked >> 5) & 0x3;
+ xreq.depth = ((stuff->bitPacked >> 2) & 0x7) + 1;
+ xreq.leftPad = 0;
+ } else {
+ xreq.depth = (stuff->bitPacked >> 2) + 1;
+ xreq.format = (*in >> 5) & 0x3;
+ xreq.leftPad = *in++ & 0x1f;
+ }
+ DECODE_USHORT(in, xreq.width);
+ DECODE_USHORT(in, xreq.height);
+ DECODE_PSHORT(in, xreq.dstX);
+ DECODE_PSHORT(in, xreq.dstY);
+ if (client->swapped) {
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone ||
+ GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (in, n);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone &&
+ GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (in + 4, n);
+ }
+ }
+ in += LbxDecodeGFXCache(client, stuff->cacheEnts, in,
+ &xreq.drawable, &xreq.gc);
+
+ ppl = xreq.width + xreq.leftPad;
+ if (xreq.format != ZPixmap ||
+ (xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1)) {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ bpl = BitmapBytePadProto(ppl);
+#else
+ bpl = BitmapBytePad(ppl);
+#endif
+ nbytes = bpl;
+ if (xreq.format == XYPixmap)
+ nbytes *= xreq.depth;
+ } else {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ bpl = PixmapBytePadProto(ppl, xreq.depth);
+#else
+ bpl = PixmapBytePad(ppl, xreq.depth);
+#endif
+ nbytes = bpl;
+ }
+ nbytes *= xreq.height;
+ xreq.length = ((nbytes + 3) >> 2) + (sz_xPutImageReq >> 2);
+ /* +1 is because fillspan in DecodeFaxG42D seems to go 1 byte too far,
+ * and I don't want to mess with that code */
+ if ((data = (char *) xalloc ((xreq.length << 2) + 1)) == NULL)
+ return BadAlloc;
+
+ *((xPutImageReq *)data) = xreq;
+
+ if (!stuff->compressionMethod)
+ {
+ memcpy(data + sz_xPutImageReq, in, nbytes);
+ }
+ else if (xreq.format != ZPixmap ||
+ (xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1))
+ {
+ LbxBitmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrLookupBitmapCompMethod (LbxProxy(client),
+ stuff->compressionMethod);
+
+ if (!compMethod)
+ {
+ xfree (data);
+ return (BadValue);
+ }
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ (*compMethod->decompFunc) (
+ (unsigned char *) in, (unsigned char *) data + sz_xPutImageReq,
+ nbytes,
+#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
+ (ppl + BITMAP_SCANLINE_UNIT - 1) & ~BITMAP_SCANLINE_UNIT,
+#else
+ ppl,
+#endif
+ bpl,
+ ((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst);
+ }
+ }
+ else
+ {
+ LbxPixmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrLookupPixmapCompMethod (LbxProxy(client),
+ stuff->compressionMethod);
+
+ if (!compMethod)
+ {
+ xfree (data);
+ return (BadValue);
+ }
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ (*compMethod->decompFunc) (
+ in, (char *) data + sz_xPutImageReq,
+ (int) xreq.height, bpl);
+ }
+ }
+
+ client->req_len = xreq.length;
+ client->requestBuffer = (pointer) data;
+
+ retval = (*ProcVector[X_PutImage])(client);
+ xfree(data);
+ return retval;
+}
+
+int
+LbxDecodeGetImage (client)
+ register ClientPtr client;
+{
+ REQUEST (xLbxGetImageReq);
+ xLbxGetImageReply *reply = NULL;
+ int lbxLen, xLen, n;
+ int method, bytes, status;
+ xGetImageReply *theImage;
+
+ REQUEST_SIZE_MATCH(xLbxGetImageReq);
+
+ status = DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, &theImage);
+
+ if (status != Success)
+ return (status);
+
+ if ((reply = (xLbxGetImageReply *) xalloc (
+ sz_xLbxGetImageReply + theImage->length)) == NULL)
+ {
+ xfree(theImage);
+ return (BadAlloc);
+ }
+
+ if (stuff->format != ZPixmap ||
+ (theImage->depth == 1 && screenInfo.formats->bitsPerPixel == 1))
+ {
+ LbxBitmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrFindPreferredBitmapCompMethod (LbxProxy(client));
+
+ if (!compMethod)
+ status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ status = (*compMethod->compFunc) (
+ (unsigned char *) &theImage[1],
+ (unsigned char *) &reply[1],
+ theImage->length,
+ theImage->length,
+#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
+ (int) (stuff->width + BITMAP_SCANLINE_UNIT - 1) &
+ ~BITMAP_SCANLINE_UNIT,
+#else
+ (int) stuff->width,
+#endif
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ BitmapBytePadProto(stuff->width),
+#else
+ BitmapBytePad(stuff->width),
+#endif
+ ((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst,
+ &bytes);
+
+ method = compMethod->methodOpCode;
+ }
+ }
+ else
+ {
+ LbxPixmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrFindPreferredPixmapCompMethod (
+ LbxProxy(client), (int) stuff->format, theImage->depth);
+
+ if (!compMethod)
+ status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ status = (*compMethod->compFunc) (
+ (char *) &theImage[1],
+ (char *) &reply[1],
+ theImage->length,
+ (int) stuff->format,
+ theImage->depth,
+ (int) stuff->height,
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ PixmapBytePadProto(stuff->width, theImage->depth),
+#else
+ PixmapBytePad(stuff->width, theImage->depth),
+#endif
+ &bytes);
+
+ method = compMethod->methodOpCode;
+ }
+ }
+
+ reply->type = X_Reply;
+ reply->depth = theImage->depth;
+ reply->sequenceNumber = client->sequence;
+ reply->visual = theImage->visual;
+ reply->pad1 = reply->pad2 = reply->pad3 = reply->pad4 = reply->pad5 = 0;
+
+ if (status != LBX_IMAGE_COMPRESS_SUCCESS)
+ {
+ reply->compressionMethod = LbxImageCompressNone;
+ reply->lbxLength = reply->xLength = (theImage->length + 3) >> 2;
+ }
+ else
+ {
+ reply->compressionMethod = method;
+ reply->lbxLength = (bytes + 3) >> 2;
+ reply->xLength = (theImage->length + 3) >> 2;
+ }
+
+ lbxLen = reply->lbxLength;
+ xLen = reply->xLength;
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->lbxLength, n);
+ swapl (&reply->xLength, n);
+ swapl (&reply->visual, n);
+ }
+
+ if (reply->compressionMethod != LbxImageCompressNone)
+ {
+ /*
+ * If the compressed image is greater that 25% of the original
+ * image, run the GetImage reply through the regular stream
+ * compressor. Otherwise, just write the compressed image.
+ */
+
+ if (lbxLen > (xLen / 4))
+ {
+ WriteToClient (client,
+ sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
+ }
+ else
+ {
+ UncompressedWriteToClient (client,
+ sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
+ }
+ }
+ else
+ {
+ /*
+ * Write back the original uncompressed image.
+ */
+
+ WriteToClient (client, sz_xLbxGetImageReply, (char *)reply);
+ WriteToClient (client, lbxLen << 2, (char *)&theImage[1]);
+ }
+
+ xfree (theImage);
+
+ if (reply)
+ xfree ((char *) reply);
+
+ return (Success);
+}
diff --git a/lbx/lbxmain.c b/lbx/lbxmain.c
new file mode 100644
index 000000000..3fa565fef
--- /dev/null
+++ b/lbx/lbxmain.c
@@ -0,0 +1,1819 @@
+/* $Xorg: lbxmain.c,v 1.4 2001/02/09 02:05:16 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "lbxdeltastr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbximage.h"
+#include "lbxsrvopts.h"
+#include "Xfuncproto.h"
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+#include <sys/uio.h>
+#include <stdio.h>
+
+#ifndef X_NOT_POSIX
+#include <unistd.h>
+#endif
+
+#define CloseLbxClient 0xff
+
+#define MAXBYTESDIFF 8
+
+extern void LbxAllowMotion();
+extern int LbxDecodePoints();
+extern int LbxDecodeSegment();
+extern int LbxDecodeRectangle();
+extern int LbxDecodeArc();
+
+extern int GrabInProgress;
+
+int LbxWhoAmI = 1; /*
+ * for lbx zlib library to know who we are
+ * server = 1
+ * proxy = 0
+ */
+
+int ProcLbxDispatch();
+extern int SProcLbxDispatch();
+static void LbxResetProc();
+static int DecodeLbxDelta();
+static void LbxFreeClient ();
+static void LbxShutdownProxy ();
+
+static LbxProxyPtr proxyList;
+unsigned char LbxReqCode;
+int LbxEventCode;
+static int BadLbxClientCode;
+static int uid_seed;
+
+static int lbxCompressWorkProcCount;
+
+LbxClientPtr lbxClients[MAXCLIENTS];
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+extern int (*LbxInitialVector[3])();
+
+#ifdef DEBUG
+int lbxDebug = 0;
+#endif
+
+
+void
+LbxExtensionInit()
+{
+ ExtensionEntry *extEntry;
+
+ lbxCompressWorkProcCount = 0;
+ proxyList = NULL;
+ uid_seed = 0;
+ if ((extEntry = AddExtension(LBXNAME, LbxNumberEvents, LbxNumberErrors,
+ ProcLbxDispatch, SProcLbxDispatch,
+ LbxResetProc, StandardMinorOpcode)))
+ {
+ LbxReqCode = (unsigned char)extEntry->base;
+ LbxEventCode = extEntry->eventBase;
+ BadLbxClientCode = extEntry->errorBase + BadLbxClient;
+ LbxDixInit();
+
+ LbxCmapInit ();
+ DeclareExtensionSecurity(LBXNAME, TRUE);
+ }
+}
+
+/*ARGSUSED*/
+static void
+LbxResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ LbxResetTags();
+ uid_seed = 0;
+}
+
+void
+LbxCloseClient (client)
+ ClientPtr client;
+{
+ xLbxCloseEvent closeEvent;
+ ClientPtr master;
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient = LbxClient(client);
+ CARD32 id;
+
+ if (!lbxClient)
+ return;
+ id = lbxClient->id;
+ proxy = lbxClient->proxy;
+
+ DBG (DBG_CLIENT, (stderr, "Close client %d\n", client->index));
+ LbxFreeClient (client);
+ if (!id)
+ {
+ isItTimeToYield = TRUE;
+ CloseDownFileDescriptor (client);
+ LbxShutdownProxy (proxy);
+ }
+ else
+ {
+ master = NULL;
+ if (proxy->lbxClients[0])
+ master = LbxProxyClient(proxy);
+ if (master && !master->clientGone)
+ {
+ closeEvent.type = LbxEventCode;
+ closeEvent.lbxType = LbxCloseEvent;
+ closeEvent.client = id;
+ closeEvent.sequenceNumber = master->sequence;
+ closeEvent.pad1 = closeEvent.pad2 = closeEvent.pad3 =
+ closeEvent.pad4 = closeEvent.pad5 = closeEvent.pad6 = 0;
+ if (master->swapped) {
+ int n;
+
+ swaps(&closeEvent.sequenceNumber, n);
+ swapl(&closeEvent.client, n);
+ }
+ WriteToClient(master, sizeof (closeEvent), (char *)&closeEvent);
+ LbxForceOutput(proxy);
+ }
+ }
+}
+
+static int
+LbxReencodeEvent(client, proxy, buf)
+ ClientPtr client;
+ LbxProxyPtr proxy;
+ char *buf;
+{
+ xEvent *ev = (xEvent *)buf;
+ int n;
+ lbxMotionCache *motionCache = &proxy->motionCache;
+ int motionDelta = 0;
+ Bool swapCache;
+ xEvent tev, *sev;
+
+ if (ev->u.u.type != MotionNotify) {
+ if (proxy->dosquishing)
+ return LbxSquishEvent(buf);
+ return 0;
+ }
+
+ /*
+ * Check if we can generate a motion delta event.
+ *
+ * The motion cache contains the last motion event the server sent.
+ *
+ * The following are always stored in the cache in the server's
+ * byte order:
+ * sequenceNumber, time, rootX, rootY, eventX, eventY
+ * This is because when determining if we can do a delta, all
+ * arithmetic must be done using the server's byte order.
+ *
+ * The following are stored in the byte order of the latest client
+ * receiving a motion event (indicated by motionCache->swapped):
+ * root, event, child, state
+ * These fields do not need to be stored in the server's byte order
+ * because we only use the '==' operator on them.
+ */
+
+ if (!proxy->motion_allowed_events) {
+ DBG(DBG_CLIENT, (stderr, "throttling motion event for client %d\n", client->index));
+ return sz_xEvent;
+ }
+ proxy->motion_allowed_events--;
+
+ motionCache = &proxy->motionCache;
+
+ if (!client->swapped)
+ {
+ swapCache = motionCache->swapped;
+ sev = ev;
+ }
+ else
+ {
+ swapCache = !motionCache->swapped;
+ sev = &tev;
+ cpswaps (ev->u.keyButtonPointer.rootX,
+ sev->u.keyButtonPointer.rootX);
+ cpswaps (ev->u.keyButtonPointer.rootY,
+ sev->u.keyButtonPointer.rootY);
+ cpswaps (ev->u.keyButtonPointer.eventX,
+ sev->u.keyButtonPointer.eventX);
+ cpswaps (ev->u.keyButtonPointer.eventY,
+ sev->u.keyButtonPointer.eventY);
+ cpswaps (ev->u.u.sequenceNumber,
+ sev->u.u.sequenceNumber);
+ cpswapl (ev->u.keyButtonPointer.time,
+ sev->u.keyButtonPointer.time);
+ }
+
+ if (swapCache)
+ {
+ swapl (&motionCache->root, n);
+ swapl (&motionCache->event, n);
+ swapl (&motionCache->child, n);
+ swaps (&motionCache->state, n);
+
+ motionCache->swapped = !motionCache->swapped;
+ }
+
+ motionDelta = 0;
+
+ if (ev->u.u.detail == motionCache->detail &&
+ ev->u.keyButtonPointer.root == motionCache->root &&
+ ev->u.keyButtonPointer.event == motionCache->event &&
+ ev->u.keyButtonPointer.child == motionCache->child &&
+ ev->u.keyButtonPointer.state == motionCache->state &&
+ ev->u.keyButtonPointer.sameScreen == motionCache->sameScreen) {
+
+ int root_delta_x =
+ sev->u.keyButtonPointer.rootX - motionCache->rootX;
+ int root_delta_y =
+ sev->u.keyButtonPointer.rootY - motionCache->rootY;
+ int event_delta_x =
+ sev->u.keyButtonPointer.eventX - motionCache->eventX;
+ int event_delta_y =
+ sev->u.keyButtonPointer.eventY - motionCache->eventY;
+ unsigned long sequence_delta =
+ sev->u.u.sequenceNumber - motionCache->sequenceNumber;
+ unsigned long time_delta =
+ sev->u.keyButtonPointer.time - motionCache->time;
+
+ if (root_delta_x == event_delta_x &&
+ event_delta_x >= -128 && event_delta_x < 128 &&
+ root_delta_y == event_delta_y &&
+ event_delta_y >= -128 && event_delta_y < 128) {
+
+ if (sequence_delta == 0 && time_delta < 256) {
+
+ lbxQuickMotionDeltaEvent *mev =
+ (lbxQuickMotionDeltaEvent *)(buf + sz_xEvent -
+ sz_lbxQuickMotionDeltaEvent);
+
+ mev->type = LbxEventCode + LbxQuickMotionDeltaEvent;
+ mev->deltaTime = time_delta;
+ mev->deltaX = event_delta_x;
+ mev->deltaY = event_delta_y;
+
+ motionDelta = sz_xEvent - sz_lbxQuickMotionDeltaEvent;
+
+ } else if (sequence_delta < 65536 && time_delta < 65536) {
+
+ lbxMotionDeltaEvent *mev =
+ (lbxMotionDeltaEvent *)(buf + sz_xEvent -
+ sz_lbxMotionDeltaEvent);
+
+ mev->type = LbxEventCode;
+ mev->lbxType = LbxMotionDeltaEvent;
+ mev->deltaTime = time_delta;
+ mev->deltaSequence = sequence_delta;
+ mev->deltaX = event_delta_x;
+ mev->deltaY = event_delta_y;
+
+ if (LbxProxyClient(proxy)->swapped)
+ {
+ swaps (&mev->deltaTime, n);
+ swaps (&mev->deltaSequence, n);
+ }
+
+ motionDelta = sz_xEvent - sz_lbxMotionDeltaEvent;
+ }
+ }
+ }
+
+ motionCache->sequenceNumber = sev->u.u.sequenceNumber;
+ motionCache->time = sev->u.keyButtonPointer.time;
+ motionCache->rootX = sev->u.keyButtonPointer.rootX;
+ motionCache->rootY = sev->u.keyButtonPointer.rootY;
+ motionCache->eventX = sev->u.keyButtonPointer.eventX;
+ motionCache->eventY = sev->u.keyButtonPointer.eventY;
+
+ if (motionDelta)
+ return motionDelta;
+
+ ev->u.keyButtonPointer.pad1 = 0;
+ motionCache->detail = ev->u.u.detail;
+ motionCache->root = ev->u.keyButtonPointer.root;
+ motionCache->event = ev->u.keyButtonPointer.event;
+ motionCache->child = ev->u.keyButtonPointer.child;
+ motionCache->state = ev->u.keyButtonPointer.state;
+ motionCache->sameScreen = ev->u.keyButtonPointer.sameScreen;
+ return 0;
+}
+
+static int
+LbxComposeDelta(proxy, reply, len, buf)
+ LbxProxyPtr proxy;
+ char *reply;
+ int len;
+ char *buf;
+{
+ int diffs;
+ int cindex;
+ int n;
+ xLbxDeltaReq *p = (xLbxDeltaReq *)buf;
+
+ diffs = LBXDeltaMinDiffs(&proxy->outdeltas, reply, len,
+ min(MAXBYTESDIFF, (len - sz_xLbxDeltaReq) >> 1),
+ &cindex);
+ if (diffs < 0) {
+ LBXAddDeltaOut(&proxy->outdeltas, reply, len);
+ return 0;
+ }
+ LBXEncodeDelta(&proxy->outdeltas, reply, diffs, cindex,
+ &buf[sz_xLbxDeltaReq]);
+ LBXAddDeltaOut(&proxy->outdeltas, reply, len);
+ p->reqType = LbxEventCode;
+ p->lbxReqType = LbxDeltaEvent;
+ p->diffs = diffs;
+ p->cindex = cindex;
+ len = (sz_xLbxDeltaReq + sz_xLbxDiffItem * diffs + 3) & ~3;
+ p->length = len >> 2;
+ if (LbxProxyClient(proxy)->swapped) {
+ swaps(&p->length, n);
+ }
+ return len;
+}
+
+void
+LbxReencodeOutput(client, pbuf, pcount, cbuf, ccount)
+ ClientPtr client;
+ char *pbuf;
+ int *pcount;
+ char *cbuf;
+ int *ccount;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ CARD32 len;
+ int n;
+ int count = *ccount;
+ char *obuf = cbuf;
+
+ if (client->clientState != ClientStateRunning) {
+ if (DELTA_CACHEABLE(&proxy->outdeltas, count) &&
+ (n = LbxComposeDelta(proxy, cbuf, count, proxy->oDeltaBuf))) {
+ memcpy(obuf, proxy->oDeltaBuf, n);
+ *ccount -= (count - n);
+ }
+ return;
+ }
+ if (lbxClient->bytes_remaining) {
+ if (count < lbxClient->bytes_remaining) {
+ lbxClient->bytes_remaining -= count;
+ return;
+ }
+ if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply)) {
+ len = lbxClient->bytes_in_reply - lbxClient->bytes_remaining;
+ pbuf += (*pcount - len);
+ memcpy(proxy->replyBuf, pbuf, len);
+ memcpy(proxy->replyBuf + len, cbuf, lbxClient->bytes_remaining);
+ n = LbxComposeDelta(proxy, proxy->replyBuf,
+ lbxClient->bytes_in_reply, proxy->oDeltaBuf);
+ if (!n)
+ obuf += lbxClient->bytes_remaining;
+ else if (n <= len) {
+ memcpy(pbuf, proxy->oDeltaBuf, n);
+ *pcount -= (len - n);
+ *ccount -= lbxClient->bytes_remaining;
+ } else {
+ memcpy(pbuf, proxy->oDeltaBuf, len);
+ memcpy(obuf, proxy->oDeltaBuf + len, n - len);
+ *ccount -= lbxClient->bytes_remaining - (n - len);
+ obuf += n - len;
+ }
+ } else
+ obuf += lbxClient->bytes_remaining;
+ cbuf += lbxClient->bytes_remaining;
+ count -= lbxClient->bytes_remaining;
+ lbxClient->bytes_remaining = 0;
+ }
+ while (count) {
+ lbxClient->bytes_in_reply = sz_xEvent;
+ if (((xGenericReply *)cbuf)->type == X_Reply) {
+ len = ((xGenericReply *)cbuf)->length;
+ if (client->swapped) {
+ swapl(&len, n);
+ }
+ lbxClient->bytes_in_reply += (len << 2);
+ if (LbxProxyClient(proxy)->swapped != client->swapped) {
+ swapl(&((xGenericReply *)cbuf)->length, n);
+ }
+ if (count < lbxClient->bytes_in_reply) {
+ lbxClient->bytes_remaining = lbxClient->bytes_in_reply - count;
+ if (obuf != cbuf)
+ memmove(obuf, cbuf, count);
+ return;
+ }
+ } else if (((xGenericReply *)cbuf)->type > X_Reply &&
+ ((xGenericReply *)cbuf)->type < LASTEvent &&
+ (n = LbxReencodeEvent(client, proxy, cbuf))) {
+ cbuf += n;
+ *ccount -= n;
+ count -= n;
+ if (n == sz_xEvent)
+ continue;
+ lbxClient->bytes_in_reply -= n;
+ }
+ if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply) &&
+ (n = LbxComposeDelta(proxy, cbuf, lbxClient->bytes_in_reply,
+ proxy->oDeltaBuf))) {
+ memcpy(obuf, proxy->oDeltaBuf, n);
+ obuf += n;
+ *ccount -= (lbxClient->bytes_in_reply - n);
+ } else {
+ if (obuf != cbuf)
+ memmove(obuf, cbuf, lbxClient->bytes_in_reply);
+ obuf += lbxClient->bytes_in_reply;
+ }
+ cbuf += lbxClient->bytes_in_reply;
+ count -= lbxClient->bytes_in_reply;
+ }
+}
+
+/*ARGSUSED*/
+static void
+LbxReplyCallback(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+ ClientPtr client = pri->client;
+ LbxClientPtr lbxClient;
+ REQUEST(xReq);
+
+ if (!pri->startOfReply || stuff->reqType > 127)
+ return;
+ lbxClient = LbxClient(client);
+ if (lbxClient)
+ ZeroReplyPadBytes(pri->replyData, stuff->reqType);
+}
+
+/*
+ * XXX If you think this is moronic, you're in good company,
+ * but things definitely hang if we don't have this.
+ */
+/* ARGSUSED */
+static Bool
+LbxCheckCompressInput (dummy1, dummy2)
+ ClientPtr dummy1;
+ pointer dummy2;
+{
+ LbxProxyPtr proxy;
+
+ if (!lbxCompressWorkProcCount)
+ return TRUE;
+
+ for (proxy = proxyList; proxy; proxy = proxy->next) {
+ if (proxy->compHandle &&
+ proxy->streamOpts.streamCompInputAvail(proxy->fd))
+ AvailableClientInput (LbxProxyClient(proxy));
+ }
+ return FALSE;
+}
+
+static Bool
+LbxIsClientBlocked (lbxClient)
+ LbxClientPtr lbxClient;
+{
+ LbxProxyPtr proxy = lbxClient->proxy;
+
+ return (lbxClient->ignored ||
+ (GrabInProgress && lbxClient->client->index != GrabInProgress &&
+ lbxClient != proxy->lbxClients[0]));
+}
+
+static void
+LbxSwitchRecv (proxy, lbxClient)
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient;
+{
+ ClientPtr client;
+
+ proxy->curRecv = lbxClient;
+ if (!lbxClient || lbxClient->client->clientGone)
+ {
+ DBG(DBG_CLIENT, (stderr, "switching to dispose input\n"));
+ lbxClient = proxy->lbxClients[0];
+ if (!lbxClient)
+ return;
+ }
+ client = lbxClient->client;
+ DBG (DBG_SWITCH, (stderr, "switching input to client %d\n", client->index));
+
+ SwitchClientInput (client, FALSE);
+ proxy->curDix = lbxClient;
+}
+
+/* ARGSUSED */
+static Bool
+LbxWaitForUnblocked (client, closure)
+ ClientPtr client;
+ pointer closure;
+{
+ LbxClientPtr lbxClient;
+ LbxProxyPtr proxy;
+
+ if (client->clientGone)
+ return TRUE;
+ lbxClient = LbxClient(client);
+ if (!lbxClient)
+ return TRUE;
+ proxy = lbxClient->proxy;
+ if (LbxIsClientBlocked (lbxClient) ||
+ ((lbxClient != proxy->curDix) && proxy->curDix->reqs_pending &&
+ !LbxIsClientBlocked(proxy->curDix)))
+ return FALSE;
+ lbxClient->input_blocked = FALSE;
+ DBG (DBG_BLOCK, (stderr, "client %d no longer blocked, switching\n",
+ client->index));
+ SwitchClientInput (client, TRUE);
+ proxy->curDix = lbxClient;
+ return TRUE;
+}
+
+void
+LbxSetForBlock(lbxClient)
+ LbxClientPtr lbxClient;
+{
+ lbxClient->reqs_pending++;
+ if (!lbxClient->input_blocked)
+ {
+ lbxClient->input_blocked = TRUE;
+ QueueWorkProc(LbxWaitForUnblocked, lbxClient->client, NULL);
+ }
+}
+
+/* ARGSUSED */
+static int
+LbxWaitForUngrab (client, closure)
+ ClientPtr client;
+ pointer closure;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy;
+ xLbxListenToAllEvent ungrabEvent;
+
+ if (client->clientGone || !lbxClient)
+ return TRUE;
+ if (GrabInProgress)
+ return FALSE;
+ proxy = lbxClient->proxy;
+ proxy->grabClient = 0;
+ ungrabEvent.type = LbxEventCode;
+ ungrabEvent.lbxType = LbxListenToAll;
+ ungrabEvent.pad1 = ungrabEvent.pad2 = ungrabEvent.pad3 =
+ ungrabEvent.pad4 = ungrabEvent.pad5 = ungrabEvent.pad6 =
+ ungrabEvent.pad7 = 0;
+ WriteToClient (client,
+ sizeof(xLbxListenToAllEvent), (char *)&ungrabEvent);
+ LbxForceOutput(proxy);
+ return TRUE;
+}
+
+static void
+LbxServerGrab(proxy)
+ LbxProxyPtr proxy;
+{
+ LbxClientPtr grabbingLbxClient;
+ xLbxListenToOneEvent grabEvent;
+
+ /*
+ * If the current grabbing client has changed, then we need
+ * to send a message to update the proxy.
+ */
+
+ grabEvent.type = LbxEventCode;
+ grabEvent.lbxType = LbxListenToOne;
+ if (!(grabbingLbxClient = lbxClients[GrabInProgress]) ||
+ grabbingLbxClient->proxy != proxy)
+ grabEvent.client = 0xffffffff; /* client other than a proxy client */
+ else
+ grabEvent.client = grabbingLbxClient->id;
+ grabEvent.pad1 = grabEvent.pad2 = grabEvent.pad3 =
+ grabEvent.pad4 = grabEvent.pad5 = grabEvent.pad6 = 0;
+ if (LbxProxyClient(proxy)->swapped) {
+ int n;
+ swapl(&grabEvent.client, n);
+ }
+ WriteToClient(LbxProxyClient(proxy),
+ sizeof(xLbxListenToOneEvent), (char *)&grabEvent);
+ LbxForceOutput(proxy);
+ if (!proxy->grabClient)
+ QueueWorkProc(LbxWaitForUngrab, LbxProxyClient(proxy), NULL);
+ proxy->grabClient = GrabInProgress;
+}
+
+#define MAJOROP(client) ((xReq *)client->requestBuffer)->reqType
+#define MINOROP(client) ((xReq *)client->requestBuffer)->data
+
+static Bool lbxCacheable[] = {
+ FALSE, /* LbxQueryVersion 0 */
+ FALSE, /* LbxStartProxy 1 */
+ TRUE, /* LbxStopProxy 2 */
+ FALSE, /* LbxSwitch 3 */
+ FALSE, /* LbxNewClient 4 */
+ TRUE, /* LbxCloseClient 5 */
+ TRUE, /* LbxModifySequence 6 */
+ FALSE, /* LbxAllowMotion 7 */
+ TRUE, /* LbxIncrementPixel 8 */
+ FALSE, /* LbxDelta 9 */
+ TRUE, /* LbxGetModifierMapping 10 */
+ FALSE, /* nothing 11 */
+ TRUE, /* LbxInvalidateTag 12 */
+ TRUE, /* LbxPolyPoint 13 */
+ TRUE, /* LbxPolyLine 14 */
+ TRUE, /* LbxPolySegment 15 */
+ TRUE, /* LbxPolyRectangle 16 */
+ TRUE, /* LbxPolyArc 17 */
+ TRUE, /* LbxFillPoly 18 */
+ TRUE, /* LbxPolyFillRectangle 19 */
+ TRUE, /* LbxPolyFillArc 20 */
+ TRUE, /* LbxGetKeyboardMapping 21 */
+ TRUE, /* LbxQueryFont 22 */
+ TRUE, /* LbxChangeProperty 23 */
+ TRUE, /* LbxGetProperty 24 */
+ TRUE, /* LbxTagData 25 */
+ TRUE, /* LbxCopyArea 26 */
+ TRUE, /* LbxCopyPlane 27 */
+ TRUE, /* LbxPolyText8 28 */
+ TRUE, /* LbxPolyText16 29 */
+ TRUE, /* LbxImageText8 30 */
+ TRUE, /* LbxImageText16 31 */
+ FALSE, /* LbxQueryExtension 32 */
+ TRUE, /* LbxPutImage 33 */
+ TRUE, /* LbxGetImage 34 */
+ FALSE, /* LbxBeginLargeRequest 35 */
+ FALSE, /* LbxLargeRequestData 36 */
+ FALSE, /* LbxEndLargeRequest 37 */
+ FALSE, /* LbxInternAtoms 38 */
+ TRUE, /* LbxGetWinAttrAndGeom 39 */
+ TRUE, /* LbxGrabCmap 40 */
+ TRUE, /* LbxReleaseCmap 41 */
+ TRUE, /* LbxAllocColor 42 */
+ TRUE, /* LbxSync 43 */
+};
+
+#define NUM(a) (sizeof (a) / sizeof (a[0]))
+
+static int
+LbxReadRequestFromClient (client)
+ ClientPtr client;
+{
+ int ret;
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ ClientPtr masterClient = LbxProxyClient(proxy);
+ Bool isblocked;
+ Bool cacheable;
+
+ DBG (DBG_READ_REQ, (stderr, "Reading request from client %d\n", client->index));
+
+ if (GrabInProgress && (proxy->grabClient != GrabInProgress))
+ LbxServerGrab(proxy);
+ isblocked = LbxIsClientBlocked(lbxClient);
+
+ if (lbxClient->reqs_pending && !isblocked) {
+ ret = StandardReadRequestFromClient(client);
+ if (ret > 0 && (MAJOROP(client) == LbxReqCode) &&
+ (MINOROP(client) == X_LbxEndLargeRequest))
+ ret = PrepareLargeReqBuffer(client);
+ if (!--lbxClient->reqs_pending && (lbxClient != proxy->curRecv))
+ LbxSwitchRecv (proxy, proxy->curRecv);
+ return ret;
+ }
+ while (1) {
+ ret = StandardReadRequestFromClient(masterClient);
+ if (ret <= 0)
+ return ret;
+ client->requestBuffer = masterClient->requestBuffer;
+ client->req_len = masterClient->req_len;
+ cacheable = client->clientState == ClientStateRunning;
+ if (cacheable && (MAJOROP(client) == LbxReqCode)) {
+ /* Check to see if this request is delta cached */
+ if (MINOROP(client) < NUM(lbxCacheable))
+ cacheable = lbxCacheable[MINOROP(client)];
+ switch (MINOROP(client)) {
+ case X_LbxSwitch:
+ /* Switch is sent by proxy */
+ if (masterClient->swapped)
+ SProcLbxSwitch (client);
+ else
+ ProcLbxSwitch (client);
+ return 0;
+ case X_LbxDelta:
+ ret = DecodeLbxDelta (client);
+ DBG(DBG_DELTA,
+ (stderr,"delta decompressed msg %d, len = %d\n",
+ (unsigned)((unsigned char *)client->requestBuffer)[0],
+ ret));
+ break;
+ case X_LbxEndLargeRequest:
+ if (!isblocked)
+ ret = PrepareLargeReqBuffer(client);
+ break;
+ }
+ }
+ if (cacheable && DELTA_CACHEABLE(&proxy->indeltas, ret)) {
+ DBG(DBG_DELTA,
+ (stderr, "caching msg %d, len = %d, index = %d\n",
+ (unsigned)((unsigned char *)client->requestBuffer)[0],
+ ret, proxy->indeltas.nextDelta));
+ LBXAddDeltaIn(&proxy->indeltas, client->requestBuffer, ret);
+ }
+ if (client->swapped != masterClient->swapped) {
+ char n;
+ /* put length in client order */
+ swaps(&((xReq *)client->requestBuffer)->length, n);
+ }
+ if (!isblocked)
+ return ret;
+ DBG (DBG_BLOCK, (stderr, "Stashing %d bytes for %d\n",
+ ret, client->index));
+ AppendFakeRequest (client, client->requestBuffer, ret);
+ LbxSetForBlock(lbxClient);
+ }
+}
+
+static LbxClientPtr
+LbxInitClient (proxy, client, id)
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ CARD32 id;
+{
+ LbxClientPtr lbxClient;
+ int i;
+
+ lbxClient = (LbxClientPtr) xalloc (sizeof (LbxClientRec));
+ if (!lbxClient)
+ return NULL;
+ lbxClient->id = id;
+ lbxClient->client = client;
+ lbxClient->proxy = proxy;
+ lbxClient->ignored = FALSE;
+ lbxClient->input_blocked = FALSE;
+ lbxClient->reqs_pending = 0;
+ lbxClient->bytes_in_reply = 0;
+ lbxClient->bytes_remaining = 0;
+ client->readRequest = LbxReadRequestFromClient;
+ bzero (lbxClient->drawableCache, sizeof (lbxClient->drawableCache));
+ bzero (lbxClient->gcontextCache, sizeof (lbxClient->gcontextCache));
+ lbxClients[client->index] = lbxClient;
+ for (i = 0; proxy->lbxClients[i]; i++)
+ ;
+ if (i > proxy->maxIndex)
+ proxy->maxIndex = i;
+ proxy->lbxClients[i] = lbxClient;
+ proxy->numClients++;
+ lbxClient->gfx_buffer = (pointer) NULL;
+ lbxClient->gb_size = 0;
+ return lbxClient;
+}
+
+static void
+LbxFreeClient (client)
+ ClientPtr client;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ int i;
+
+ if (lbxClient != proxy->lbxClients[0]) {
+ if (lbxClient == proxy->curRecv)
+ LbxSwitchRecv(proxy, NULL);
+ else if (lbxClient == proxy->curDix)
+ LbxSwitchRecv(proxy, proxy->curRecv);
+ }
+
+ --proxy->numClients;
+ lbxClients[client->index] = NULL;
+ for (i = 0; i <= proxy->maxIndex; i++) {
+ if (proxy->lbxClients[i] == lbxClient) {
+ proxy->lbxClients[i] = NULL;
+ break;
+ }
+ }
+ while (proxy->maxIndex >= 0 && !proxy->lbxClients[proxy->maxIndex])
+ --proxy->maxIndex;
+ xfree(lbxClient->gfx_buffer);
+ client->readRequest = StandardReadRequestFromClient;
+ xfree (lbxClient);
+}
+
+static void
+LbxFreeProxy (proxy)
+ LbxProxyPtr proxy;
+{
+ LbxProxyPtr *p;
+
+ LBXFreeDeltaCache(&proxy->indeltas);
+ LBXFreeDeltaCache(&proxy->outdeltas);
+ LbxFreeOsBuffers(proxy);
+ if (proxy->iDeltaBuf)
+ xfree(proxy->iDeltaBuf);
+ if (proxy->replyBuf)
+ xfree(proxy->replyBuf);
+ if (proxy->oDeltaBuf)
+ xfree(proxy->oDeltaBuf);
+ if (proxy->compHandle)
+ proxy->streamOpts.streamCompFreeHandle(proxy->compHandle);
+ if (proxy->bitmapCompMethods)
+ xfree (proxy->bitmapCompMethods);
+ if (proxy->pixmapCompMethods)
+ xfree (proxy->pixmapCompMethods);
+ if (proxy->pixmapCompDepths)
+ {
+ int i;
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ xfree (proxy->pixmapCompDepths[i]);
+ xfree (proxy->pixmapCompDepths);
+ }
+
+ for (p = &proxyList; *p; p = &(*p)->next) {
+ if (*p == proxy) {
+ *p = proxy->next;
+ break;
+ }
+ }
+ if (!proxyList)
+ DeleteCallback(&ReplyCallback, LbxReplyCallback, NULL);
+
+ xfree (proxy);
+}
+
+LbxProxyPtr
+LbxPidToProxy(pid)
+ int pid;
+{
+ LbxProxyPtr proxy;
+
+ for (proxy = proxyList; proxy; proxy = proxy->next) {
+ if (proxy->pid == pid)
+ return proxy;
+ }
+ return NULL;
+}
+
+static void
+LbxShutdownProxy (proxy)
+ LbxProxyPtr proxy;
+{
+ int i;
+ ClientPtr client;
+
+ if (proxy->compHandle)
+ --lbxCompressWorkProcCount;
+ while (proxy->grabbedCmaps)
+ LbxReleaseCmap(proxy->grabbedCmaps, FALSE);
+ for (i = 0; i <= proxy->maxIndex; i++)
+ {
+ if (proxy->lbxClients[i])
+ {
+ client = proxy->lbxClients[i]->client;
+ if (!client->clientGone)
+ CloseDownClient (client);
+ }
+ }
+ LbxFlushTags(proxy);
+ LbxFreeProxy(proxy);
+}
+
+
+int
+ProcLbxQueryVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxQueryVersionReq);
+ xLbxQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xLbxQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = LBX_MAJOR_VERSION;
+ rep.minorVersion = LBX_MINOR_VERSION;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xLbxQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+NextProxyID()
+{
+ LbxProxyPtr proxy;
+ int id;
+
+ for (id = 1; id < MAX_NUM_PROXIES; id++) {
+ for (proxy = proxyList; proxy && proxy->pid != id; proxy = proxy->next)
+ ;
+ if (!proxy)
+ return id;
+ }
+ return -1;
+}
+
+int
+ProcLbxStartProxy(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxStartProxyReq);
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient;
+ int reqlen;
+ int replylen;
+ xLbxStartReply *replybuf;
+ LbxNegOptsRec negopt;
+ register int n;
+ pointer compHandle = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xLbxStartProxyReq);
+ if (lbxClients[client->index])
+ return BadLbxClientCode;
+ proxy = (LbxProxyPtr) xalloc (sizeof (LbxProxyRec));
+ if (!proxy)
+ return BadAlloc;
+ bzero(proxy, sizeof (LbxProxyRec));
+ proxy->pid = NextProxyID();
+ if (proxy->pid < 0) { /* too many proxies */
+ xfree(proxy);
+ return BadAlloc;
+ }
+ proxy->uid = ++uid_seed;
+ if (!proxyList)
+ AddCallback(&ReplyCallback, LbxReplyCallback, NULL);
+
+ if(!proxyList)
+ proxyList = proxy;
+ else{
+ proxy->next = proxyList;
+ proxyList = proxy;
+ }
+
+ /*
+ * Don't know exactly how big the reply will be, but it won't be
+ * bigger than the request
+ */
+ reqlen = client->req_len << 2;
+ replybuf = (xLbxStartReply *) xalloc(max(reqlen, sz_xLbxStartReply));
+ if (!replybuf) {
+ LbxFreeProxy(proxy);
+ return BadAlloc;
+ }
+
+ LbxOptionInit(&negopt);
+
+ replylen = LbxOptionParse(&negopt,
+ &stuff[1],
+ reqlen - sz_xLbxStartProxyReq,
+ &replybuf->optDataStart);
+ if (replylen < 0) {
+ /*
+ * Didn't understand option format, so we'll just end up
+ * using the defaults. Set nopts so that the proxy will
+ * be informed that we rejected the options because of
+ * decoding problems.
+ */
+ LbxOptionInit(&negopt);
+ negopt.nopts = 0xff;
+ replylen = 0;
+ }
+
+ if (LBXInitDeltaCache(&proxy->indeltas, negopt.proxyDeltaN,
+ negopt.proxyDeltaMaxLen) < 0
+ ||
+ LBXInitDeltaCache(&proxy->outdeltas, negopt.serverDeltaN,
+ negopt.serverDeltaMaxLen) < 0) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+
+ n = 0;
+ if (negopt.proxyDeltaN)
+ n = negopt.proxyDeltaMaxLen;
+ if (negopt.serverDeltaN && negopt.serverDeltaMaxLen > n)
+ n = negopt.serverDeltaMaxLen;
+ if (n &&
+ (!(proxy->iDeltaBuf = (char *)xalloc (n)) ||
+ !(proxy->replyBuf = (char *)xalloc (n)) ||
+ !(proxy->oDeltaBuf = (char *)xalloc (n)))) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+
+ MakeClientGrabImpervious(client); /* proxy needs to be grab-proof */
+ proxy->fd = ClientConnectionNumber(client);
+ if (negopt.streamOpts.streamCompInit) {
+ compHandle =
+ (*negopt.streamOpts.streamCompInit)(proxy->fd, negopt.streamOpts.streamCompArg);
+ if (!compHandle) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+ }
+ proxy->ofirst = NULL;
+ proxy->olast = NULL;
+ if (!LbxInitClient (proxy, client, 0))
+ {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+ proxy->dosquishing = negopt.squish;
+ proxy->numBitmapCompMethods = negopt.numBitmapCompMethods;
+ proxy->bitmapCompMethods = negopt.bitmapCompMethods;
+ proxy->numPixmapCompMethods = negopt.numPixmapCompMethods;
+ proxy->pixmapCompMethods = negopt.pixmapCompMethods;
+ proxy->pixmapCompDepths = negopt.pixmapCompDepths;
+
+ proxy->streamOpts = negopt.streamOpts;
+ proxy->useTags = negopt.useTags;
+
+ proxy->grabbedCmaps = NULL;
+
+ /* send reply */
+ replybuf->type = X_Reply;
+ replybuf->nOpts = negopt.nopts;
+ replybuf->sequenceNumber = client->sequence;
+
+ replylen += sz_xLbxStartReplyHdr;
+ if (replylen < sz_xLbxStartReply)
+ replylen = sz_xLbxStartReply;
+ replybuf->length = (replylen - sz_xLbxStartReply + 3) >> 2;
+ if (client->swapped) {
+ swaps(&replybuf->sequenceNumber, n);
+ swapl(&replybuf->length, n);
+ }
+ lbxClient = LbxClient(client);
+ WriteToClient(client, replylen, (char *)replybuf);
+
+ LbxProxyConnection(client, proxy);
+ lbxClient = proxy->lbxClients[0];
+ proxy->curDix = lbxClient;
+ proxy->curRecv = lbxClient;
+ proxy->compHandle = compHandle;
+
+ if (proxy->compHandle && !lbxCompressWorkProcCount++)
+ QueueWorkProc(LbxCheckCompressInput, NULL, NULL);
+
+ xfree(replybuf);
+ return Success;
+}
+
+int
+ProcLbxStopProxy(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxStopProxyReq);
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ REQUEST_SIZE_MATCH(xLbxStopProxyReq);
+
+ if (!lbxClient)
+ return BadLbxClientCode;
+ if (lbxClient->id)
+ return BadLbxClientCode;
+
+ proxy = lbxClient->proxy;
+ LbxFreeClient (client);
+ LbxShutdownProxy (proxy);
+ return Success;
+}
+
+int
+ProcLbxSwitch(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxSwitchReq);
+ LbxProxyPtr proxy = LbxMaybeProxy(client);
+ LbxClientPtr lbxClient;
+ int i;
+
+ REQUEST_SIZE_MATCH(xLbxSwitchReq);
+ if (!proxy)
+ return BadLbxClientCode;
+ for (i = 0; i <= proxy->maxIndex; i++) {
+ lbxClient = proxy->lbxClients[i];
+ if (lbxClient && lbxClient->id == stuff->client) {
+ LbxSwitchRecv (proxy, lbxClient);
+ return Success;
+ }
+ }
+ LbxSwitchRecv (proxy, NULL);
+ return BadLbxClientCode;
+}
+
+int
+ProcLbxBeginLargeRequest(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxBeginLargeRequestReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxBeginLargeRequestReq);
+ if (!AllocateLargeReqBuffer(client, stuff->largeReqLength << 2))
+ return BadAlloc;
+ return Success;
+}
+
+
+int
+ProcLbxLargeRequestData(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxLargeRequestDataReq);
+
+ client->sequence--;
+ REQUEST_AT_LEAST_SIZE(xLbxLargeRequestDataReq);
+ if (!AddToLargeReqBuffer(client, (char *) (stuff + 1),
+ (client->req_len - 1) << 2))
+ return BadAlloc;
+ return Success;
+}
+
+
+int
+ProcLbxEndLargeRequest(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xReq);
+ return BadAlloc;
+}
+
+
+int
+ProcLbxInternAtoms(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxInternAtomsReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+ xLbxInternAtomsReply *replyRet;
+ char *ptr = (char *) stuff + sz_xLbxInternAtomsReq;
+ Atom *atomsRet;
+ int replyLen, i;
+ char lenbuf[2];
+ CARD16 len;
+ char n;
+
+ REQUEST_AT_LEAST_SIZE(xLbxInternAtomsReq);
+
+ if (!lbxClient)
+ return BadLbxClientCode;
+ if (lbxClient->id)
+ return BadLbxClientCode;
+
+ replyLen = sz_xLbxInternAtomsReplyHdr + stuff->num * sizeof (Atom);
+ if (replyLen < sz_xLbxInternAtomsReply)
+ replyLen = sz_xLbxInternAtomsReply;
+
+ if (!(replyRet = (xLbxInternAtomsReply *) xalloc (replyLen)))
+ return BadAlloc;
+
+ atomsRet = (Atom *) ((char *) replyRet + sz_xLbxInternAtomsReplyHdr);
+
+ for (i = 0; i < stuff->num; i++)
+ {
+ lenbuf[0] = ptr[0];
+ lenbuf[1] = ptr[1];
+ len = *((CARD16 *) lenbuf);
+ ptr += 2;
+
+ if ((atomsRet[i] = MakeAtom (ptr, len, TRUE)) == BAD_RESOURCE)
+ {
+ xfree (replyRet);
+ return BadAlloc;
+ }
+
+ ptr += len;
+ }
+
+ if (client->swapped)
+ for (i = 0; i < stuff->num; i++)
+ swapl (&atomsRet[i], n);
+
+ replyRet->type = X_Reply;
+ replyRet->sequenceNumber = client->sequence;
+ replyRet->length = (replyLen - sz_xLbxInternAtomsReply + 3) >> 2;
+
+ if (client->swapped) {
+ swaps(&replyRet->sequenceNumber, n);
+ swapl(&replyRet->length, n);
+ }
+
+ WriteToClient (client, replyLen, (char *) replyRet);
+
+ xfree (replyRet);
+
+ return Success;
+}
+
+
+int
+ProcLbxGetWinAttrAndGeom(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxGetWinAttrAndGeomReq);
+ xGetWindowAttributesReply wa;
+ xGetGeometryReply wg;
+ xLbxGetWinAttrAndGeomReply reply;
+ WindowPtr pWin;
+ int status;
+
+ REQUEST_SIZE_MATCH(xLbxGetWinAttrAndGeomReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+
+ if ((status = GetGeometry(client, &wg)) != Success)
+ return status;
+
+ reply.type = X_Reply;
+ reply.length = (sz_xLbxGetWinAttrAndGeomReply - 32) >> 2;
+ reply.sequenceNumber = client->sequence;
+
+ reply.backingStore = wa.backingStore;
+ reply.visualID = wa.visualID;
+#if defined(__cplusplus) || defined(c_plusplus)
+ reply.c_class = wa.c_class;
+#else
+ reply.class = wa.class;
+#endif
+ reply.bitGravity = wa.bitGravity;
+ reply.winGravity = wa.winGravity;
+ reply.backingBitPlanes = wa.backingBitPlanes;
+ reply.backingPixel = wa.backingPixel;
+ reply.saveUnder = wa.saveUnder;
+ reply.mapInstalled = wa.mapInstalled;
+ reply.mapState = wa.mapState;
+ reply.override = wa.override;
+ reply.colormap = wa.colormap;
+ reply.allEventMasks = wa.allEventMasks;
+ reply.yourEventMask = wa.yourEventMask;
+ reply.doNotPropagateMask = wa.doNotPropagateMask;
+ reply.pad1 = 0;
+ reply.root = wg.root;
+ reply.x = wg.x;
+ reply.y = wg.y;
+ reply.width = wg.width;
+ reply.height = wg.height;
+ reply.borderWidth = wg.borderWidth;
+ reply.depth = wg.depth;
+ reply.pad2 = 0;
+
+ if (client->swapped)
+ {
+ register char n;
+
+ swaps(&reply.sequenceNumber, n);
+ swapl(&reply.length, n);
+ swapl(&reply.visualID, n);
+ swaps(&reply.class, n);
+ swapl(&reply.backingBitPlanes, n);
+ swapl(&reply.backingPixel, n);
+ swapl(&reply.colormap, n);
+ swapl(&reply.allEventMasks, n);
+ swapl(&reply.yourEventMask, n);
+ swaps(&reply.doNotPropagateMask, n);
+ swapl(&reply.root, n);
+ swaps(&reply.x, n);
+ swaps(&reply.y, n);
+ swaps(&reply.width, n);
+ swaps(&reply.height, n);
+ swaps(&reply.borderWidth, n);
+ }
+
+ WriteToClient(client, sizeof(xLbxGetWinAttrAndGeomReply), (char *)&reply);
+ return(client->noClientException);
+}
+
+int
+ProcLbxNewClient(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxNewClientReq);
+ ClientPtr newClient;
+ LbxProxyPtr proxy = LbxMaybeProxy(client);
+ CARD32 id;
+ int len, i;
+ char *setupbuf;
+ LbxClientPtr lbxClient;
+
+ REQUEST_AT_LEAST_SIZE(xLbxNewClientReq);
+
+ /* save info before our request disappears */
+ id = stuff->client;
+ if (!proxy || !id)
+ return BadLbxClientCode;
+ if (proxy->numClients == MAX_LBX_CLIENTS)
+ return BadAlloc;
+ for (i = 1; i <= proxy->maxIndex; i++) {
+ if (proxy->lbxClients[i] && proxy->lbxClients[i]->id == id)
+ return BadLbxClientCode;
+ }
+ len = (client->req_len << 2) - sizeof(xLbxNewClientReq);
+ setupbuf = (char *)xalloc (len);
+ if (!setupbuf)
+ return BadAlloc;
+ memcpy (setupbuf, (char *)&stuff[1], len);
+
+ newClient = AllocLbxClientConnection (client, proxy);
+ if (!newClient)
+ return BadAlloc;
+ newClient->requestVector = LbxInitialVector;
+ lbxClient = LbxInitClient (proxy, newClient, id);
+ if (!lbxClient)
+ {
+ CloseDownClient (newClient);
+ return BadAlloc;
+ }
+
+ AppendFakeRequest (newClient, setupbuf, len);
+ xfree (setupbuf);
+ LbxSetForBlock(lbxClient);
+
+ DBG (DBG_CLIENT, (stderr, "lbxNewClient X %d\n", newClient->index));
+ return Success;
+}
+
+int
+ProcLbxEstablishConnection(client)
+ register ClientPtr client;
+{
+ char *reason = NULL;
+ char *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ prefix->nbytesAuthProto,
+ auth_proto,
+ prefix->nbytesAuthString,
+ auth_string);
+
+ if (client->clientState == ClientStateCheckingSecurity ||
+ client->clientState == ClientStateAuthenticating)
+ return (client->noClientException = -1); /* XXX some day */
+ return(LbxSendConnSetup(client, reason));
+}
+
+int
+ProcLbxCloseClient (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxCloseClientReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ REQUEST_SIZE_MATCH(xLbxCloseClientReq);
+ if (!lbxClient || lbxClient->id != stuff->client)
+ return BadLbxClientCode;
+
+ /* this will cause the client to be closed down back in Dispatch() */
+ return(client->noClientException = CloseLbxClient);
+}
+
+int
+ProcLbxModifySequence (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxModifySequenceReq);
+
+ REQUEST_SIZE_MATCH(xLbxModifySequenceReq);
+ client->sequence += (stuff->adjust - 1); /* Dispatch() adds 1 */
+ return Success;
+}
+
+int
+ProcLbxAllowMotion (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxAllowMotionReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxAllowMotionReq);
+ LbxAllowMotion(client, stuff->num);
+ return Success;
+}
+
+
+static int
+DecodeLbxDelta(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxDeltaReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ int len;
+ char *buf;
+
+ /* Note that LBXDecodeDelta decodes and adds current msg to the cache */
+ len = LBXDecodeDelta(&proxy->indeltas, ((char *)stuff) + sz_xLbxDeltaReq,
+ stuff->diffs, stuff->cindex, &buf);
+ /*
+ * Some requests, such as FillPoly, result in the protocol input
+ * buffer being modified. So we need to copy the request
+ * into a temporary buffer where a write would be harmless.
+ * Maybe some day do this copying on a case by case basis,
+ * since not all requests are guilty of this.
+ */
+ memcpy(proxy->iDeltaBuf, buf, len);
+
+ client->requestBuffer = proxy->iDeltaBuf;
+ client->req_len = len >> 2;
+ return len;
+}
+
+int
+ProcLbxGetModifierMapping(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetModifierMappingReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetModifierMappingReq);
+ return LbxGetModifierMapping(client);
+}
+
+int
+ProcLbxGetKeyboardMapping(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetKeyboardMappingReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
+ return LbxGetKeyboardMapping(client);
+}
+
+int
+ProcLbxQueryFont(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxQueryFontReq);
+
+ REQUEST_SIZE_MATCH(xLbxQueryFontReq);
+ return LbxQueryFont(client);
+}
+
+int
+ProcLbxChangeProperty(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxChangePropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
+ return LbxChangeProperty(client);
+}
+
+int
+ProcLbxGetProperty(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
+ return LbxGetProperty(client);
+}
+
+int
+ProcLbxTagData(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxTagDataReq);
+
+ client->sequence--; /* not a counted request */
+ REQUEST_AT_LEAST_SIZE(xLbxTagDataReq);
+
+ return LbxTagData(client, stuff->tag, stuff->real_length,
+ (pointer)&stuff[1]); /* better not give any errors */
+}
+
+int
+ProcLbxInvalidateTag(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxInvalidateTagReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxInvalidateTagReq);
+ return LbxInvalidateTag(client, stuff->tag);
+}
+
+int
+ProcLbxPolyPoint(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyPoint, LbxDecodePoints);
+}
+
+int
+ProcLbxPolyLine(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyLine, LbxDecodePoints);
+}
+
+int
+ProcLbxPolySegment(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolySegment, LbxDecodeSegment);
+}
+
+int
+ProcLbxPolyRectangle(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyRectangle, LbxDecodeRectangle);
+}
+
+int
+ProcLbxPolyArc(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyArc, LbxDecodeArc);
+}
+
+int
+ProcLbxFillPoly(client)
+ register ClientPtr client;
+{
+ return LbxDecodeFillPoly(client);
+}
+
+int
+ProcLbxPolyFillRectangle(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyFillRectangle, LbxDecodeRectangle);
+}
+
+int
+ProcLbxPolyFillArc(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyFillArc, LbxDecodeArc);
+}
+
+int
+ProcLbxCopyArea (client)
+ register ClientPtr client;
+{
+ return LbxDecodeCopyArea(client);
+}
+
+int
+ProcLbxCopyPlane (client)
+ register ClientPtr client;
+{
+ return LbxDecodeCopyPlane(client);
+}
+
+
+int
+ProcLbxPolyText (client)
+ register ClientPtr client;
+{
+ return LbxDecodePolyText(client);
+}
+
+int
+ProcLbxImageText (client)
+ register ClientPtr client;
+{
+ return LbxDecodeImageText(client);
+}
+
+int
+ProcLbxQueryExtension(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxQueryExtensionReq);
+ char *ename;
+
+ REQUEST_AT_LEAST_SIZE(xLbxQueryExtensionReq);
+ ename = (char *) &stuff[1];
+ return LbxQueryExtension(client, ename, stuff->nbytes);
+}
+
+int
+ProcLbxPutImage(client)
+ register ClientPtr client;
+{
+ return LbxDecodePutImage(client);
+}
+
+int
+ProcLbxGetImage(client)
+ register ClientPtr client;
+{
+ return LbxDecodeGetImage(client);
+}
+
+
+int
+ProcLbxSync(client)
+ register ClientPtr client;
+{
+ xLbxSyncReply reply;
+
+ client->sequence--; /* not a counted request */
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Got LBX sync, seq = 0x%x\n", client->sequence);
+#endif
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.pad0 = reply.pad1 = reply.pad2 = reply.pad3 = reply.pad4 =
+ reply.pad5 = reply.pad6 = 0;
+
+ if (client->swapped)
+ {
+ register char n;
+ swaps (&reply.sequenceNumber, n);
+ }
+
+ WriteToClient (client, sz_xLbxSyncReply, (char *)&reply);
+
+ return (client->noClientException);
+}
+
+
+int
+ProcLbxDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_LbxQueryVersion:
+ return ProcLbxQueryVersion(client);
+ case X_LbxStartProxy:
+ return ProcLbxStartProxy(client);
+ case X_LbxStopProxy:
+ return ProcLbxStopProxy(client);
+ case X_LbxNewClient:
+ return ProcLbxNewClient(client);
+ case X_LbxCloseClient:
+ return ProcLbxCloseClient(client);
+ case X_LbxModifySequence:
+ return ProcLbxModifySequence(client);
+ case X_LbxAllowMotion:
+ return ProcLbxAllowMotion(client);
+ case X_LbxIncrementPixel:
+ return ProcLbxIncrementPixel(client);
+ case X_LbxGrabCmap:
+ return ProcLbxGrabCmap(client);
+ case X_LbxReleaseCmap:
+ return ProcLbxReleaseCmap(client);
+ case X_LbxAllocColor:
+ return ProcLbxAllocColor(client);
+ case X_LbxGetModifierMapping:
+ return ProcLbxGetModifierMapping(client);
+ case X_LbxGetKeyboardMapping:
+ return ProcLbxGetKeyboardMapping(client);
+ case X_LbxInvalidateTag:
+ return ProcLbxInvalidateTag(client);
+ case X_LbxPolyPoint:
+ return ProcLbxPolyPoint (client);
+ case X_LbxPolyLine:
+ return ProcLbxPolyLine (client);
+ case X_LbxPolySegment:
+ return ProcLbxPolySegment (client);
+ case X_LbxPolyRectangle:
+ return ProcLbxPolyRectangle (client);
+ case X_LbxPolyArc:
+ return ProcLbxPolyArc (client);
+ case X_LbxFillPoly:
+ return ProcLbxFillPoly (client);
+ case X_LbxPolyFillRectangle:
+ return ProcLbxPolyFillRectangle (client);
+ case X_LbxPolyFillArc:
+ return ProcLbxPolyFillArc (client);
+ case X_LbxQueryFont:
+ return ProcLbxQueryFont (client);
+ case X_LbxChangeProperty:
+ return ProcLbxChangeProperty (client);
+ case X_LbxGetProperty:
+ return ProcLbxGetProperty (client);
+ case X_LbxTagData:
+ return ProcLbxTagData (client);
+ case X_LbxCopyArea:
+ return ProcLbxCopyArea (client);
+ case X_LbxCopyPlane:
+ return ProcLbxCopyPlane (client);
+ case X_LbxPolyText8:
+ case X_LbxPolyText16:
+ return ProcLbxPolyText (client);
+ case X_LbxImageText8:
+ case X_LbxImageText16:
+ return ProcLbxImageText (client);
+ case X_LbxQueryExtension:
+ return ProcLbxQueryExtension (client);
+ case X_LbxPutImage:
+ return ProcLbxPutImage (client);
+ case X_LbxGetImage:
+ return ProcLbxGetImage (client);
+ case X_LbxInternAtoms:
+ return ProcLbxInternAtoms(client);
+ case X_LbxGetWinAttrAndGeom:
+ return ProcLbxGetWinAttrAndGeom(client);
+ case X_LbxSync:
+ return ProcLbxSync(client);
+ case X_LbxBeginLargeRequest:
+ return ProcLbxBeginLargeRequest(client);
+ case X_LbxLargeRequestData:
+ return ProcLbxLargeRequestData(client);
+ case X_LbxEndLargeRequest:
+ return ProcLbxLargeRequestData(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/lbx/lbxopts.c b/lbx/lbxopts.c
new file mode 100644
index 000000000..fe9af687e
--- /dev/null
+++ b/lbx/lbxopts.c
@@ -0,0 +1,817 @@
+/* $Xorg: lbxopts.c,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifdef OPTDEBUG
+#include <stdio.h>
+#endif
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "lbxserve.h"
+#include "lbxstr.h"
+#include "lbximage.h"
+#include "lbxopts.h"
+#include "lbxsrvopts.h"
+#ifndef NO_ZLIB
+#include "lbxzlib.h"
+#endif /* NO_ZLIB */
+
+static int LbxDeltaOpt();
+static int LbxProxyDeltaOpt();
+static int LbxServerDeltaOpt();
+static int LbxStreamCompOpt();
+static int LbxBitmapCompOpt();
+static int LbxPixmapCompOpt();
+static int LbxMessageCompOpt();
+static int LbxUseTagsOpt();
+static int LbxCmapAllOpt();
+
+/*
+ * List of LBX options we recognize and are willing to negotiate
+ */
+static struct _LbxOptionParser {
+ CARD8 optcode;
+ int (*parser)();
+} LbxOptions[] = {
+ { LBX_OPT_DELTA_PROXY, LbxProxyDeltaOpt },
+ { LBX_OPT_DELTA_SERVER, LbxServerDeltaOpt },
+ { LBX_OPT_STREAM_COMP, LbxStreamCompOpt },
+ { LBX_OPT_BITMAP_COMP, LbxBitmapCompOpt },
+ { LBX_OPT_PIXMAP_COMP, LbxPixmapCompOpt },
+ { LBX_OPT_MSG_COMP, LbxMessageCompOpt },
+ { LBX_OPT_USE_TAGS, LbxUseTagsOpt },
+ { LBX_OPT_CMAP_ALL, LbxCmapAllOpt }
+};
+
+#define LBX_N_OPTS (sizeof(LbxOptions) / sizeof(struct _LbxOptionParser))
+
+/*
+ * Set option defaults
+ */
+LbxOptionInit(pno)
+ LbxNegOptsPtr pno;
+{
+ bzero(pno, sizeof(LbxNegOptsRec));
+ pno->proxyDeltaN = pno->serverDeltaN = LBX_OPT_DELTA_NCACHE_DFLT;
+ pno->proxyDeltaMaxLen = pno->serverDeltaMaxLen = LBX_OPT_DELTA_MSGLEN_DFLT;
+ pno->squish = TRUE;
+ pno->numBitmapCompMethods = 0;
+ pno->bitmapCompMethods = NULL;
+ pno->numPixmapCompMethods = 0;
+ pno->pixmapCompMethods = NULL;
+ pno->pixmapCompDepths = NULL;
+ pno->useTags = TRUE;
+}
+
+int
+LbxOptionParse(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int i;
+ int nopts = *popt++;
+ unsigned char *pout = preply;
+
+ for (i = 0; i < nopts; i++) {
+ int j;
+ int len;
+ int hdrlen;
+ int replylen;
+
+ LBX_OPT_DECODE_LEN(popt + 1, len, hdrlen);
+ if (len < ++hdrlen || len > optlen) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad option length, len = %d, hdrlen = %d, optlen = %d\n", len, hdrlen, optlen);
+#endif
+ return -1;
+ }
+
+ for (j = 0; j < LBX_N_OPTS; j++) {
+ if (popt[0] == LbxOptions[j].optcode) {
+ replylen = (*LbxOptions[j].parser)(pno,
+ popt + hdrlen,
+ len - hdrlen,
+ pout + LBX_OPT_SMALLHDR_LEN);
+ if (replylen < 0)
+ return -1;
+ else if (replylen > 0) {
+ /*
+ * None of the current options require big headers,
+ * so this works for now.
+ */
+ *pout++ = i;
+ *pout++ = LBX_OPT_SMALLHDR_LEN + replylen;
+ pout += replylen;
+ pno->nopts++;
+ }
+ break;
+ }
+ }
+
+ optlen -= len;
+ popt += len;
+ }
+
+ return (pout - preply);
+}
+
+static int
+LbxProxyDeltaOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ return LbxDeltaOpt(popt, optlen, preply,
+ &pno->proxyDeltaN, &pno->proxyDeltaMaxLen);
+}
+
+static int
+LbxServerDeltaOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ return LbxDeltaOpt(popt, optlen, preply,
+ &pno->serverDeltaN, &pno->serverDeltaMaxLen);
+}
+
+static int
+LbxDeltaOpt(popt, optlen, preply, pn, pmaxlen)
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+ short *pn;
+ short *pmaxlen;
+{
+ short n;
+ short maxlen;
+
+ /*
+ * If there's more data than we expect, we just ignore it.
+ */
+ if (optlen < LBX_OPT_DELTA_REQLEN) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad delta option length = %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ /*
+ * Accept whatever value the proxy prefers, so skip the
+ * min/max offerings. Note that the max message len value is
+ * encoded as the number of 4-byte values.
+ */
+ popt += 2;
+ n = *popt++;
+ popt += 2;
+ maxlen = *popt++;
+ if ((maxlen <<= 2) == 0)
+ n = 0;
+ else if (maxlen < 32) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad delta max msg length %d\n", maxlen);
+#endif
+ return -1;
+ }
+
+ /*
+ * Put the response in the reply buffer
+ */
+ *preply++ = n;
+ *preply++ = maxlen >> 2;
+
+ *pn = n;
+ *pmaxlen = maxlen;
+
+ return LBX_OPT_DELTA_REPLYLEN;
+}
+
+static int ZlibParse();
+
+static struct _LbxStreamCompParser {
+ int typelen;
+ char *type;
+ int (*parser)();
+} LbxStreamComp[] = {
+#ifndef NO_ZLIB
+ { ZLIB_STRCOMP_OPT_LEN, ZLIB_STRCOMP_OPT, ZlibParse },
+#endif /* NO_ZLIB */
+};
+
+#define LBX_N_STRCOMP \
+ (sizeof(LbxStreamComp) / sizeof(struct _LbxStreamCompParser))
+
+static int
+LbxStreamCompOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int i;
+ int typelen;
+ int nopts = *popt++;
+
+ for (i = 0; i < nopts; i++) {
+ int j;
+ int len;
+ int lensize;
+ int replylen;
+
+ typelen = popt[0];
+ for (j = 0; j < LBX_N_STRCOMP; j++) {
+ if (typelen == LbxStreamComp[j].typelen &&
+ !strncmp((char *) popt + 1, LbxStreamComp[j].type, typelen))
+ break;
+ }
+
+ popt += 1 + typelen;
+ optlen -= 1 + typelen;
+ LBX_OPT_DECODE_LEN(popt, len, lensize);
+
+ if (j < LBX_N_STRCOMP) {
+ if (len > optlen)
+ return -1;
+ replylen = (*LbxStreamComp[j].parser)(pno,
+ popt + lensize,
+ len - lensize,
+ preply + 1);
+ if (replylen == -1)
+ return -1;
+ else if (replylen >= 0) {
+ *preply = i;
+ return replylen + 1;
+ }
+ }
+
+ optlen -= len;
+ popt += len;
+ }
+
+ return 0;
+}
+
+
+extern LbxStreamCompHandle ZlibInit();
+extern int ZlibStuffInput(), ZlibInputAvail(), ZlibFlush(),
+ ZlibRead(), ZlibWriteV();
+extern void ZlibCompressOn(), ZlibCompressOff(), ZlibFree();
+
+
+static int
+ZlibParse(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int level; /* compression level */
+
+ if (*popt++ != 1) /* length should be 1 */
+ return (-1);
+
+ level = *popt;
+ if (level < 1 || level > 9)
+ return (-1);
+
+ pno->streamOpts.streamCompInit = ZlibInit;
+ pno->streamOpts.streamCompArg = (pointer) level;
+ pno->streamOpts.streamCompStuffInput = ZlibStuffInput;
+ pno->streamOpts.streamCompInputAvail = ZlibInputAvail;
+ pno->streamOpts.streamCompFlush = ZlibFlush;
+ pno->streamOpts.streamCompRead = ZlibRead;
+ pno->streamOpts.streamCompWriteV = ZlibWriteV;
+ pno->streamOpts.streamCompOn = ZlibCompressOn;
+ pno->streamOpts.streamCompOff = ZlibCompressOff;
+ pno->streamOpts.streamCompFreeHandle = ZlibFree;
+
+ return (0);
+}
+
+static int
+LbxMessageCompOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+
+ if (optlen == 0) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad message-comp option length specified %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ pno->squish = *preply = *popt;
+ return 1;
+}
+
+
+static int
+LbxUseTagsOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+
+ if (optlen == 0) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad use-tags option length specified %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ pno->useTags = *preply = *popt;
+ return 1;
+}
+
+
+/*
+ * Option negotiation for image compression
+ */
+
+LbxBitmapCompMethod
+LbxBitmapCompMethods [] = {
+ {
+ "XC-FaxG42D", /* compression method name */
+ 0, /* inited */
+ 2, /* method opcode */
+ NULL, /* init function */
+ LbxImageEncodeFaxG42D, /* encode function */
+ LbxImageDecodeFaxG42D /* decode function */
+ }
+};
+
+#define NUM_BITMAP_METHODS \
+ (sizeof (LbxBitmapCompMethods) / sizeof (LbxBitmapCompMethod))
+
+
+#if 1
+/*
+ * Currently, we don't support any pixmap compression algorithms
+ * because regular stream compression does much better than PackBits.
+ * If we want to plug in a better pixmap image compression algorithm,
+ * it would go here.
+ */
+
+#define NUM_PIXMAP_METHODS 0
+LbxPixmapCompMethod LbxPixmapCompMethods [1]; /* dummy */
+
+#else
+
+LbxPixmapCompMethod
+LbxPixmapCompMethods [] = {
+ {
+ "XC-PackBits", /* compression method name */
+ 1 << ZPixmap, /* formats supported */
+ 1, {8}, /* depths supported */
+ 0, /* inited */
+ 1, /* method opcode */
+ NULL, /* init function */
+ LbxImageEncodePackBits, /* encode function */
+ LbxImageDecodePackBits /* decode function */
+ }
+};
+
+#define NUM_PIXMAP_METHODS \
+ (sizeof (LbxPixmapCompMethods) / sizeof (LbxPixmapCompMethod))
+#endif
+
+static int MergeDepths ();
+
+
+static int
+LbxImageCompOpt (pixmap, pno, popt, optlen, preply)
+
+Bool pixmap;
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ unsigned char *preplyStart = preply;
+ int numMethods = *popt++;
+ char *myIndices, *hisIndices;
+ unsigned *retFormats;
+ int **retDepths;
+ int replyCount = 0;
+ int status, i, j;
+
+ if (numMethods == 0)
+ {
+ if (pixmap)
+ pno->numPixmapCompMethods = 0;
+ else
+ pno->numBitmapCompMethods = 0;
+
+ *preply++ = 0;
+ return (1);
+ }
+
+ myIndices = (char *) xalloc (numMethods);
+ hisIndices = (char *) xalloc (numMethods);
+
+ if (!myIndices || !hisIndices)
+ {
+ if (myIndices)
+ xfree (myIndices);
+ if (hisIndices)
+ xfree (hisIndices);
+ return -1;
+ }
+
+ if (pixmap)
+ {
+ retFormats = (unsigned *) xalloc (numMethods);
+ retDepths = (int **) xalloc (numMethods * sizeof (int *));
+
+ if (!retFormats || !retDepths)
+ {
+ if (retFormats)
+ xfree (retFormats);
+ if (retDepths)
+ xfree (retDepths);
+ xfree (myIndices);
+ xfree (hisIndices);
+ return -1;
+ }
+ }
+
+ /*
+ * For each method in the list sent by the proxy, see if the server
+ * supports this method. If YES, update the following lists:
+ *
+ * myIndices[] is a list of indices into the server's
+ * LbxBit[Pix]mapCompMethods table.
+ *
+ * hisIndices[] is a list of indices into the list of
+ * method names sent by the proxy.
+ *
+ * retFormats[] indicates for each pixmap compression method,
+ * the pixmap formats supported.
+ *
+ * retDepths[] indicates for each pixmap compression method,
+ * the pixmap depths supported.
+ */
+
+ for (i = 0; i < numMethods; i++)
+ {
+ unsigned formatMask, newFormatMask;
+ int depthCount, *depths, len;
+ int freeDepths;
+ char *methodName;
+
+ freeDepths = 0;
+ len = *popt++;
+ methodName = (char *) popt;
+ popt += len;
+
+ if (pixmap)
+ {
+ formatMask = *popt++;
+ depthCount = *popt++;
+ depths = (int *) xalloc ((depthCount + 1) * sizeof (int));
+ freeDepths = 1;
+ depths[0] = depthCount;
+ for (j = 1; j <= depthCount; j++)
+ depths[j] = *popt++;
+ }
+
+ for (j = 0;
+ j < (pixmap ? NUM_PIXMAP_METHODS : NUM_BITMAP_METHODS); j++)
+ {
+
+ status = strncmp (methodName,
+ (pixmap ? LbxPixmapCompMethods[j].methodName :
+ LbxBitmapCompMethods[j].methodName),
+ len);
+
+ if (status == 0 && pixmap)
+ {
+ newFormatMask =
+ formatMask & LbxPixmapCompMethods[j].formatMask;
+
+ depthCount = MergeDepths (depths, &LbxPixmapCompMethods[j]);
+
+ if (newFormatMask == 0 || depthCount == 0)
+ status = 1;
+ }
+
+ if (status == 0)
+ {
+ myIndices[replyCount] = j;
+ hisIndices[replyCount] = i;
+
+ if (pixmap)
+ {
+ retFormats[replyCount] = newFormatMask;
+ retDepths[replyCount] = depths;
+ freeDepths = 0;
+ }
+
+ replyCount++;
+ break;
+ }
+ }
+
+ if (freeDepths)
+ xfree (depths);
+ }
+
+ *preply++ = replyCount;
+
+ /*
+ * Sort the lists by LBX server preference (increasing myIndices[] vals)
+ */
+
+ for (i = 0; i <= replyCount - 2; i++)
+ for (j = replyCount - 1; j >= i; j--)
+ if (myIndices[j - 1] > myIndices[j])
+ {
+ char temp1 = myIndices[j - 1];
+ char temp2 = hisIndices[j - 1];
+
+ myIndices[j - 1] = myIndices[j];
+ myIndices[j] = temp1;
+
+ hisIndices[j - 1] = hisIndices[j];
+ hisIndices[j] = temp2;
+
+ if (pixmap)
+ {
+ unsigned temp3 = retFormats[j - 1];
+ int *temp4 = retDepths[j - 1];
+
+ retFormats[j - 1] = retFormats[j];
+ retFormats[j] = temp3;
+
+ retDepths[j - 1] = retDepths[j];
+ retDepths[j] = temp4;
+ }
+ }
+
+ /*
+ * For each method supported, return to the proxy an index into
+ * the list sent by the proxy, the opcode to be used for the method,
+ * the pixmap formats supported, and the list of depths supported.
+ */
+
+ for (i = 0; i < replyCount; i++)
+ {
+ *preply++ = hisIndices[i];
+
+ if (pixmap)
+ {
+ int left;
+ *preply++ = LbxPixmapCompMethods[myIndices[i]].methodOpCode;
+ *preply++ = retFormats[i];
+ *preply++ = left = retDepths[i][0];
+ j = 1;
+ while (left > 0)
+ {
+ *preply++ = retDepths[i][j];
+ left--;
+ }
+ }
+ else
+ {
+ *preply++ = LbxBitmapCompMethods[myIndices[i]].methodOpCode;
+ }
+ }
+
+ if (pixmap)
+ {
+ pno->numPixmapCompMethods = replyCount;
+ pno->pixmapCompMethods = myIndices;
+ pno->pixmapCompDepths = retDepths;
+ }
+ else
+ {
+ pno->numBitmapCompMethods = replyCount;
+ pno->bitmapCompMethods = myIndices;
+ }
+
+ if (hisIndices)
+ xfree (hisIndices);
+
+ if (pixmap)
+ {
+ if (retFormats)
+ xfree (retFormats);
+ }
+
+ return (preply - preplyStart);
+}
+
+
+
+static int
+LbxBitmapCompOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ return (LbxImageCompOpt (0 /* bitmap */, pno, popt, optlen, preply));
+}
+
+
+static int
+LbxPixmapCompOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ return (LbxImageCompOpt (1 /* Pixmap */, pno, popt, optlen, preply));
+}
+
+
+LbxBitmapCompMethod *
+LbxSrvrLookupBitmapCompMethod (proxy, methodOpCode)
+
+LbxProxyPtr proxy;
+int methodOpCode;
+
+{
+ int i;
+
+ for (i = 0; i < proxy->numBitmapCompMethods; i++)
+ {
+ LbxBitmapCompMethod *method;
+
+ method = &LbxBitmapCompMethods[proxy->bitmapCompMethods[i]];
+
+ if (method->methodOpCode == methodOpCode)
+ return (method);
+ }
+
+ return (NULL);
+}
+
+
+LbxPixmapCompMethod *
+LbxSrvrLookupPixmapCompMethod (proxy, methodOpCode)
+
+LbxProxyPtr proxy;
+int methodOpCode;
+
+{
+ int i;
+
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ {
+ LbxPixmapCompMethod *method;
+
+ method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
+
+ if (method->methodOpCode == methodOpCode)
+ return (method);
+ }
+
+ return (NULL);
+}
+
+
+LbxBitmapCompMethod *
+LbxSrvrFindPreferredBitmapCompMethod (proxy)
+
+LbxProxyPtr proxy;
+
+{
+ if (proxy->numBitmapCompMethods == 0)
+ return NULL;
+ else
+ return (&LbxBitmapCompMethods[proxy->bitmapCompMethods[0]]);
+}
+
+
+
+LbxPixmapCompMethod *
+LbxSrvrFindPreferredPixmapCompMethod (proxy, format, depth)
+
+LbxProxyPtr proxy;
+int format;
+int depth;
+
+{
+ if (proxy->numPixmapCompMethods == 0)
+ return NULL;
+ else
+ {
+ LbxPixmapCompMethod *method;
+ int i, j;
+
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ {
+ method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
+
+ if ((method->formatMask & (1 << format)))
+ {
+ int n = proxy->pixmapCompDepths[i][0];
+ j = 1;
+ while (n > 0)
+ {
+ if (depth == proxy->pixmapCompDepths[i][j])
+ return method;
+ else
+ n--;
+ }
+ }
+ }
+
+ return NULL;
+ }
+}
+
+
+static int MergeDepths (depths, method)
+
+int *depths;
+LbxPixmapCompMethod *method;
+
+{
+ int i, j, count;
+ int temp[LBX_MAX_DEPTHS + 1];
+
+ temp[0] = count = 0;
+
+ for (i = 1; i <= depths[0]; i++)
+ {
+ for (j = 0; j < method->depthCount; j++)
+ if (method->depths[j] == depths[i])
+ {
+ temp[0]++;
+ temp[++count] = depths[i];
+ break;
+ }
+ }
+
+ memcpy (depths, temp, (count + 1) * sizeof (int));
+
+ return (count);
+}
+
+
+#define LbxCmapAllMethod "XC-CMAP"
+
+static int
+LbxCmapAllOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ int numMethods = *popt++;
+ int i;
+
+ for (i = 0; i < numMethods; i++)
+ {
+ int len;
+ char *methodName;
+
+ len = *popt++;
+ methodName = (char *) popt;
+ popt += len;
+ if (!strncmp(methodName, LbxCmapAllMethod, len))
+ break;
+ }
+ if (i >= numMethods)
+ i = 0; /* assume first one is proxy's favorite */
+ *preply = i;
+ return 1;
+}
diff --git a/lbx/lbxprop.c b/lbx/lbxprop.c
new file mode 100644
index 000000000..b70fade72
--- /dev/null
+++ b/lbx/lbxprop.c
@@ -0,0 +1,552 @@
+/* $Xorg: lbxprop.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1986, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "servermd.h"
+#include "propertyst.h"
+#include "windowstr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "Xfuncproto.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+extern int (*ProcVector[256]) ();
+extern void (*ReplySwapVector[256]) ();
+extern void CopySwap16Write(), CopySwap32Write(), Swap32Write();
+
+void
+LbxStallPropRequest(client, pProp)
+ ClientPtr client;
+ PropertyPtr pProp;
+{
+ xReq *req = (xReq *) client->requestBuffer;
+ register char n;
+
+ LbxQueryTagData(client, pProp->owner_pid,
+ pProp->tag_id, LbxTagTypeProperty);
+
+ /*
+ * Before we reset the request, we must make sure
+ * it is in the client's byte order.
+ */
+
+ if (client->swapped) {
+ if (req->reqType == X_ChangeProperty) {
+ xChangePropertyReq *stuff = (xChangePropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch ( stuff->format ) {
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ } else if (req->reqType == X_GetProperty) {
+ xGetPropertyReq *stuff = (xGetPropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ } else if (req->data == X_LbxChangeProperty) {
+ xLbxChangePropertyReq *stuff = (xLbxChangePropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ } else if (req->data == X_LbxGetProperty) {
+ xLbxGetPropertyReq *stuff = (xLbxGetPropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ }
+ }
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+}
+
+int
+LbxChangeWindowProperty(client, pWin, property, type, format, mode, len,
+ have_data, value, sendevent, tag)
+ ClientPtr client;
+ WindowPtr pWin;
+ Atom property,
+ type;
+ int format,
+ mode;
+ unsigned long len;
+ Bool have_data;
+ pointer value;
+ Bool sendevent;
+ XID *tag;
+{
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format >> 3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps(pWin);
+ while (pProp) {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) { /* just add to list */
+ if (!pWin->optional && !MakeWindowOptional(pWin))
+ return (BadAlloc);
+ pProp = (PropertyPtr) xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return (BadAlloc);
+ data = (pointer) xalloc(totalSize);
+ if (!data && len) {
+ xfree(pProp);
+ return (BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (have_data) {
+ if (len)
+ memmove((char *) data, (char *) value, totalSize);
+ pProp->tag_id = 0;
+ pProp->owner_pid = 0;
+ } else {
+ if (!TagSaveTag(LbxTagTypeProperty, totalSize,
+ (pointer)pProp, &pProp->tag_id)) {
+ xfree(pProp);
+ xfree(pProp->data);
+ return BadAlloc;
+ }
+ pProp->owner_pid = LbxProxyID(client);
+ TagMarkProxy(pProp->tag_id, pProp->owner_pid);
+ }
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ } else {
+ /*
+ * To append or prepend to a property the request format and type must
+ * match those of the already defined property. The existing format
+ * and type are irrelevant when using the mode "PropModeReplace" since
+ * they will be written over.
+ */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return (BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return (BadMatch);
+
+ /*
+ * if its a modify instead of replace, make sure we have the current
+ * value
+ */
+ if ((mode != PropModeReplace) && pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return (client->noClientException);
+ }
+ /* make sure any old tag is flushed first */
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+ if (mode == PropModeReplace) {
+ if (totalSize != pProp->size * (pProp->format >> 3)) {
+ data = (pointer) xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return (BadAlloc);
+ pProp->data = data;
+ }
+ if (have_data) {
+ if (len)
+ memmove((char *) pProp->data, (char *) value, totalSize);
+ } else {
+ if (!TagSaveTag(LbxTagTypeProperty, totalSize,
+ (pointer)pProp, &pProp->tag_id)) {
+ xfree(pProp);
+ xfree(pProp->data);
+ return BadAlloc;
+ }
+ pProp->owner_pid = LbxProxyID(client);
+ TagMarkProxy(pProp->tag_id, pProp->owner_pid);
+ }
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ } else if (len == 0) {
+ /* do nothing */
+ } else if (mode == PropModeAppend) {
+ data = (pointer) xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return (BadAlloc);
+ pProp->data = data;
+ memmove(&((char *) data)[pProp->size * sizeInBytes],
+ (char *) value,
+ totalSize);
+ pProp->size += len;
+ } else if (mode == PropModePrepend) {
+ data = (pointer) xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return (BadAlloc);
+ memmove(&((char *) data)[totalSize], (char *) pProp->data,
+ (int) (pProp->size * sizeInBytes));
+ memmove((char *) data, (char *) value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent) {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
+ }
+ if (pProp->tag_id)
+ *tag = pProp->tag_id;
+ return (Success);
+}
+
+int
+LbxChangeProperty(client)
+ ClientPtr client;
+{
+ WindowPtr pWin;
+ char format,
+ mode;
+ unsigned long len;
+ int err;
+ int n;
+ XID newtag;
+ xLbxChangePropertyReply rep;
+ REQUEST(xLbxChangePropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend)) {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32)) {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return (BadWindow);
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+ if (!ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return (BadAtom);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.pad = rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ rep.tag = 0;
+ WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
+ return client->noClientException;
+ }
+#endif
+
+ err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ (int) format, (int) mode, len, FALSE, (pointer) &stuff[1],
+ TRUE, &newtag);
+ if (err)
+ return err;
+
+ rep.tag = newtag;
+
+ if (client->swapped) {
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
+
+ return client->noClientException;
+}
+
+static void
+LbxWriteGetpropReply(client, rep)
+ ClientPtr client;
+ xLbxGetPropertyReply *rep;
+{
+ int n;
+
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->propertyType, n);
+ swapl(&rep->bytesAfter, n);
+ swapl(&rep->nItems, n);
+ swapl(&rep->tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetPropertyReply), (char *)rep);
+}
+
+int
+LbxGetProperty(client)
+ ClientPtr client;
+{
+ PropertyPtr pProp,
+ prevProp;
+ unsigned long n,
+ len,
+ ind;
+ WindowPtr pWin;
+ xLbxGetPropertyReply reply;
+ Bool send_data = FALSE;
+
+ REQUEST(xLbxGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
+
+ reply.pad1 = 0;
+ reply.pad2 = 0;
+
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return (BadWindow);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
+ client->errorValue = stuff->delete;
+ return (BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+ pProp = wUserProps(pWin);
+ prevProp = (PropertyPtr) NULL;
+ while (pProp) {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp) {
+ reply.nItems = 0;
+ reply.length = 0;
+ reply.bytesAfter = 0;
+ reply.propertyType = None;
+ reply.format = 0;
+ reply.tag = 0;
+ LbxWriteGetpropReply(client, &reply);
+ return client->noClientException;
+ }
+ /*
+ * If the request type and actual type don't match. Return the
+ * property information, but not the data.
+ */
+ if ((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType)) {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ reply.tag = 0;
+ LbxWriteGetpropReply(client, &reply);
+ return client->noClientException;
+ }
+ /*
+ * Return type, format, value to client
+ */
+ n = (pProp->format >> 3) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /*
+ * If longOffset is invalid such that it causes "len" to be
+ * negative, it's a value error.
+ */
+
+ if (n < ind) {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ /* make sure we have the current value */
+ if (pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return client->noClientException;
+ }
+
+ len = min(n - ind, stuff->longLength << 2);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.propertyType = pProp->type;
+
+ if (!pProp->tag_id) {
+ if (n && (!stuff->delete || reply.bytesAfter)) {
+ TagSaveTag(LbxTagTypeProperty, n, (pointer)pProp, &pProp->tag_id);
+ pProp->owner_pid = 0;
+ }
+ send_data = TRUE;
+ } else
+ send_data = !TagProxyMarked(pProp->tag_id, LbxProxyID(client));
+ if (pProp->tag_id && send_data)
+ TagMarkProxy(pProp->tag_id, LbxProxyID(client));
+ reply.tag = pProp->tag_id;
+
+ if (!send_data)
+ len = 0;
+ else if (reply.tag) {
+ len = n;
+ ind = 0;
+ }
+ reply.nItems = len / (pProp->format >> 3);
+ reply.length = (len + 3) >> 2;
+
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
+ }
+ LbxWriteGetpropReply(client, &reply);
+ if (len) {
+ switch (reply.format) {
+ case 32:
+ client->pSwapReplyFunc = CopySwap32Write;
+ break;
+ case 16:
+ client->pSwapReplyFunc = CopySwap16Write;
+ break;
+ default:
+ client->pSwapReplyFunc = (void (*) ()) WriteToClient;
+ break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *) pProp->data + ind);
+ }
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+ if (prevProp == (PropertyPtr) NULL) {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed(pWin);
+ } else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return client->noClientException;
+}
diff --git a/lbx/lbxserve.h b/lbx/lbxserve.h
new file mode 100644
index 000000000..3151207be
--- /dev/null
+++ b/lbx/lbxserve.h
@@ -0,0 +1,173 @@
+/* $Xorg: lbxserve.h,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBXSERVE_H_
+#define _LBXSERVE_H_
+#include "lbxdeltastr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxopts.h"
+
+#define MAX_LBX_CLIENTS MAXCLIENTS
+#define MAX_NUM_PROXIES (MAXCLIENTS >> 1)
+
+typedef struct _LbxClient *LbxClientPtr;
+typedef struct _LbxProxy *LbxProxyPtr;
+
+typedef struct _LbxClient {
+ CARD32 id;
+ ClientPtr client;
+ LbxProxyPtr proxy;
+ Bool ignored;
+ Bool input_blocked;
+ int reqs_pending;
+ long bytes_in_reply;
+ long bytes_remaining;
+ Drawable drawableCache[GFX_CACHE_SIZE];
+ GContext gcontextCache[GFX_CACHE_SIZE];
+ pointer gfx_buffer; /* tmp buffer for unpacking gfx requests */
+ unsigned long gb_size;
+} LbxClientRec;
+
+typedef struct _connectionOutput *OSBufPtr;
+
+typedef struct _LbxProxy {
+ LbxProxyPtr next;
+ /* this array is indexed by lbx proxy index */
+ LbxClientPtr lbxClients[MAX_LBX_CLIENTS];
+ LbxClientPtr curRecv,
+ curDix;
+ int fd;
+ int pid; /* proxy ID */
+ int uid;
+ int numClients;
+ int maxIndex;
+ Bool aborted;
+ int grabClient;
+ pointer compHandle;
+ Bool dosquishing;
+ Bool useTags;
+ LBXDeltasRec indeltas;
+ LBXDeltasRec outdeltas;
+ char *iDeltaBuf;
+ char *replyBuf;
+ char *oDeltaBuf;
+ OSBufPtr ofirst;
+ OSBufPtr olast;
+ CARD32 cur_send_id;
+
+ LbxStreamOpts streamOpts;
+
+ int numBitmapCompMethods;
+ char *bitmapCompMethods; /* array of indices */
+ int numPixmapCompMethods;
+ char *pixmapCompMethods; /* array of indices */
+ int **pixmapCompDepths; /* depths supported from each method */
+
+ struct _ColormapRec *grabbedCmaps; /* chained via lbx private */
+ int motion_allowed_events;
+ lbxMotionCache motionCache;
+} LbxProxyRec;
+
+/* This array is indexed by server client index, not lbx proxy index */
+
+extern LbxClientPtr lbxClients[MAXCLIENTS];
+
+#define LbxClient(client) (lbxClients[(client)->index])
+#define LbxProxy(client) (LbxClient(client)->proxy)
+#define LbxMaybeProxy(client) (LbxClient(client) ? LbxProxy(client) : 0)
+#define LbxProxyID(client) (LbxProxy(client)->pid)
+#define LbxProxyClient(proxy) ((proxy)->lbxClients[0]->client)
+
+extern int LbxEventCode;
+
+extern void LbxDixInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern LbxProxyPtr LbxPidToProxy(
+#if NeedFunctionPrototypes
+ int /* pid */
+#endif
+);
+
+extern void LbxReencodeOutput(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ char* /*pbuf*/,
+ int* /*pcount*/,
+ char* /*cbuf*/,
+ int* /*ccount*/
+#endif
+);
+
+extern int UncompressedWriteToClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*who*/,
+ int /*count*/,
+ char* /*buf*/
+#endif
+);
+
+extern ClientPtr AllocLbxClientConnection(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+extern void LbxProxyConnection(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+#endif /* _LBXSERVE_H_ */
diff --git a/lbx/lbxsquish.c b/lbx/lbxsquish.c
new file mode 100644
index 000000000..6d3eddbfc
--- /dev/null
+++ b/lbx/lbxsquish.c
@@ -0,0 +1,152 @@
+/* $Xorg: lbxsquish.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "lbxserve.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+
+/* handles server-side protocol squishing */
+
+static char lbxevdelta[] = {
+ 0,
+ 0,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_EnterLeaveEvent,
+ sz_xEvent - lbxsz_EnterLeaveEvent,
+ sz_xEvent - lbxsz_FocusEvent,
+ sz_xEvent - lbxsz_FocusEvent,
+ sz_xEvent - lbxsz_KeymapEvent,
+ sz_xEvent - lbxsz_ExposeEvent,
+ sz_xEvent - lbxsz_GfxExposeEvent,
+ sz_xEvent - lbxsz_NoExposeEvent,
+ sz_xEvent - lbxsz_VisibilityEvent,
+ sz_xEvent - lbxsz_CreateNotifyEvent,
+ sz_xEvent - lbxsz_DestroyNotifyEvent,
+ sz_xEvent - lbxsz_UnmapNotifyEvent,
+ sz_xEvent - lbxsz_MapNotifyEvent,
+ sz_xEvent - lbxsz_MapRequestEvent,
+ sz_xEvent - lbxsz_ReparentEvent,
+ sz_xEvent - lbxsz_ConfigureNotifyEvent,
+ sz_xEvent - lbxsz_ConfigureRequestEvent,
+ sz_xEvent - lbxsz_GravityEvent,
+ sz_xEvent - lbxsz_ResizeRequestEvent,
+ sz_xEvent - lbxsz_CirculateEvent,
+ sz_xEvent - lbxsz_CirculateEvent,
+ sz_xEvent - lbxsz_PropertyEvent,
+ sz_xEvent - lbxsz_SelectionClearEvent,
+ sz_xEvent - lbxsz_SelectionRequestEvent,
+ sz_xEvent - lbxsz_SelectionNotifyEvent,
+ sz_xEvent - lbxsz_ColormapEvent,
+ sz_xEvent - lbxsz_ClientMessageEvent,
+ sz_xEvent - lbxsz_MappingNotifyEvent
+};
+
+static char lbxevpad[] = {
+ 0,
+ 0,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_EnterLeaveEvent - lbxupsz_EnterLeaveEvent,
+ lbxsz_EnterLeaveEvent - lbxupsz_EnterLeaveEvent,
+ lbxsz_FocusEvent - lbxupsz_FocusEvent,
+ lbxsz_FocusEvent - lbxupsz_FocusEvent,
+ lbxsz_KeymapEvent - lbxupsz_KeymapEvent,
+ lbxsz_ExposeEvent - lbxupsz_ExposeEvent,
+ lbxsz_GfxExposeEvent - lbxupsz_GfxExposeEvent,
+ lbxsz_NoExposeEvent - lbxupsz_NoExposeEvent,
+ lbxsz_VisibilityEvent - lbxupsz_VisibilityEvent,
+ lbxsz_CreateNotifyEvent - lbxupsz_CreateNotifyEvent,
+ lbxsz_DestroyNotifyEvent - lbxupsz_DestroyNotifyEvent,
+ lbxsz_UnmapNotifyEvent - lbxupsz_UnmapNotifyEvent,
+ lbxsz_MapNotifyEvent - lbxupsz_MapNotifyEvent,
+ lbxsz_MapRequestEvent - lbxupsz_MapRequestEvent,
+ lbxsz_ReparentEvent - lbxupsz_ReparentEvent,
+ lbxsz_ConfigureNotifyEvent - lbxupsz_ConfigureNotifyEvent,
+ lbxsz_ConfigureRequestEvent - lbxupsz_ConfigureRequestEvent,
+ lbxsz_GravityEvent - lbxupsz_GravityEvent,
+ lbxsz_ResizeRequestEvent - lbxupsz_ResizeRequestEvent,
+ lbxsz_CirculateEvent - lbxupsz_CirculateEvent,
+ lbxsz_CirculateEvent - lbxupsz_CirculateEvent,
+ lbxsz_PropertyEvent - lbxupsz_PropertyEvent,
+ lbxsz_SelectionClearEvent - lbxupsz_SelectionClearEvent,
+ lbxsz_SelectionRequestEvent - lbxupsz_SelectionRequestEvent,
+ lbxsz_SelectionNotifyEvent - lbxupsz_SelectionNotifyEvent,
+ lbxsz_ColormapEvent - lbxupsz_ColormapEvent,
+ lbxsz_ClientMessageEvent - lbxupsz_ClientMessageEvent,
+ lbxsz_MappingNotifyEvent - lbxupsz_MappingNotifyEvent
+};
+
+int
+LbxSquishEvent(buf)
+ char *buf;
+{
+ int delta = lbxevdelta[((xEvent *)buf)->u.u.type];
+ int pad = lbxevpad[((xEvent *)buf)->u.u.type];
+
+ if (delta)
+ memmove(buf + delta, buf, sz_xEvent - delta);
+ if (pad) {
+ buf += sz_xEvent;
+ while (--pad >= 0)
+ *--buf = 0;
+ }
+ return delta;
+}
diff --git a/lbx/lbxsrvopts.h b/lbx/lbxsrvopts.h
new file mode 100644
index 000000000..a08f1fec8
--- /dev/null
+++ b/lbx/lbxsrvopts.h
@@ -0,0 +1,78 @@
+/* $Xorg: lbxsrvopts.h,v 1.3 2000/08/17 19:53:31 cpqbld Exp $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBX_SRVOPTS_H_
+#define _LBX_SRVOPTS_H_
+
+#include "lbxopts.h"
+
+typedef struct _LbxNegOpts {
+ int nopts;
+ short proxyDeltaN;
+ short proxyDeltaMaxLen;
+ short serverDeltaN;
+ short serverDeltaMaxLen;
+ LbxStreamOpts streamOpts;
+ int numBitmapCompMethods;
+ char *bitmapCompMethods; /* array of indices */
+ int numPixmapCompMethods;
+ char *pixmapCompMethods; /* array of indices */
+ int **pixmapCompDepths; /* depths supported from each method */
+ Bool squish;
+ Bool useTags;
+} LbxNegOptsRec;
+
+typedef LbxNegOptsRec *LbxNegOptsPtr;
+
+
+extern LbxBitmapCompMethod *LbxSrvrLookupBitmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int /* methodOpCode */
+#endif
+);
+
+extern LbxPixmapCompMethod *LbxSrvrLookupPixmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int /* methodOpCode */
+#endif
+);
+
+extern LbxBitmapCompMethod *LbxSrvrFindPreferredBitmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+extern LbxPixmapCompMethod *LbxSrvrFindPreferredPixmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int, /* format */
+ int /* depth */
+#endif
+);
+
+
+#endif /* _LBX_SRVOPTS_H_ */
diff --git a/lbx/lbxswap.c b/lbx/lbxswap.c
new file mode 100644
index 000000000..38ba66b70
--- /dev/null
+++ b/lbx/lbxswap.c
@@ -0,0 +1,858 @@
+/* $Xorg: lbxswap.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "Xfuncproto.h"
+
+#include <stdio.h>
+
+static int
+SProcLbxQueryVersion(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxQueryVersion(client);
+}
+
+static int
+SProcLbxStartProxy(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxStartProxyReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxStartProxy(client);
+}
+
+static int
+SProcLbxStopProxy(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxStopProxyReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxStopProxy(client);
+}
+
+int
+SProcLbxSwitch(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxSwitchReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxSwitch(client);
+}
+
+int
+SProcLbxBeginLargeRequest (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxBeginLargeRequestReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->largeReqLength, n);
+ return ProcLbxBeginLargeRequest(client);
+}
+
+int
+SProcLbxLargeRequestData (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxLargeRequestDataReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxLargeRequestData(client);
+}
+
+int
+SProcLbxEndLargeRequest (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxEndLargeRequestReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxEndLargeRequest(client);
+}
+
+static int
+SProcLbxNewClient(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxNewClientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxNewClient(client);
+}
+
+static int
+SProcLbxCloseClient(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCloseClientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxCloseClient(client);
+}
+
+static int
+SProcLbxModifySequence(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxModifySequenceReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->adjust, n);
+ return ProcLbxModifySequence(client);
+}
+
+static int
+SProcLbxAllowMotion(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxAllowMotionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->num, n);
+ return ProcLbxAllowMotion(client);
+}
+
+static int
+SProcLbxIncrementPixel(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxIncrementPixelReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->pixel, n);
+ return ProcLbxIncrementPixel(client);
+}
+
+static int
+SProcLbxGrabCmap(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGrabCmapReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+
+ return ProcLbxGrabCmap(client);
+}
+
+static int
+SProcLbxReleaseCmap(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxReleaseCmapReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+
+ return ProcLbxReleaseCmap(client);
+}
+
+static int
+SProcLbxAllocColor(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxAllocColorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->pixel, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+
+ return ProcLbxAllocColor(client);
+}
+
+static int
+SProcLbxGetModifierMapping(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetModifierMappingReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxGetModifierMapping(client);
+}
+
+static int
+SProcLbxGetKeyboardMapping(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetKeyboardMappingReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxGetKeyboardMapping(client);
+}
+
+static int
+SProcLbxQueryFont(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxQueryFontReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->fid, n);
+ return ProcLbxQueryFont(client);
+}
+
+static int
+SProcLbxChangeProperty(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxChangePropertyReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xLbxChangePropertyReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch (stuff->format) {
+ case 8:
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return ProcLbxChangeProperty(client);
+}
+
+static int
+SProcLbxGetProperty(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetPropertyReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ return ProcLbxGetProperty(client);
+}
+
+static int
+SProcLbxTagData(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxTagDataReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->tag, n);
+ swapl(&stuff->real_length, n);
+ return ProcLbxTagData(client);
+}
+
+static int
+SProcLbxInvalidateTag(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxInvalidateTagReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->tag, n);
+ return ProcLbxInvalidateTag(client);
+}
+
+static int
+SProcLbxPoly(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPolyPointReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxPolyPointReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+static int
+SProcLbxFillPoly(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxFillPolyReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxFillPolyReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxFillPoly(client);
+}
+
+static int
+SProcLbxCopyArea (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCopyAreaReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxCopyAreaReq);
+ if (GFXdCacheEnt (stuff->srcCache) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxCopyArea(client);
+}
+
+static int
+SProcLbxCopyPlane (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCopyPlaneReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->bitPlane, n);
+ after = ((char *) stuff) + SIZEOF(xLbxCopyPlaneReq);
+ if (GFXdCacheEnt (stuff->srcCache) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxCopyPlane(client);
+}
+
+static int
+SProcLbxPolyText(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPolyTextReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxPolyTextReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+static int
+SProcLbxImageText(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxImageTextReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxImageTextReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+
+static int
+SProcLbxPutImage(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPutImageReq);
+
+ swaps (&stuff->length, n);
+ return ProcLbxPutImage(client);
+}
+
+static int
+SProcLbxGetImage(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetImageReq);
+
+ swaps (&stuff->length, n);
+ swapl (&stuff->drawable, n);
+ swaps (&stuff->x, n);
+ swaps (&stuff->y, n);
+ swaps (&stuff->width, n);
+ swaps (&stuff->height, n);
+ swapl (&stuff->planeMask, n);
+ return ProcLbxGetImage(client);
+}
+
+static int
+SProcLbxInternAtoms(client)
+ register ClientPtr client;
+{
+ register int n;
+ char *ptr;
+ char lenbuf[2];
+ CARD16 len;
+ int i;
+
+ REQUEST(xLbxInternAtomsReq);
+
+ swaps (&stuff->length, n);
+ swaps (&stuff->num, n);
+
+ ptr = (char *) stuff + sz_xLbxInternAtomsReq;
+ for (i = 0; i < stuff->num; i++)
+ {
+ swaps (ptr, n);
+ lenbuf[0] = ptr[0];
+ lenbuf[1] = ptr[1];
+ len = *((CARD16 *) lenbuf);
+ ptr += (len + 2);
+ }
+
+ return ProcLbxInternAtoms(client);
+}
+
+
+static int
+SProcLbxGetWinAttrAndGeom(client)
+ ClientPtr client;
+{
+ int n;
+
+ REQUEST(xLbxGetWinAttrAndGeomReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->id, n);
+
+ return ProcLbxGetWinAttrAndGeom(client);
+}
+
+
+
+static int
+SProcLbxQueryExtension(client)
+ ClientPtr client;
+{
+ int n;
+
+ REQUEST(xLbxQueryExtensionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->nbytes, n);
+ return ProcLbxQueryExtension(client);
+}
+
+int
+SProcLbxDispatch(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_LbxQueryVersion:
+ return SProcLbxQueryVersion(client);
+ case X_LbxStartProxy:
+ return SProcLbxStartProxy(client);
+ case X_LbxStopProxy:
+ return SProcLbxStopProxy(client);
+ case X_LbxNewClient:
+ return SProcLbxNewClient(client);
+ case X_LbxCloseClient:
+ return SProcLbxCloseClient(client);
+ case X_LbxModifySequence:
+ return SProcLbxModifySequence(client);
+ case X_LbxAllowMotion:
+ return SProcLbxAllowMotion(client);
+ case X_LbxIncrementPixel:
+ return SProcLbxIncrementPixel(client);
+ case X_LbxGrabCmap:
+ return SProcLbxGrabCmap(client);
+ case X_LbxReleaseCmap:
+ return SProcLbxReleaseCmap(client);
+ case X_LbxAllocColor:
+ return SProcLbxAllocColor(client);
+ case X_LbxGetModifierMapping:
+ return SProcLbxGetModifierMapping(client);
+ case X_LbxGetKeyboardMapping:
+ return SProcLbxGetKeyboardMapping(client);
+ case X_LbxInvalidateTag:
+ return SProcLbxInvalidateTag(client);
+ case X_LbxPolyPoint:
+ case X_LbxPolyLine:
+ case X_LbxPolySegment:
+ case X_LbxPolyRectangle:
+ case X_LbxPolyArc:
+ case X_LbxPolyFillRectangle:
+ case X_LbxPolyFillArc:
+ return SProcLbxPoly(client);
+ case X_LbxFillPoly:
+ return SProcLbxFillPoly(client);
+ case X_LbxQueryFont:
+ return SProcLbxQueryFont(client);
+ case X_LbxChangeProperty:
+ return SProcLbxChangeProperty(client);
+ case X_LbxGetProperty:
+ return SProcLbxGetProperty(client);
+ case X_LbxTagData:
+ return SProcLbxTagData(client);
+ case X_LbxCopyArea:
+ return SProcLbxCopyArea(client);
+ case X_LbxCopyPlane:
+ return SProcLbxCopyPlane(client);
+ case X_LbxPolyText8:
+ case X_LbxPolyText16:
+ return SProcLbxPolyText(client);
+ case X_LbxImageText8:
+ case X_LbxImageText16:
+ return SProcLbxImageText (client);
+ case X_LbxQueryExtension:
+ return SProcLbxQueryExtension(client);
+ case X_LbxPutImage:
+ return SProcLbxPutImage(client);
+ case X_LbxGetImage:
+ return SProcLbxGetImage(client);
+ case X_LbxInternAtoms:
+ return SProcLbxInternAtoms(client);
+ case X_LbxGetWinAttrAndGeom:
+ return SProcLbxGetWinAttrAndGeom(client);
+ case X_LbxSync:
+ return ProcLbxSync(client); /* nothing to swap */
+ case X_LbxBeginLargeRequest:
+ return SProcLbxBeginLargeRequest(client);
+ case X_LbxLargeRequestData:
+ return SProcLbxLargeRequestData(client);
+ default:
+ return BadRequest;
+ }
+}
+
+#ifdef notyet
+void
+LbxWriteSConnectionInfo(pClient, size, pInfo)
+ ClientPtr pClient;
+ unsigned long size;
+ char *pInfo;
+{
+ int i, j, k;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ char *pInfoT, *pInfoTBase;
+ xConnSetup *pConnSetup = (xConnSetup *)pInfo;
+
+ pInfoT = pInfoTBase = (char *) ALLOCATE_LOCAL(size);
+ if (!pInfoTBase)
+ {
+ pClient->noClientException = -1;
+ return;
+ }
+ SwapConnSetup(pConnSetup, (xConnSetup *)pInfoT);
+ pInfo += sizeof(xConnSetup);
+ pInfoT += sizeof(xConnSetup);
+
+ /* Copy the vendor string */
+ i = (pConnSetup->nbytesVendor + 3) & ~3;
+ memmove(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ /* The Pixmap formats don't need to be swapped, just copied. */
+ i = sizeof(xPixmapFormat) * screenInfo.numPixmapFormats;
+ memmove(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ for(i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ SwapWinRoot((xWindowRoot *)pInfo, (xWindowRoot *)pInfoT);
+ pInfo += sizeof(xWindowRoot);
+ pInfoT += sizeof(xWindowRoot);
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ ((xDepth *)pInfoT)->depth = ((xDepth *)pInfo)->depth;
+ cpswaps(((xDepth *)pInfo)->nVisuals, ((xDepth *)pInfoT)->nVisuals);
+ pInfo += sizeof(xDepth);
+ pInfoT += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ SwapVisual((xVisualType *)pInfo, (xVisualType *)pInfoT);
+ pInfo += sizeof(xVisualType);
+ pInfoT += sizeof(xVisualType);
+ }
+ }
+ }
+ (void)WriteToClient(pClient, (int)size, (char *) pInfoTBase);
+ DEALLOCATE_LOCAL(pInfoTBase);
+}
+
+void
+SwapConnSetup(pConnSetup, pConnSetupT)
+ xConnSetup *pConnSetup, *pConnSetupT;
+{
+ cpswapl(pConnSetup->release, pConnSetupT->release);
+ cpswapl(pConnSetup->ridBase, pConnSetupT->ridBase);
+ cpswapl(pConnSetup->ridMask, pConnSetupT->ridMask);
+ cpswapl(pConnSetup->motionBufferSize, pConnSetupT->motionBufferSize);
+ cpswaps(pConnSetup->nbytesVendor, pConnSetupT->nbytesVendor);
+ cpswaps(pConnSetup->maxRequestSize, pConnSetupT->maxRequestSize);
+ pConnSetupT->minKeyCode = pConnSetup->minKeyCode;
+ pConnSetupT->maxKeyCode = pConnSetup->maxKeyCode;
+ pConnSetupT->numRoots = pConnSetup->numRoots;
+ pConnSetupT->numFormats = pConnSetup->numFormats;
+ pConnSetupT->imageByteOrder = pConnSetup->imageByteOrder;
+ pConnSetupT->bitmapBitOrder = pConnSetup->bitmapBitOrder;
+ pConnSetupT->bitmapScanlineUnit = pConnSetup->bitmapScanlineUnit;
+ pConnSetupT->bitmapScanlinePad = pConnSetup->bitmapScanlinePad;
+}
+
+void
+SwapWinRoot(pRoot, pRootT)
+ xWindowRoot *pRoot, *pRootT;
+{
+ cpswapl(pRoot->windowId, pRootT->windowId);
+ cpswapl(pRoot->defaultColormap, pRootT->defaultColormap);
+ cpswapl(pRoot->whitePixel, pRootT->whitePixel);
+ cpswapl(pRoot->blackPixel, pRootT->blackPixel);
+ cpswapl(pRoot->currentInputMask, pRootT->currentInputMask);
+ cpswaps(pRoot->pixWidth, pRootT->pixWidth);
+ cpswaps(pRoot->pixHeight, pRootT->pixHeight);
+ cpswaps(pRoot->mmWidth, pRootT->mmWidth);
+ cpswaps(pRoot->mmHeight, pRootT->mmHeight);
+ cpswaps(pRoot->minInstalledMaps, pRootT->minInstalledMaps);
+ cpswaps(pRoot->maxInstalledMaps, pRootT->maxInstalledMaps);
+ cpswapl(pRoot->rootVisualID, pRootT->rootVisualID);
+ pRootT->backingStore = pRoot->backingStore;
+ pRootT->saveUnders = pRoot->saveUnders;
+ pRootT->rootDepth = pRoot->rootDepth;
+ pRootT->nDepths = pRoot->nDepths;
+}
+
+void
+SwapVisual(pVis, pVisT)
+ xVisualType *pVis, *pVisT;
+{
+ cpswapl(pVis->visualID, pVisT->visualID);
+ pVisT->class = pVis->class;
+ pVisT->bitsPerRGB = pVis->bitsPerRGB;
+ cpswaps(pVis->colormapEntries, pVisT->colormapEntries);
+ cpswapl(pVis->redMask, pVisT->redMask);
+ cpswapl(pVis->greenMask, pVisT->greenMask);
+ cpswapl(pVis->blueMask, pVisT->blueMask);
+}
+#endif
+
+void
+LbxWriteSConnSetupPrefix(pClient, pcsp)
+ ClientPtr pClient;
+ xLbxConnSetupPrefix *pcsp;
+{
+ xLbxConnSetupPrefix cspT;
+
+ cspT.success = pcsp->success;
+ cspT.changeType = pcsp->changeType;
+ cspT.length = pcsp->length;
+ cpswaps(pcsp->majorVersion, cspT.majorVersion);
+ cpswaps(pcsp->minorVersion, cspT.minorVersion);
+ cpswapl(pcsp->tag, cspT.tag);
+
+ (void)WriteToClient(pClient, sizeof(cspT), (char *) &cspT);
+}
+
+void
+LbxSwapFontInfo(pr, compressed)
+ xLbxFontInfo *pr;
+ Bool compressed;
+{
+ unsigned i;
+ xCharInfo *pxci;
+ unsigned nchars,
+ nprops;
+ char *pby;
+ register char n;
+
+ nchars = pr->nCharInfos;
+ nprops = pr->nFontProps;
+ swaps(&pr->minCharOrByte2, n);
+ swaps(&pr->maxCharOrByte2, n);
+ swaps(&pr->defaultChar, n);
+ swaps(&pr->nFontProps, n);
+ swaps(&pr->fontAscent, n);
+ swaps(&pr->fontDescent, n);
+ SwapCharInfo(&pr->minBounds);
+ SwapCharInfo(&pr->maxBounds);
+ swapl(&pr->nCharInfos, n);
+
+ pby = (char *) &pr[1];
+ /*
+ * Font properties are an atom and either an int32 or a CARD32, so they
+ * are always 2 4 byte values
+ */
+ for (i = 0; i < nprops; i++) {
+ swapl(pby, n);
+ pby += 4;
+ swapl(pby, n);
+ pby += 4;
+ }
+ if (!compressed) {
+ pxci = (xCharInfo *) pby;
+ for (i = 0; i < nchars; i++, pxci++)
+ SwapCharInfo(pxci);
+ } else {
+ SwapLongs((CARD32 *) pby, nchars);
+ }
+}
diff --git a/lbx/lbxtables.c b/lbx/lbxtables.c
new file mode 100644
index 000000000..c3d4f1270
--- /dev/null
+++ b/lbx/lbxtables.c
@@ -0,0 +1,33 @@
+/* $Xorg: lbxtables.c,v 1.3 2000/08/17 19:53:32 cpqbld Exp $ */
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+extern int ProcInitialConnection();
+extern int ProcLbxEstablishConnection();
+
+int (* LbxInitialVector[3]) () =
+{
+ 0,
+ ProcInitialConnection,
+ ProcLbxEstablishConnection
+};
diff --git a/lbx/lbxtags.c b/lbx/lbxtags.c
new file mode 100644
index 000000000..b2bc40ade
--- /dev/null
+++ b/lbx/lbxtags.c
@@ -0,0 +1,238 @@
+/* $Xorg: lbxtags.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "X.h"
+#include "misc.h"
+#include "lbxdata.h"
+#include "resource.h"
+#include "lbxtags.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "propertyst.h"
+
+static int tag_free();
+
+static RESTYPE TagResType;
+
+/* ARGSUSED */
+static int
+tag_free(data, id)
+ pointer data;
+ XID id;
+{
+ TagData td = (TagData) data;
+ FontTagInfoPtr ftip;
+ char *t;
+ extern int _lbx_fi_junklen;
+
+ if (td->global)
+ *(td->global) = 0;
+ /* some types need to be freed, others are shared */
+ if (td->data_type == LbxTagTypeFont) {
+ /* remove any back links */
+ ftip = (FontTagInfoPtr) td->tdata;
+ FontSetPrivate(ftip->pfont, lbx_font_private, NULL);
+ t = (char *) ftip->fontinfo;
+ if (!ftip->compression) /* points to xQueryFont, so back up to it */
+ t -= _lbx_fi_junklen;
+ xfree(t);
+ xfree(ftip);
+ }
+ xfree(data);
+ return 0;
+}
+
+TagInit()
+{
+ TagResType = CreateNewResourceType(tag_free);
+}
+
+XID
+TagNewTag()
+{
+ return FakeClientID(0);
+}
+
+void
+TagClearProxy(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ if (td)
+ td->sent_to_proxy[pid >> 3] &= ~(1 << (pid & 7));
+}
+
+void
+TagMarkProxy(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ td->sent_to_proxy[pid >> 3] |= 1 << (pid & 7);
+}
+
+Bool
+TagProxyMarked(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ return (td->sent_to_proxy[pid >> 3] & (1 << (pid & 7))) != 0;
+}
+
+XID
+TagSaveTag(dtype, size, data, global)
+ int dtype;
+ int size;
+ pointer data;
+ XID *global;
+{
+ TagData td;
+
+ td = (TagData) xalloc(sizeof(TagDataRec));
+ if (!td) {
+ if (global)
+ *global = 0;
+ return 0;
+ }
+ bzero((char *) td->sent_to_proxy, (MAX_NUM_PROXIES + 7) / 8);
+ td->tid = TagNewTag();
+ td->data_type = dtype;
+ td->tdata = data;
+ td->size = size;
+ td->global = global;
+ if (!AddResource(td->tid, TagResType, (pointer) td))
+ return 0;
+ if (global)
+ *global = td->tid;
+ return td->tid;
+}
+
+void
+TagDeleteTag(tid)
+ XID tid;
+{
+ int pid;
+ TagData td;
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ if (!td) /* shouldn't happen, but play it safe */
+ return;
+ for (pid = 1; pid < MAX_NUM_PROXIES; pid++) {
+ if (td->sent_to_proxy[pid >> 3] & (1 << (pid & 7))) {
+ proxy = LbxPidToProxy(pid);
+ lbxcp = (proxy != NULL) ? proxy->lbxClients[0] : NULL;
+ if (lbxcp && (client = lbxcp->client))
+ LbxSendInvalidateTag(client, tid, td->data_type);
+ td->sent_to_proxy[pid >> 3] &= ~(1 << (pid & 7));
+ }
+ }
+ if (td->data_type != LbxTagTypeProperty || !LbxFlushQTag(tid))
+ FreeResource(tid, 0);
+ else if (td->global) {
+ *(td->global) = 0;
+ td->global = NULL;
+ }
+}
+
+TagData
+TagGetTag(tid)
+ XID tid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ return td;
+}
+
+static void
+LbxFlushTag(value, tid, cdata)
+ pointer value;
+ XID tid;
+ pointer cdata;
+{
+ TagData td = (TagData)value;
+ LbxProxyPtr proxy = (LbxProxyPtr)cdata;
+ int i;
+
+ if ((td->data_type == LbxTagTypeProperty) && td->global) {
+ PropertyPtr pProp = (PropertyPtr)td->tdata;
+ if ((pProp->tag_id == tid) && (pProp->owner_pid == proxy->pid)) {
+ LbxFlushQTag(tid);
+ pProp->size = 0;
+ FreeResource(tid, 0);
+ return;
+ }
+ }
+ td->sent_to_proxy[proxy->pid >> 3] &= ~(1 << (proxy->pid & 7));
+ for (i = 0; i < (MAX_NUM_PROXIES + 7) / 8; i++) {
+ if (td->sent_to_proxy[i])
+ return;
+ }
+ FreeResource(tid, 0);
+}
+
+/*
+ * clear out markers for proxies
+ */
+LbxFlushTags(proxy)
+ LbxProxyPtr proxy;
+{
+ FindClientResourcesByType(NULL, TagResType, LbxFlushTag, (pointer)proxy);
+}
diff --git a/lbx/lbxtags.h b/lbx/lbxtags.h
new file mode 100644
index 000000000..3b6ab731a
--- /dev/null
+++ b/lbx/lbxtags.h
@@ -0,0 +1,119 @@
+/* $Xorg: lbxtags.h,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBXTAGS_H_
+#define _LBXTAGS_H_
+#include "lbxserve.h"
+
+#include "os.h"
+#include "opaque.h"
+#include "resource.h"
+#include "X.h"
+#include "Xproto.h"
+
+typedef struct _tagdata {
+ XID tid;
+ short data_type;
+ unsigned char sent_to_proxy[(MAX_NUM_PROXIES + 7) / 8];
+ int size;
+ pointer tdata;
+ XID *global;
+} TagDataRec;
+
+typedef struct _tagdata *TagData;
+
+extern TagData TagGetTag(
+#if NeedFunctionPrototypes
+ XID /*tid*/
+#endif
+);
+
+extern XID TagNewTag(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void TagClearProxy(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern void TagMarkProxy(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern Bool TagProxyMarked(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern void TagDeleteTag(
+#if NeedFunctionPrototypes
+ XID /*tid*/
+#endif
+);
+
+extern XID TagSaveTag(
+#if NeedFunctionPrototypes
+ int /*dtype*/,
+ int /*size*/,
+ pointer /*data*/,
+ XID* /*global*/
+#endif
+);
+
+#endif /* _LBXTAGS_H_ */
diff --git a/lbx/lbxzerorep.c b/lbx/lbxzerorep.c
new file mode 100644
index 000000000..350d7f0f9
--- /dev/null
+++ b/lbx/lbxzerorep.c
@@ -0,0 +1,416 @@
+/* $Xorg: lbxzerorep.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
+
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * This module handles zeroing out unused pad bytes in core X replies.
+ * This will hopefully improve both stream and delta compression,
+ * since we are removing the random values in pad bytes.
+ */
+
+#define NEED_REPLIES
+#include "X.h"
+#include <X11/Xproto.h>
+
+
+ZeroReplyPadBytes (buf, reqType)
+ char *buf;
+ int reqType;
+{
+ switch (reqType) {
+ case X_GetWindowAttributes:
+ {
+ xGetWindowAttributesReply *reply = (xGetWindowAttributesReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetGeometry:
+ {
+ xGetGeometryReply *reply = (xGetGeometryReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_QueryTree:
+ {
+ xQueryTreeReply *reply = (xQueryTreeReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_InternAtom:
+ {
+ xInternAtomReply *reply = (xInternAtomReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetAtomName:
+ {
+ xGetAtomNameReply *reply = (xGetAtomNameReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetProperty:
+ {
+ xGetPropertyReply *reply = (xGetPropertyReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_ListProperties:
+ {
+ xListPropertiesReply *reply = (xListPropertiesReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetSelectionOwner:
+ {
+ xGetSelectionOwnerReply *reply = (xGetSelectionOwnerReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GrabKeyboard:
+ case X_GrabPointer:
+ {
+ xGrabKeyboardReply *reply = (xGrabKeyboardReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_QueryPointer:
+ {
+ xQueryPointerReply *reply = (xQueryPointerReply *) buf;
+ reply->pad1 = 0;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetMotionEvents:
+ {
+ xGetMotionEventsReply *reply = (xGetMotionEventsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_TranslateCoords:
+ {
+ xTranslateCoordsReply *reply = (xTranslateCoordsReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_GetInputFocus:
+ {
+ xGetInputFocusReply *reply = (xGetInputFocusReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_QueryKeymap:
+ {
+ xQueryKeymapReply *reply = (xQueryKeymapReply *) buf;
+ reply->pad1 = 0;
+ break;
+ }
+ case X_QueryFont:
+ {
+ xQueryFontReply *reply = (xQueryFontReply *) buf;
+ reply->pad1 = 0;
+ break;
+ }
+ case X_QueryTextExtents:
+ {
+ xQueryTextExtentsReply *reply = (xQueryTextExtentsReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_ListFonts:
+ {
+ xListFontsReply *reply = (xListFontsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetFontPath:
+ {
+ xGetFontPathReply *reply = (xGetFontPathReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetImage:
+ {
+ xGetImageReply *reply = (xGetImageReply *) buf;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_ListInstalledColormaps:
+ {
+ xListInstalledColormapsReply *reply =
+ (xListInstalledColormapsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_AllocColor:
+ {
+ xAllocColorReply *reply = (xAllocColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_AllocNamedColor:
+ {
+ xAllocNamedColorReply *reply = (xAllocNamedColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_AllocColorCells:
+ {
+ xAllocColorCellsReply *reply = (xAllocColorCellsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_AllocColorPlanes:
+ {
+ xAllocColorPlanesReply *reply = (xAllocColorPlanesReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ break;
+ }
+ case X_QueryColors:
+ {
+ xQueryColorsReply *reply = (xQueryColorsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_LookupColor:
+ {
+ xLookupColorReply *reply = (xLookupColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_QueryBestSize:
+ {
+ xQueryBestSizeReply *reply = (xQueryBestSizeReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_QueryExtension:
+ {
+ xQueryExtensionReply *reply = (xQueryExtensionReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_ListExtensions:
+ {
+ xListExtensionsReply *reply = (xListExtensionsReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_SetPointerMapping:
+ case X_SetModifierMapping:
+ {
+ xSetMappingReply *reply = (xSetMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetPointerMapping:
+ {
+ xGetPointerMappingReply *reply = (xGetPointerMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetKeyboardMapping:
+ {
+ xGetKeyboardMappingReply *reply = (xGetKeyboardMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetModifierMapping:
+ {
+ xGetModifierMappingReply *reply = (xGetModifierMappingReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetKeyboardControl:
+ {
+ xGetKeyboardControlReply *reply = (xGetKeyboardControlReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetPointerControl:
+ {
+ xGetPointerControlReply *reply = (xGetPointerControlReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetScreenSaver:
+ {
+ xGetScreenSaverReply *reply = (xGetScreenSaverReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_ListHosts:
+ {
+ xListHostsReply *reply = (xListHostsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ }
+}