summaryrefslogtreecommitdiff
path: root/lbx/lbxcmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lbx/lbxcmap.c')
-rw-r--r--lbx/lbxcmap.c1156
1 files changed, 0 insertions, 1156 deletions
diff --git a/lbx/lbxcmap.c b/lbx/lbxcmap.c
deleted file mode 100644
index 3ae598bc6..000000000
--- a/lbx/lbxcmap.c
+++ /dev/null
@@ -1,1156 +0,0 @@
-/* $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.
-*/
-/* $XFree86: xc/programs/Xserver/lbx/lbxcmap.c,v 1.9 2001/08/23 14:46:57 alanh Exp $ */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <sys/types.h>
-#define NEED_REPLIES
-#define NEED_EVENTS
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xos.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "scrnintstr.h"
-#include "colormapst.h"
-#include "propertyst.h"
-#define _XLBX_SERVER_
-#include <X11/extensions/lbxstr.h>
-#include "lbxserve.h"
-#include <X11/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;
- CloseScreenProcPtr CloseScreen;
-} 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(pointer data, XID id);
-
-static RESTYPE StalledResType;
-
-/*
- * Initialize the fields in the colormap private allocated for LBX.
- */
-
-static LbxColormapPriv *
-LbxColormapPrivInit (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 (ColormapPtr pmap, int index)
-{
-#if 0
- /* BUG: You can't do that. lbxColormapPrivIndex hasn't
- been initialized yet. */
- pmap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
-#endif
- return 1;
-}
-
-static Bool
-LbxCreateColormap (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 (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;
-}
-
-static Bool
-LbxCloseScreen(int i, ScreenPtr pScreen)
-{
- LbxScreenPriv* pLbxScrPriv = ((LbxScreenPriv *)
- (pScreen->devPrivates[lbxScreenPrivIndex].ptr));
-
- pScreen->CloseScreen = pLbxScrPriv->CloseScreen;
-
- xfree(pScreen->devPrivates[lbxScreenPrivIndex].ptr);
- pScreen->devPrivates[lbxScreenPrivIndex].ptr = NULL;
-
- return pScreen->CloseScreen(i, pScreen);
-}
-
-/*
- * Initialize LBX colormap private.
- */
-
-int
-LbxCmapInit (void)
-
-{
- LbxScreenPriv *pScreenPriv;
- ColormapPtr defMap;
- 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];
-
- defMap = (ColormapPtr) LookupIDByType(
- pScreen->defColormap, RT_COLORMAP);
-
- /* now lbxColormapPrivIndex exists */
- defMap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
-
- pScreenPriv = (LbxScreenPriv *) xalloc (sizeof (LbxScreenPriv));
- if (!pScreenPriv)
- return 0;
-
- pScreenPriv->CreateColormap = pScreen->CreateColormap;
- pScreen->CreateColormap = LbxCreateColormap;
- pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
- pScreen->DestroyColormap = LbxDestroyColormap;
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = LbxCloseScreen;
- pScreen->devPrivates[lbxScreenPrivIndex].ptr = (pointer) pScreenPriv;
- }
-
- return 1;
-}
-
-/*
- * Return the number of allocated cells in the PSEUDO colormap.
- */
-
-static int
-NumAllocatedCells (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(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 (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 (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 (ClientPtr client,
- 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 (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 (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 (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 (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 (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 (ColormapPtr pmap)
-{
- pixel_start = -1;
- pixel_end = -1;
-}
-
-
-void
-LbxAddFreeCellToEvent (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 (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 (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(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(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(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(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(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(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;
-}