diff options
Diffstat (limited to 'lbx/lbxcmap.c')
-rw-r--r-- | lbx/lbxcmap.c | 1156 |
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; -} |