1
/* $XFree86: xc/programs/Xserver/dix/colormap.c,v 3.10 2002/04/14 00:45:54 mvojkovi Exp $ */
2
/***********************************************************
4
Copyright 1987, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
Except as contained in this notice, the name of The Open Group shall not be
23
used in advertising or otherwise to promote the sale, use or other dealings
24
in this Software without prior written authorization from The Open Group.
27
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
31
Permission to use, copy, modify, and distribute this software and its
32
documentation for any purpose and without fee is hereby granted,
33
provided that the above copyright notice appear in all copies and that
34
both that copyright notice and this permission notice appear in
35
supporting documentation, and that the name of Digital not be
36
used in advertising or publicity pertaining to distribution of the
37
software without specific, written prior permission.
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47
******************************************************************/
49
/* $Xorg: colormap.c,v 1.4 2001/02/09 02:04:39 xorgcvs Exp $ */
56
#include "colormapst.h"
58
#include "scrnintstr.h"
60
#include "windowstr.h"
65
extern XID clientErrorValue;
66
extern int colormapPrivateCount;
68
static Pixel FindBestPixel(
69
#if NeedFunctionPrototypes
70
EntryPtr /*pentFirst*/,
78
#if NeedFunctionPrototypes
85
#if NeedFunctionPrototypes
92
#if NeedFunctionPrototypes
99
#if NeedFunctionPrototypes
105
static void FreePixels(
106
#if NeedFunctionPrototypes
107
register ColormapPtr /*pmap*/,
108
register int /*client*/
112
static void CopyFree(
113
#if NeedFunctionPrototypes
116
ColormapPtr /*pmapSrc*/,
117
ColormapPtr /*pmapDst*/
121
static void FreeCell(
122
#if NeedFunctionPrototypes
123
ColormapPtr /*pmap*/,
129
static void UpdateColors(
130
#if NeedFunctionPrototypes
135
static int AllocDirect(
136
#if NeedFunctionPrototypes
138
ColormapPtr /*pmap*/,
151
static int AllocPseudo(
152
#if NeedFunctionPrototypes
154
ColormapPtr /*pmap*/,
160
Pixel ** /*pppixFirst*/
165
#if NeedFunctionPrototypes
166
ColormapPtr /*pmap*/,
167
EntryPtr /*pentFirst*/,
176
static Bool AllocShared(
177
#if NeedFunctionPrototypes
178
ColormapPtr /*pmap*/,
187
Pixel * /*ppixFirst*/
192
#if NeedFunctionPrototypes
193
ColormapPtr /*pmap*/,
202
static int TellNoMap(
203
#if NeedFunctionPrototypes
209
static void FindColorInRootCmap (
210
#if NeedFunctionPrototypes
211
ColormapPtr /* pmap */,
212
EntryPtr /* pentFirst */,
217
ColorCompareProcPtr /* comp */
221
#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
222
#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
223
#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
224
#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask)
226
/* GetNextBitsOrBreak(bits, mask, base) --
227
* (Suggestion: First read the macro, then read this explanation.
229
* Either generate the next value to OR in to a pixel or break out of this
232
* This macro is used when we're trying to generate all 2^n combinations of
233
* bits in mask. What we're doing here is counting in binary, except that
234
* the bits we use to count may not be contiguous. This macro will be
235
* called 2^n times, returning a different value in bits each time. Then
236
* it will cause us to break out of a surrounding loop. (It will always be
237
* called from within a while loop.)
238
* On call: mask is the value we want to find all the combinations for
239
* base has 1 bit set where the least significant bit of mask is set
241
* For example,if mask is 01010, base should be 0010 and we count like this:
242
* 00010 (see this isn't so hard),
243
* then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
244
* we add that to bits getting (0100 + 0100) =
245
* 01000 for our next value.
246
* then we add 0010 to get
247
* 01010 and we're done (easy as 1, 2, 3)
249
#define GetNextBitsOrBreak(bits, mask, base) \
250
if((bits) == (mask)) \
253
while((bits) & ~(mask)) \
254
(bits) += ((bits) & ~(mask));
255
/* ID of server as client */
258
typedef struct _colorResource
265
* refcnt == 0 means entry is empty
266
* refcnt > 0 means entry is useable by many clients, so it can't be changed
267
* refcnt == AllocPrivate means entry owned by one client only
268
* fShared should only be set if refcnt == AllocPrivate, and only in red map
272
/* Create and initialize the color map */
274
CreateColormap (mid, pScreen, pVisual, ppcmap, alloc, client)
275
Colormap mid; /* resource to use for this colormap */
279
int alloc; /* 1 iff all entries are allocated writeable */
283
unsigned long sizebytes;
285
register EntryPtr pent;
287
register Pixel *ppix, **pptr;
289
class = pVisual->class;
290
if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
293
size = pVisual->ColormapEntries;
294
sizebytes = (size * sizeof(Entry)) +
295
(MAXCLIENTS * sizeof(Pixel *)) +
296
(MAXCLIENTS * sizeof(int));
297
if ((class | DynamicClass) == DirectColor)
299
sizebytes += sizeof(ColormapRec);
300
pmap = (ColormapPtr) xalloc(sizebytes);
303
pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
304
sizebytes = size * sizeof(Entry);
305
pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
306
pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
307
(MAXCLIENTS * sizeof(Pixel *)));
309
pmap->flags = 0; /* start out with all flags clear */
310
if(mid == pScreen->defColormap)
311
pmap->flags |= IsDefault;
312
pmap->pScreen = pScreen;
313
pmap->pVisual = pVisual;
315
if ((class | DynamicClass) == DirectColor)
316
size = NUMRED(pVisual);
317
pmap->freeRed = size;
318
bzero ((char *) pmap->red, (int)sizebytes);
319
bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
320
for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
321
*pptr = (Pixel *)NULL;
322
if (alloc == AllocAll)
324
if (class & DynamicClass)
325
pmap->flags |= AllAllocated;
326
for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
327
pent->refcnt = AllocPrivate;
329
ppix = (Pixel *)xalloc(size * sizeof(Pixel));
335
pmap->clientPixelsRed[client] = ppix;
336
for(i = 0; i < size; i++)
338
pmap->numPixelsRed[client] = size;
341
if ((class | DynamicClass) == DirectColor)
343
pmap->freeGreen = NUMGREEN(pVisual);
344
pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
345
(MAXCLIENTS * sizeof(int)));
346
pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
347
pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
348
(MAXCLIENTS * sizeof(Pixel *)));
349
pmap->freeBlue = NUMBLUE(pVisual);
350
pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
351
(MAXCLIENTS * sizeof(int)));
352
pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
353
pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
354
(MAXCLIENTS * sizeof(Pixel *)));
356
bzero ((char *) pmap->green, (int)sizebytes);
357
bzero ((char *) pmap->blue, (int)sizebytes);
359
memmove((char *) pmap->clientPixelsGreen,
360
(char *) pmap->clientPixelsRed,
361
MAXCLIENTS * sizeof(Pixel *));
362
memmove((char *) pmap->clientPixelsBlue,
363
(char *) pmap->clientPixelsRed,
364
MAXCLIENTS * sizeof(Pixel *));
365
bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
366
bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
368
/* If every cell is allocated, mark its refcnt */
369
if (alloc == AllocAll)
371
size = pmap->freeGreen;
372
for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
373
pent->refcnt = AllocPrivate;
375
ppix = (Pixel *) xalloc(size * sizeof(Pixel));
378
xfree(pmap->clientPixelsRed[client]);
382
pmap->clientPixelsGreen[client] = ppix;
383
for(i = 0; i < size; i++)
385
pmap->numPixelsGreen[client] = size;
387
size = pmap->freeBlue;
388
for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
389
pent->refcnt = AllocPrivate;
391
ppix = (Pixel *) xalloc(size * sizeof(Pixel));
394
xfree(pmap->clientPixelsGreen[client]);
395
xfree(pmap->clientPixelsRed[client]);
399
pmap->clientPixelsBlue[client] = ppix;
400
for(i = 0; i < size; i++)
402
pmap->numPixelsBlue[client] = size;
405
if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
407
/* If the device wants a chance to initialize the colormap in any way,
408
* this is it. In specific, if this is a Static colormap, this is the
409
* time to fill in the colormap's values */
410
pmap->flags |= BeingCreated;
414
* Allocate the array of devPrivate's for this colormap.
417
if (colormapPrivateCount == 0)
418
pmap->devPrivates = NULL;
421
pmap->devPrivates = (DevUnion *) xalloc (
422
colormapPrivateCount * sizeof(DevUnion));
424
if (!pmap->devPrivates)
426
FreeResource (mid, RT_NONE);
431
if (!(*pScreen->CreateColormap)(pmap))
433
FreeResource (mid, RT_NONE);
436
pmap->flags &= ~BeingCreated;
442
FreeColormap (value, mid)
443
pointer value; /* must conform to DeleteType */
447
register EntryPtr pent;
448
ColormapPtr pmap = (ColormapPtr)value;
450
if(CLIENT_ID(mid) != SERVER_ID)
452
(*pmap->pScreen->UninstallColormap) (pmap);
453
WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
456
/* This is the device's chance to undo anything it needs to, especially
457
* to free any storage it allocated */
458
(*pmap->pScreen->DestroyColormap)(pmap);
460
if(pmap->clientPixelsRed)
462
for(i = 0; i < MAXCLIENTS; i++)
463
xfree(pmap->clientPixelsRed[i]);
466
if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
468
for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
474
if (--pent->co.shco.red->refcnt == 0)
475
xfree(pent->co.shco.red);
476
if (--pent->co.shco.green->refcnt == 0)
477
xfree(pent->co.shco.green);
478
if (--pent->co.shco.blue->refcnt == 0)
479
xfree(pent->co.shco.blue);
483
if((pmap->class | DynamicClass) == DirectColor)
485
for(i = 0; i < MAXCLIENTS; i++)
487
xfree(pmap->clientPixelsGreen[i]);
488
xfree(pmap->clientPixelsBlue[i]);
492
if (pmap->devPrivates)
493
xfree(pmap->devPrivates);
499
/* Tell window that pmid has disappeared */
501
TellNoMap (pwin, pmid)
507
if (wColormap(pwin) == *pmid)
509
/* This should be call to DeliverEvent */
510
xE.u.u.type = ColormapNotify;
511
xE.u.colormap.window = pwin->drawable.id;
512
xE.u.colormap.colormap = None;
513
xE.u.colormap.new = TRUE;
514
xE.u.colormap.state = ColormapUninstalled;
516
if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
518
DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
519
if (pwin->optional) {
520
pwin->optional->colormap = None;
521
CheckWindowOptionalNeed (pwin);
525
return (WT_WALKCHILDREN);
528
/* Tell window that pmid got uninstalled */
530
TellLostMap (pwin, value)
534
Colormap *pmid = (Colormap *)value;
538
if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
539
return WT_STOPWALKING;
541
if (wColormap(pwin) == *pmid)
543
/* This should be call to DeliverEvent */
544
xE.u.u.type = ColormapNotify;
545
xE.u.colormap.window = pwin->drawable.id;
546
xE.u.colormap.colormap = *pmid;
547
xE.u.colormap.new = FALSE;
548
xE.u.colormap.state = ColormapUninstalled;
549
DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
552
return (WT_WALKCHILDREN);
555
/* Tell window that pmid got installed */
557
TellGainedMap (pwin, value)
561
Colormap *pmid = (Colormap *)value;
565
if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
566
return WT_STOPWALKING;
568
if (wColormap (pwin) == *pmid)
570
/* This should be call to DeliverEvent */
571
xE.u.u.type = ColormapNotify;
572
xE.u.colormap.window = pwin->drawable.id;
573
xE.u.colormap.colormap = *pmid;
574
xE.u.colormap.new = FALSE;
575
xE.u.colormap.state = ColormapInstalled;
576
DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
579
return (WT_WALKCHILDREN);
584
CopyColormapAndFree (mid, pSrc, client)
589
ColormapPtr pmap = (ColormapPtr) NULL;
590
int result, alloc, size;
595
pScreen = pSrc->pScreen;
596
pVisual = pSrc->pVisual;
598
alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
599
AllocAll : AllocNone;
600
size = pVisual->ColormapEntries;
602
/* If the create returns non-0, it failed */
603
result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
604
if(result != Success)
606
if(alloc == AllocAll)
608
memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
609
if((pmap->class | DynamicClass) == DirectColor)
611
memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
612
memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
614
pSrc->flags &= ~AllAllocated;
615
FreePixels(pSrc, client);
620
CopyFree(REDMAP, client, pSrc, pmap);
621
if ((pmap->class | DynamicClass) == DirectColor)
623
CopyFree(GREENMAP, client, pSrc, pmap);
624
CopyFree(BLUEMAP, client, pSrc, pmap);
626
if (pmap->class & DynamicClass)
628
/* XXX should worry about removing any RT_CMAPENTRY resource */
632
/* Helper routine for freeing large numbers of cells from a map */
634
CopyFree (channel, client, pmapSrc, pmapDst)
636
ColormapPtr pmapSrc, pmapDst;
638
int z, npix, oldFree;
639
EntryPtr pentSrcFirst, pentDstFirst;
640
EntryPtr pentSrc, pentDst;
646
default: /* so compiler can see that everything gets initialized */
648
ppix = (pmapSrc->clientPixelsRed)[client];
649
npix = (pmapSrc->numPixelsRed)[client];
650
pentSrcFirst = pmapSrc->red;
651
pentDstFirst = pmapDst->red;
652
oldFree = pmapSrc->freeRed;
655
ppix = (pmapSrc->clientPixelsGreen)[client];
656
npix = (pmapSrc->numPixelsGreen)[client];
657
pentSrcFirst = pmapSrc->green;
658
pentDstFirst = pmapDst->green;
659
oldFree = pmapSrc->freeGreen;
662
ppix = (pmapSrc->clientPixelsBlue)[client];
663
npix = (pmapSrc->numPixelsBlue)[client];
664
pentSrcFirst = pmapSrc->blue;
665
pentDstFirst = pmapDst->blue;
666
oldFree = pmapSrc->freeBlue;
670
if (pmapSrc->class & DynamicClass)
672
for(z = npix; --z >= 0; ppix++)
675
pentSrc = pentSrcFirst + *ppix;
676
pentDst = pentDstFirst + *ppix;
677
if (pentDst->refcnt > 0)
685
if (pentSrc->refcnt > 0)
688
pentSrc->fShared = FALSE;
690
FreeCell(pmapSrc, *ppix, channel);
694
/* Note that FreeCell has already fixed pmapSrc->free{Color} */
698
pmapDst->freeRed -= nalloc;
699
(pmapDst->clientPixelsRed)[client] =
700
(pmapSrc->clientPixelsRed)[client];
701
(pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
702
(pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
703
(pmapSrc->numPixelsRed)[client] = 0;
706
pmapDst->freeGreen -= nalloc;
707
(pmapDst->clientPixelsGreen)[client] =
708
(pmapSrc->clientPixelsGreen)[client];
709
(pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
710
(pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
711
(pmapSrc->numPixelsGreen)[client] = 0;
714
pmapDst->freeBlue -= nalloc;
715
pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
716
pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
717
pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
718
pmapSrc->numPixelsBlue[client] = 0;
723
/* Free the ith entry in a color map. Must handle freeing of
724
* colors allocated through AllocColorPlanes */
726
FreeCell (pmap, i, channel)
737
default: /* so compiler can see that everything gets initialized */
740
pent = (EntryPtr) &pmap->red[i];
741
pCount = &pmap->freeRed;
744
pent = (EntryPtr) &pmap->green[i];
745
pCount = &pmap->freeGreen;
748
pent = (EntryPtr) &pmap->blue[i];
749
pCount = &pmap->freeBlue;
752
/* If it's not privately allocated and it's not time to free it, just
753
* decrement the count */
754
if (pent->refcnt > 1)
758
/* If the color type is shared, find the sharedcolor. If decremented
759
* refcnt is 0, free the shared cell. */
762
if(--pent->co.shco.red->refcnt == 0)
763
xfree(pent->co.shco.red);
764
if(--pent->co.shco.green->refcnt == 0)
765
xfree(pent->co.shco.green);
766
if(--pent->co.shco.blue->refcnt == 0)
767
xfree(pent->co.shco.blue);
768
pent->fShared = FALSE;
780
register xColorItem *pdef;
781
register EntryPtr pent;
782
register VisualPtr pVisual;
785
pVisual = pmap->pVisual;
786
size = pVisual->ColormapEntries;
787
defs = (xColorItem *)ALLOCATE_LOCAL(size * sizeof(xColorItem));
792
if (pmap->class == DirectColor)
794
for (i = 0; i < size; i++)
796
if (!pmap->red[i].refcnt &&
797
!pmap->green[i].refcnt &&
798
!pmap->blue[i].refcnt)
800
pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
801
((Pixel)i << pVisual->offsetGreen) |
802
((Pixel)i << pVisual->offsetBlue);
803
pdef->red = pmap->red[i].co.local.red;
804
pdef->green = pmap->green[i].co.local.green;
805
pdef->blue = pmap->blue[i].co.local.blue;
806
pdef->flags = DoRed|DoGreen|DoBlue;
813
for (i = 0, pent = pmap->red; i < size; i++, pent++)
820
pdef->red = pent->co.shco.red->color;
821
pdef->green = pent->co.shco.green->color;
822
pdef->blue = pent->co.shco.blue->color;
826
pdef->red = pent->co.local.red;
827
pdef->green = pent->co.local.green;
828
pdef->blue = pent->co.local.blue;
830
pdef->flags = DoRed|DoGreen|DoBlue;
836
(*pmap->pScreen->StoreColors)(pmap, n, defs);
837
DEALLOCATE_LOCAL(defs);
840
/* Get a read-only color from a ColorMap (probably slow for large maps)
841
* Returns by changing the value in pred, pgreen, pblue and pPix
844
AllocColor (pmap, pred, pgreen, pblue, pPix, client)
846
unsigned short *pred, *pgreen, *pblue;
850
Pixel pixR, pixG, pixB;
858
pVisual = pmap->pVisual;
859
(*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
864
entries = pVisual->ColormapEntries;
866
/* If the colormap is being created, then we want to be able to change
867
* the colormap, even if it's a static type. Otherwise, we'd never be
868
* able to initialize static colormaps
870
if(pmap->flags & BeingCreated)
871
class |= DynamicClass;
873
/* If this is one of the static storage classes, and we're not initializing
874
* it, the best we can do is to find the closest color entry to the
875
* requested one and return that.
880
/* Look up all three components in the same pmap */
881
*pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
882
*pred = pmap->red[pixR].co.local.red;
883
*pgreen = pmap->red[pixR].co.local.green;
884
*pblue = pmap->red[pixR].co.local.blue;
885
npix = pmap->numPixelsRed[client];
886
ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
887
(npix + 1) * sizeof(Pixel));
891
pmap->clientPixelsRed[client] = ppix;
892
pmap->numPixelsRed[client]++;
896
/* Look up each component in its own map, then OR them together */
897
pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
898
pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
899
pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
900
*pPix = (pixR << pVisual->offsetRed) |
901
(pixG << pVisual->offsetGreen) |
902
(pixB << pVisual->offsetBlue);
903
*pred = pmap->red[pixR].co.local.red;
904
*pgreen = pmap->green[pixG].co.local.green;
905
*pblue = pmap->blue[pixB].co.local.blue;
906
npix = pmap->numPixelsRed[client];
907
ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
908
(npix + 1) * sizeof(Pixel));
912
pmap->clientPixelsRed[client] = ppix;
913
npix = pmap->numPixelsGreen[client];
914
ppix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
915
(npix + 1) * sizeof(Pixel));
919
pmap->clientPixelsGreen[client] = ppix;
920
npix = pmap->numPixelsBlue[client];
921
ppix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
922
(npix + 1) * sizeof(Pixel));
926
pmap->clientPixelsBlue[client] = ppix;
927
pmap->numPixelsRed[client]++;
928
pmap->numPixelsGreen[client]++;
929
pmap->numPixelsBlue[client]++;
934
if (pmap->mid != pmap->pScreen->defColormap &&
935
pmap->pVisual->vid == pmap->pScreen->rootVisual)
937
ColormapPtr prootmap = (ColormapPtr)
938
SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
939
RT_COLORMAP, SecurityReadAccess);
941
if (pmap->class == prootmap->class)
942
FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
943
pPix, PSEUDOMAP, AllComp);
945
if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
946
client, AllComp) != Success)
951
if (pmap->mid != pmap->pScreen->defColormap &&
952
pmap->pVisual->vid == pmap->pScreen->rootVisual)
954
ColormapPtr prootmap = (ColormapPtr)
955
SecurityLookupIDByType (clients[client], pmap->pScreen->defColormap,
956
RT_COLORMAP, SecurityReadAccess);
958
if (pmap->class == prootmap->class)
960
pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
961
FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
962
&pixR, REDMAP, RedComp);
963
pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
964
FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
965
&pixG, GREENMAP, GreenComp);
966
pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
967
FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
968
&pixB, BLUEMAP, BlueComp);
969
*pPix = pixR | pixG | pixB;
973
pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
974
if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
975
client, RedComp) != Success)
977
pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
978
if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
979
GREENMAP, client, GreenComp) != Success)
981
(void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
984
pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
985
if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
986
client, BlueComp) != Success)
988
(void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
989
(void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
992
*pPix = pixR | pixG | pixB;
996
/* if this is the client's first pixel in this colormap, tell the
997
* resource manager that the client has pixels in this colormap which
998
* should be freed when the client dies */
999
if ((pmap->numPixelsRed[client] == 1) &&
1000
(CLIENT_ID(pmap->mid) != client) &&
1001
!(pmap->flags & BeingCreated))
1005
pcr = (colorResource *) xalloc(sizeof(colorResource));
1008
(void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
1011
pcr->mid = pmap->mid;
1012
pcr->client = client;
1013
if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
1020
* FakeAllocColor -- fake an AllocColor request by
1021
* returning a free pixel if availible, otherwise returning
1022
* the closest matching pixel. This is used by the mi
1023
* software sprite code to recolor cursors. A nice side-effect
1024
* is that this routine will never return failure.
1028
FakeAllocColor (pmap, item)
1029
register ColormapPtr pmap;
1030
register xColorItem *item;
1032
Pixel pixR, pixG, pixB;
1037
register VisualPtr pVisual;
1039
pVisual = pmap->pVisual;
1040
rgb.red = item->red;
1041
rgb.green = item->green;
1042
rgb.blue = item->blue;
1043
(*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
1044
class = pmap->class;
1045
entries = pVisual->ColormapEntries;
1051
if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
1052
-1, AllComp) == Success) {
1056
/* fall through ... */
1059
item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
1063
/* Look up each component in its own map, then OR them together */
1064
pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
1065
pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
1066
pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
1067
if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
1068
-1, RedComp) != Success)
1069
pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
1070
<< pVisual->offsetRed;
1071
if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
1072
GREENMAP, -1, GreenComp) != Success)
1073
pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
1074
GREENMAP) << pVisual->offsetGreen;
1075
if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
1076
-1, BlueComp) != Success)
1077
pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
1078
<< pVisual->offsetBlue;
1079
item->pixel = pixR | pixG | pixB;
1083
/* Look up each component in its own map, then OR them together */
1084
pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
1085
pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
1086
pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
1087
item->pixel = (pixR << pVisual->offsetRed) |
1088
(pixG << pVisual->offsetGreen) |
1089
(pixB << pVisual->offsetBlue);
1094
/* free a pixel value obtained from FakeAllocColor */
1096
FakeFreeColor(pmap, pixel)
1097
register ColormapPtr pmap;
1100
register VisualPtr pVisual;
1101
Pixel pixR, pixG, pixB;
1103
switch (pmap->class) {
1106
if (pmap->red[pixel].refcnt == AllocTemporary)
1107
pmap->red[pixel].refcnt = 0;
1110
pVisual = pmap->pVisual;
1111
pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
1112
pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
1113
pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
1114
if (pmap->red[pixR].refcnt == AllocTemporary)
1115
pmap->red[pixR].refcnt = 0;
1116
if (pmap->green[pixG].refcnt == AllocTemporary)
1117
pmap->green[pixG].refcnt = 0;
1118
if (pmap->blue[pixB].refcnt == AllocTemporary)
1119
pmap->blue[pixB].refcnt = 0;
1124
typedef unsigned short BigNumUpper;
1125
typedef unsigned long BigNumLower;
1127
#define BIGNUMLOWERBITS 24
1128
#define BIGNUMUPPERBITS 16
1129
#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
1130
#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
1131
#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
1132
#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
1134
typedef struct _bignum {
1137
} BigNumRec, *BigNumPtr;
1139
#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
1140
((x)->upper == (y)->upper && (x)->lower > (y)->lower))
1142
#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
1143
((r)->lower = LOWERPART(u)))
1145
#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
1146
((r)->lower = BIGNUMLOWER-1))
1149
#if NeedFunctionPrototypes
1150
BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
1156
BigNumLower lower, carry = 0;
1158
lower = x->lower + y->lower;
1159
if (lower >= BIGNUMLOWER) {
1160
lower -= BIGNUMLOWER;
1164
r->upper = x->upper + y->upper + carry;
1168
FindBestPixel(pentFirst, size, prgb, channel)
1178
BigNumRec minval, sum, temp;
1182
/* look for the minimal difference */
1183
for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
1189
dg = (long) pent->co.local.green - prgb->green;
1190
db = (long) pent->co.local.blue - prgb->blue;
1192
dr = (long) pent->co.local.red - prgb->red;
1195
dg = (long) pent->co.local.green - prgb->green;
1198
db = (long) pent->co.local.blue - prgb->blue;
1202
UnsignedToBigNum (sq, &sum);
1204
UnsignedToBigNum (sq, &temp);
1205
BigNumAdd (&sum, &temp, &sum);
1207
UnsignedToBigNum (sq, &temp);
1208
BigNumAdd (&sum, &temp, &sum);
1209
if (BigNumGreater (&minval, &sum))
1219
FindColorInRootCmap (pmap, pentFirst, size, prgb, pPixel, channel, comp)
1226
ColorCompareProcPtr comp;
1232
if ((pixel = *pPixel) >= size)
1234
for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
1236
if (pent->refcnt > 0 && (*comp) (pent, prgb))
1241
pixel <<= pmap->pVisual->offsetRed;
1244
pixel <<= pmap->pVisual->offsetGreen;
1247
pixel <<= pmap->pVisual->offsetBlue;
1249
default: /* PSEUDOMAP */
1257
/* Tries to find a color in pmap that exactly matches the one requested in prgb
1258
* if it can't it allocates one.
1259
* Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
1260
* load *pPixel with that value, otherwise set it to 0
1263
FindColor (pmap, pentFirst, size, prgb, pPixel, channel, client, comp)
1271
ColorCompareProcPtr comp;
1275
Pixel pixel, Free = 0;
1276
int npix, count, *nump = NULL;
1277
Pixel **pixp = NULL, *ppix;
1282
if((pixel = *pPixel) >= size)
1284
/* see if there is a match, and also look for a free entry */
1285
for (pent = pentFirst + pixel, count = size; --count >= 0; )
1287
if (pent->refcnt > 0)
1289
if ((*comp) (pent, prgb))
1297
*pPixel <<= pmap->pVisual->offsetRed;
1301
*pPixel <<= pmap->pVisual->offsetGreen;
1304
*pPixel <<= pmap->pVisual->offsetBlue;
1310
else if (!foundFree && pent->refcnt == 0)
1314
/* If we're initializing the colormap, then we are looking for
1315
* the first free cell we can find, not to minimize the number
1316
* of entries we use. So don't look any further. */
1317
if(pmap->flags & BeingCreated)
1330
/* If we got here, we didn't find a match. If we also didn't find
1331
* a free entry, we're out of luck. Otherwise, we'll usurp a free
1332
* entry and fill it in */
1335
pent = pentFirst + Free;
1336
pent->fShared = FALSE;
1337
pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
1342
pent->co.local.red = prgb->red;
1343
pent->co.local.green = prgb->green;
1344
pent->co.local.blue = prgb->blue;
1345
def.red = prgb->red;
1346
def.green = prgb->green;
1347
def.blue = prgb->blue;
1348
def.flags = (DoRed|DoGreen|DoBlue);
1355
pent->co.local.red = prgb->red;
1356
def.red = prgb->red;
1357
def.green = pmap->green[0].co.local.green;
1358
def.blue = pmap->blue[0].co.local.blue;
1362
def.pixel = Free << pmap->pVisual->offsetRed;
1366
pent->co.local.green = prgb->green;
1367
def.red = pmap->red[0].co.local.red;
1368
def.green = prgb->green;
1369
def.blue = pmap->blue[0].co.local.blue;
1370
def.flags = DoGreen;
1373
def.pixel = Free << pmap->pVisual->offsetGreen;
1377
pent->co.local.blue = prgb->blue;
1378
def.red = pmap->red[0].co.local.red;
1379
def.green = pmap->green[0].co.local.green;
1380
def.blue = prgb->blue;
1384
def.pixel = Free << pmap->pVisual->offsetBlue;
1387
(*pmap->pScreen->StoreColors) (pmap, 1, &def);
1389
*pPixel = def.pixel;
1392
if (pmap->flags & BeingCreated || client == -1)
1394
/* Now remember the pixel, for freeing later */
1399
nump = pmap->numPixelsRed;
1400
pixp = pmap->clientPixelsRed;
1404
nump = pmap->numPixelsGreen;
1405
pixp = pmap->clientPixelsGreen;
1409
nump = pmap->numPixelsBlue;
1410
pixp = pmap->clientPixelsBlue;
1413
npix = nump[client];
1414
ppix = (Pixel *) xrealloc (pixp[client], (npix + 1) * sizeof(Pixel));
1435
pixp[client] = ppix;
1441
/* Comparison functions -- passed to FindColor to determine if an
1442
* entry is already the color we're looking for or not */
1444
AllComp (pent, prgb)
1448
if((pent->co.local.red == prgb->red) &&
1449
(pent->co.local.green == prgb->green) &&
1450
(pent->co.local.blue == prgb->blue) )
1456
RedComp (pent, prgb)
1460
if (pent->co.local.red == prgb->red)
1466
GreenComp (pent, prgb)
1470
if (pent->co.local.green == prgb->green)
1476
BlueComp (pent, prgb)
1480
if (pent->co.local.blue == prgb->blue)
1486
/* Read the color value of a cell */
1489
QueryColors (pmap, count, ppixIn, prgbList)
1500
int errVal = Success;
1502
pVisual = pmap->pVisual;
1503
if ((pmap->class | DynamicClass) == DirectColor)
1505
int numred, numgreen, numblue;
1508
numred = NUMRED(pVisual);
1509
numgreen = NUMGREEN(pVisual);
1510
numblue = NUMBLUE(pVisual);
1511
rgbbad = ~RGBMASK(pVisual);
1512
for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
1515
if (pixel & rgbbad) {
1516
clientErrorValue = pixel;
1520
i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
1523
clientErrorValue = pixel;
1527
prgb->red = pmap->red[i].co.local.red;
1528
i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
1531
clientErrorValue = pixel;
1535
prgb->green = pmap->green[i].co.local.green;
1536
i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
1539
clientErrorValue = pixel;
1543
prgb->blue = pmap->blue[i].co.local.blue;
1548
for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
1551
if (pixel >= pVisual->ColormapEntries)
1553
clientErrorValue = pixel;
1558
pent = (EntryPtr)&pmap->red[pixel];
1561
prgb->red = pent->co.shco.red->color;
1562
prgb->green = pent->co.shco.green->color;
1563
prgb->blue = pent->co.shco.blue->color;
1567
prgb->red = pent->co.local.red;
1568
prgb->green = pent->co.local.green;
1569
prgb->blue = pent->co.local.blue;
1578
FreePixels(pmap, client)
1579
register ColormapPtr pmap;
1580
register int client;
1582
register Pixel *ppix, *ppixStart;
1588
Bool anyRefCountReachedZero = 0;
1591
class = pmap->class;
1592
ppixStart = pmap->clientPixelsRed[client];
1593
if (class & DynamicClass)
1595
n = pmap->numPixelsRed[client];
1597
grabbed = LbxCheckCmapGrabbed (pmap);
1601
* If the colormap is grabbed by a proxy, the server must
1602
* notify the proxy of all cells that are freed (the refcount
1603
* has reached zero on these cells).
1606
LbxBeginFreeCellsEvent (pmap);
1607
LbxSortPixelList (ppixStart, n);
1610
for (ppix = ppixStart; --n >= 0; )
1612
FreeCell(pmap, *ppix, REDMAP);
1615
* Only PSEUDO colormaps are grabbed by LBX proxies.
1616
* Check if the ref count reached zero on this pixel.
1619
zeroRefCount = pmap->red[*ppix].refcnt == 0;
1621
anyRefCountReachedZero = 1;
1623
if (grabbed && zeroRefCount)
1624
LbxAddFreeCellToEvent (pmap, *ppix);
1630
LbxEndFreeCellsEvent (pmap);
1631
else if (anyRefCountReachedZero)
1634
* We only send LbxFreeCell events to a proxy that has the colormap
1635
* grabbed. If the colormap is not grabbed, the proxy that last
1636
* had the colormap grabbed will not be able to do a smart grab
1637
* in the future. A smart grab can only occur if the proxy is kept
1638
* up to date on every alloc/free change in the colormap.
1641
LbxDisableSmartGrab (pmap);
1647
pmap->clientPixelsRed[client] = (Pixel *) NULL;
1648
pmap->numPixelsRed[client] = 0;
1649
if ((class | DynamicClass) == DirectColor)
1651
ppixStart = pmap->clientPixelsGreen[client];
1652
if (class & DynamicClass)
1653
for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
1654
FreeCell(pmap, *ppix++, GREENMAP);
1656
pmap->clientPixelsGreen[client] = (Pixel *) NULL;
1657
pmap->numPixelsGreen[client] = 0;
1659
ppixStart = pmap->clientPixelsBlue[client];
1660
if (class & DynamicClass)
1661
for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
1662
FreeCell(pmap, *ppix++, BLUEMAP);
1664
pmap->clientPixelsBlue[client] = (Pixel *) NULL;
1665
pmap->numPixelsBlue[client] = 0;
1669
/* Free all of a client's colors and cells */
1672
FreeClientPixels (value, fakeid)
1673
pointer value; /* must conform to DeleteType */
1677
colorResource *pcr = (colorResource *)value;
1679
pmap = (ColormapPtr) LookupIDByType(pcr->mid, RT_COLORMAP);
1681
FreePixels(pmap, pcr->client);
1687
AllocColorCells (client, pmap, colors, planes, contig, ppix, masks)
1695
Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
1699
colorResource *pcr = (colorResource *)NULL;
1701
class = pmap->class;
1702
if (!(class & DynamicClass))
1703
return (BadAlloc); /* Shouldn't try on this type */
1704
oldcount = pmap->numPixelsRed[client];
1705
if (pmap->class == DirectColor)
1706
oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
1707
if (!oldcount && (CLIENT_ID(pmap->mid) != client))
1709
pcr = (colorResource *) xalloc(sizeof(colorResource));
1714
if (pmap->class == DirectColor)
1716
ok = AllocDirect (client, pmap, colors, planes, planes, planes,
1717
contig, ppix, &rmask, &gmask, &bmask);
1720
for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
1728
*masks++ = r | g | b;
1734
ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
1738
for (r = 1, n = planes; --n >= 0; r += r)
1747
/* if this is the client's first pixels in this colormap, tell the
1748
* resource manager that the client has pixels in this colormap which
1749
* should be freed when the client dies */
1750
if ((ok == Success) && pcr)
1752
pcr->mid = pmap->mid;
1753
pcr->client = client;
1754
if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
1764
AllocColorPlanes (client, pmap, colors, r, g, b, contig, pixels,
1765
prmask, pgmask, pbmask)
1768
int colors, r, g, b;
1771
Pixel *prmask, *pgmask, *pbmask;
1774
Pixel mask, *ppixFirst;
1775
register Pixel shift;
1779
colorResource *pcr = (colorResource *)NULL;
1781
class = pmap->class;
1782
if (!(class & DynamicClass))
1783
return (BadAlloc); /* Shouldn't try on this type */
1784
oldcount = pmap->numPixelsRed[client];
1785
if (class == DirectColor)
1786
oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
1787
if (!oldcount && (CLIENT_ID(pmap->mid) != client))
1789
pcr = (colorResource *) xalloc(sizeof(colorResource));
1794
if (class == DirectColor)
1796
ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
1797
prmask, pgmask, pbmask);
1801
/* Allocate the proper pixels */
1802
/* XXX This is sort of bad, because of contig is set, we force all
1803
* r + g + b bits to be contiguous. Should only force contiguity
1806
ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
1811
/* now split that mask into three */
1812
*prmask = *pgmask = *pbmask = 0;
1814
for (i = r; --i >= 0; shift += shift)
1816
while (!(mask & shift))
1820
for (i = g; --i >= 0; shift += shift)
1822
while (!(mask & shift))
1826
for (i = b; --i >= 0; shift += shift)
1828
while (!(mask & shift))
1833
/* set up the shared color cells */
1834
if (!AllocShared(pmap, pixels, colors, r, g, b,
1835
*prmask, *pgmask, *pbmask, ppixFirst))
1837
(void)FreeColors(pmap, client, colors, pixels, mask);
1843
/* if this is the client's first pixels in this colormap, tell the
1844
* resource manager that the client has pixels in this colormap which
1845
* should be freed when the client dies */
1846
if ((ok == Success) && pcr)
1848
pcr->mid = pmap->mid;
1849
pcr->client = client;
1850
if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
1859
AllocDirect (client, pmap, c, r, g, b, contig, pixels, prmask, pgmask, pbmask)
1865
Pixel *prmask, *pgmask, *pbmask;
1867
Pixel *ppixRed, *ppixGreen, *ppixBlue;
1868
Pixel *ppix, *pDst, *p;
1869
int npix, npixR, npixG, npixB;
1871
Pixel *rpix = 0, *gpix = 0, *bpix = 0;
1876
if ((r >= 32) || (g >= 32) || (b >= 32) ||
1877
(npixR > pmap->freeRed) || (npixR < c) ||
1878
(npixG > pmap->freeGreen) || (npixG < c) ||
1879
(npixB > pmap->freeBlue) || (npixB < c))
1882
/* start out with empty pixels */
1883
for(p = pixels; p < pixels + c; p++)
1886
ppixRed = (Pixel *)ALLOCATE_LOCAL(npixR * sizeof(Pixel));
1887
ppixGreen = (Pixel *)ALLOCATE_LOCAL(npixG * sizeof(Pixel));
1888
ppixBlue = (Pixel *)ALLOCATE_LOCAL(npixB * sizeof(Pixel));
1889
if (!ppixRed || !ppixGreen || !ppixBlue)
1891
if (ppixBlue) DEALLOCATE_LOCAL(ppixBlue);
1892
if (ppixGreen) DEALLOCATE_LOCAL(ppixGreen);
1893
if (ppixRed) DEALLOCATE_LOCAL(ppixRed);
1897
okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
1898
okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
1899
okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
1901
if (okR && okG && okB)
1903
rpix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
1904
(pmap->numPixelsRed[client] + (c << r)) *
1907
pmap->clientPixelsRed[client] = rpix;
1908
gpix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
1909
(pmap->numPixelsGreen[client] + (c << g)) *
1912
pmap->clientPixelsGreen[client] = gpix;
1913
bpix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
1914
(pmap->numPixelsBlue[client] + (c << b)) *
1917
pmap->clientPixelsBlue[client] = bpix;
1920
if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
1923
for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
1924
pmap->red[*ppix].refcnt = 0;
1926
for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
1927
pmap->green[*ppix].refcnt = 0;
1929
for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
1930
pmap->blue[*ppix].refcnt = 0;
1931
DEALLOCATE_LOCAL(ppixBlue);
1932
DEALLOCATE_LOCAL(ppixGreen);
1933
DEALLOCATE_LOCAL(ppixRed);
1937
*prmask <<= pmap->pVisual->offsetRed;
1938
*pgmask <<= pmap->pVisual->offsetGreen;
1939
*pbmask <<= pmap->pVisual->offsetBlue;
1941
ppix = rpix + pmap->numPixelsRed[client];
1942
for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
1946
*pDst++ |= *p << pmap->pVisual->offsetRed;
1948
pmap->numPixelsRed[client] += npixR;
1949
pmap->freeRed -= npixR;
1951
ppix = gpix + pmap->numPixelsGreen[client];
1952
for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
1955
if(p < ppixGreen + c)
1956
*pDst++ |= *p << pmap->pVisual->offsetGreen;
1958
pmap->numPixelsGreen[client] += npixG;
1959
pmap->freeGreen -= npixG;
1961
ppix = bpix + pmap->numPixelsBlue[client];
1962
for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
1965
if(p < ppixBlue + c)
1966
*pDst++ |= *p << pmap->pVisual->offsetBlue;
1968
pmap->numPixelsBlue[client] += npixB;
1969
pmap->freeBlue -= npixB;
1971
DEALLOCATE_LOCAL(ppixBlue);
1972
DEALLOCATE_LOCAL(ppixGreen);
1973
DEALLOCATE_LOCAL(ppixRed);
1979
AllocPseudo (client, pmap, c, r, contig, pixels, pmask, pppixFirst)
1988
Pixel *ppix, *p, *pDst, *ppixTemp;
1993
if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
1995
if(!(ppixTemp = (Pixel *)ALLOCATE_LOCAL(npix * sizeof(Pixel))))
1997
ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
2002
/* all the allocated pixels are added to the client pixel list,
2003
* but only the unique ones are returned to the client */
2004
ppix = (Pixel *)xrealloc(pmap->clientPixelsRed[client],
2005
(pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
2008
for (p = ppixTemp; p < ppixTemp + npix; p++)
2009
pmap->red[*p].refcnt = 0;
2012
pmap->clientPixelsRed[client] = ppix;
2013
ppix += pmap->numPixelsRed[client];
2016
for (p = ppixTemp; p < ppixTemp + npix; p++)
2019
if(p < ppixTemp + c)
2022
pmap->numPixelsRed[client] += npix;
2023
pmap->freeRed -= npix;
2025
DEALLOCATE_LOCAL(ppixTemp);
2026
return (ok ? Success : BadAlloc);
2029
/* Allocates count << planes pixels from colormap pmap for client. If
2030
* contig, then the plane mask is made of consecutive bits. Returns
2031
* all count << pixels in the array pixels. The first count of those
2032
* pixels are the unique pixels. *pMask has the mask to Or with the
2033
* unique pixels to get the rest of them.
2035
* Returns True iff all pixels could be allocated
2036
* All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
2037
* (see AllocShared for why we care)
2040
AllocCP (pmap, pentFirst, count, planes, contig, pixels, pMask)
2045
Pixel *pixels, *pMask;
2049
Pixel pixel, base, entries, maxp, save;
2055
dplanes = pmap->pVisual->nplanes;
2057
/* Easy case. Allocate pixels only */
2060
/* allocate writable entries */
2064
while (--count >= 0)
2066
/* Just find count unallocated cells */
2072
ent->refcnt = AllocPrivate;
2074
ent->fShared = FALSE;
2079
else if (planes > dplanes)
2084
/* General case count pixels * 2 ^ planes cells to be allocated */
2086
/* make room for new pixels */
2089
/* first try for contiguous planes, since it's fastest */
2090
for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
2092
mask += mask, base += base)
2097
entries = pmap->pVisual->ColormapEntries - mask;
2098
while (pixel < entries)
2101
maxp = pixel + mask + base;
2102
/* check if all are free */
2103
while (pixel != maxp && ent[pixel].refcnt == 0)
2107
/* this one works */
2112
/* found enough, allocate them all */
2113
while (--count >= 0)
2115
pixel = pixels[count];
2116
maxp = pixel + mask;
2119
ent[pixel].refcnt = AllocPrivate;
2120
ent[pixel].fShared = FALSE;
2137
dplanes = pmap->pVisual->nplanes;
2138
if (contig || planes == 1 || dplanes < 3)
2141
/* this will be very slow for large maps, need a better algorithm */
2144
we can generate the smallest and largest numbers that fits in dplanes
2145
bits and contain exactly planes bits set as follows. First, we need to
2146
check that it is possible to generate such a mask at all.
2147
(Non-contiguous masks need one more bit than contiguous masks). Then
2148
the smallest such mask consists of the rightmost planes-1 bits set, then
2149
a zero, then a one in position planes + 1. The formula is
2150
(3 << (planes-1)) -1
2151
The largest such masks consists of the leftmost planes-1 bits set, then
2152
a zero, then a one bit in position dplanes-planes-1. If dplanes is
2153
smaller than 32 (the number of bits in a word) then the formula is:
2154
(1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
2155
If dplanes = 32, then we can't calculate (1<<dplanes) and we have
2157
( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
2159
<< Thank you, Loretta>>>
2164
(((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
2165
(((Pixel)1)<<(dplanes-planes-1));
2166
for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
2168
/* next 3 magic statements count number of ones (HAKMEM #169) */
2169
pixel = (mask >> 1) & 033333333333;
2170
pixel = mask - pixel - ((pixel >> 1) & 033333333333);
2171
if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
2175
entries = pmap->pVisual->ColormapEntries - mask;
2176
base = lowbit (mask);
2177
for (pixel = 0; pixel < entries; pixel++)
2182
/* check if all are free */
2183
while (ent[pixel + maxp].refcnt == 0)
2185
GetNextBitsOrBreak(maxp, mask, base);
2187
if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
2189
/* this one works */
2194
/* found enough, allocate them all */
2195
while (--count >= 0)
2197
pixel = (pixels)[count];
2201
ent[pixel + maxp].refcnt = AllocPrivate;
2202
ent[pixel + maxp].fShared = FALSE;
2203
GetNextBitsOrBreak(maxp, mask, base);
2204
*ppix++ = pixel + maxp;
2216
AllocShared (pmap, ppix, c, r, g, b, rmask, gmask, bmask, ppixFirst)
2220
Pixel rmask, gmask, bmask;
2221
Pixel *ppixFirst; /* First of the client's new pixels */
2224
int npix, z, npixClientNew, npixShared;
2225
Pixel basemask, base, bits, common;
2226
SHAREDCOLOR *pshared, **ppshared, **psharedList;
2228
npixClientNew = c << (r + g + b);
2229
npixShared = (c << r) + (c << g) + (c << b);
2230
psharedList = (SHAREDCOLOR **)ALLOCATE_LOCAL(npixShared *
2231
sizeof(SHAREDCOLOR *));
2234
ppshared = psharedList;
2235
for (z = npixShared; --z >= 0; )
2237
if (!(ppshared[z] = (SHAREDCOLOR *)xalloc(sizeof(SHAREDCOLOR))))
2239
for (z++ ; z < npixShared; z++)
2244
for(pptr = ppix, npix = c; --npix >= 0; pptr++)
2246
basemask = ~(gmask | bmask);
2247
common = *pptr & basemask;
2251
base = lowbit (rmask);
2254
pshared = *ppshared++;
2255
pshared->refcnt = 1 << (g + b);
2256
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2258
if ((*cptr & basemask) == (common | bits))
2260
pmap->red[*cptr].fShared = TRUE;
2261
pmap->red[*cptr].co.shco.red = pshared;
2264
GetNextBitsOrBreak(bits, rmask, base);
2269
pshared = *ppshared++;
2270
pshared->refcnt = 1 << (g + b);
2271
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2273
if ((*cptr & basemask) == common)
2275
pmap->red[*cptr].fShared = TRUE;
2276
pmap->red[*cptr].co.shco.red = pshared;
2280
basemask = ~(rmask | bmask);
2281
common = *pptr & basemask;
2285
base = lowbit (gmask);
2288
pshared = *ppshared++;
2289
pshared->refcnt = 1 << (r + b);
2290
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2292
if ((*cptr & basemask) == (common | bits))
2294
pmap->red[*cptr].co.shco.green = pshared;
2297
GetNextBitsOrBreak(bits, gmask, base);
2302
pshared = *ppshared++;
2303
pshared->refcnt = 1 << (g + b);
2304
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2306
if ((*cptr & basemask) == common)
2308
pmap->red[*cptr].co.shco.green = pshared;
2312
basemask = ~(rmask | gmask);
2313
common = *pptr & basemask;
2317
base = lowbit (bmask);
2320
pshared = *ppshared++;
2321
pshared->refcnt = 1 << (r + g);
2322
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2324
if ((*cptr & basemask) == (common | bits))
2326
pmap->red[*cptr].co.shco.blue = pshared;
2329
GetNextBitsOrBreak(bits, bmask, base);
2334
pshared = *ppshared++;
2335
pshared->refcnt = 1 << (g + b);
2336
for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
2338
if ((*cptr & basemask) == common)
2340
pmap->red[*cptr].co.shco.blue = pshared;
2345
DEALLOCATE_LOCAL(psharedList);
2350
/* Free colors and/or cells (probably slow for large numbers) */
2353
FreeColors (pmap, client, count, pixels, mask)
2359
int rval, result, class;
2362
class = pmap->class;
2363
if (pmap->flags & AllAllocated)
2365
if ((class | DynamicClass) == DirectColor)
2367
rmask = mask & RGBMASK(pmap->pVisual);
2368
result = FreeCo(pmap, client, REDMAP, count, pixels,
2369
mask & pmap->pVisual->redMask);
2370
/* If any of the three calls fails, we must report that, if more
2371
* than one fails, it's ok that we report the last one */
2372
rval = FreeCo(pmap, client, GREENMAP, count, pixels,
2373
mask & pmap->pVisual->greenMask);
2376
rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
2377
mask & pmap->pVisual->blueMask);
2383
rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
2384
result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
2386
if ((mask != rmask) && count)
2388
clientErrorValue = *pixels | mask;
2391
/* XXX should worry about removing any RT_CMAPENTRY resource */
2395
/* Helper for FreeColors -- frees all combinations of *newpixels and mask bits
2396
* which the client has allocated in channel colormap cells of pmap.
2397
* doesn't change newpixels if it doesn't need to */
2399
FreeCo (pmap, client, color, npixIn, ppixIn, mask)
2400
ColormapPtr pmap; /* which colormap head */
2402
int color; /* which sub-map, eg RED, BLUE, PSEUDO */
2403
int npixIn; /* number of pixels passed in */
2404
Pixel *ppixIn; /* list of base pixels */
2405
Pixel mask; /* mask client gave us */
2408
Pixel *ppixClient, pixTest;
2409
int npixClient, npixNew, npix;
2410
Pixel bits, base, cmask, rgbbad;
2413
int errVal = Success;
2414
int offset, numents;
2418
Bool anyRefCountReachedZero = 0;
2425
base = lowbit (mask);
2430
cmask = pmap->pVisual->redMask;
2431
rgbbad = ~RGBMASK(pmap->pVisual);
2432
offset = pmap->pVisual->offsetRed;
2433
numents = (cmask >> offset) + 1;
2434
ppixClient = pmap->clientPixelsRed[client];
2435
npixClient = pmap->numPixelsRed[client];
2438
cmask = pmap->pVisual->greenMask;
2439
rgbbad = ~RGBMASK(pmap->pVisual);
2440
offset = pmap->pVisual->offsetGreen;
2441
numents = (cmask >> offset) + 1;
2442
ppixClient = pmap->clientPixelsGreen[client];
2443
npixClient = pmap->numPixelsGreen[client];
2446
cmask = pmap->pVisual->blueMask;
2447
rgbbad = ~RGBMASK(pmap->pVisual);
2448
offset = pmap->pVisual->offsetBlue;
2449
numents = (cmask >> offset) + 1;
2450
ppixClient = pmap->clientPixelsBlue[client];
2451
npixClient = pmap->numPixelsBlue[client];
2453
default: /* so compiler can see that everything gets initialized */
2455
cmask = ~((Pixel)0);
2458
numents = pmap->pVisual->ColormapEntries;
2459
ppixClient = pmap->clientPixelsRed[client];
2460
npixClient = pmap->numPixelsRed[client];
2465
grabbed = LbxCheckCmapGrabbed (pmap);
2470
* If the colormap is grabbed by a proxy, the server must
2471
* notify the proxy of all cells that are freed (the refcount
2472
* has reached zero on these cells).
2475
LbxBeginFreeCellsEvent (pmap);
2476
LbxSortPixelList (ppixIn, npixIn);
2480
/* zap all pixels which match */
2483
/* go through pixel list */
2484
for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
2486
pixTest = ((*pptr | bits) & cmask) >> offset;
2487
if ((pixTest >= numents) || (*pptr & rgbbad))
2489
clientErrorValue = *pptr | bits;
2494
/* find match in client list */
2495
for (cptr = ppixClient, npix = npixClient;
2496
--npix >= 0 && *cptr != pixTest;
2501
if (pmap->class & DynamicClass)
2503
FreeCell(pmap, pixTest, color);
2506
* Only PSEUDO colormaps are grabbed by LBX proxies.
2507
* Check if the ref count reached zero on this pixel.
2510
zeroRefCount = pmap->red[pixTest].refcnt == 0;
2512
anyRefCountReachedZero = 1;
2514
if (grabbed && zeroRefCount)
2515
LbxAddFreeCellToEvent (pmap, pixTest);
2518
*cptr = ~((Pixel)0);
2524
/* generate next bits value */
2525
GetNextBitsOrBreak(bits, mask, base);
2530
LbxEndFreeCellsEvent (pmap);
2531
else if (anyRefCountReachedZero)
2534
* We only send LbxFreeCell events to a proxy that has the colormap
2535
* grabbed. If the colormap is not grabbed, the proxy that last
2536
* had the colormap grabbed will not be able to do a smart grab
2537
* in the future. A smart grab can only occur if the proxy is kept
2538
* up to date on every alloc/free change in the colormap.
2541
LbxDisableSmartGrab (pmap);
2545
/* delete freed pixels from client pixel list */
2548
npixNew = npixClient - zapped;
2551
/* Since the list can only get smaller, we can do a copy in
2552
* place and then realloc to a smaller size */
2553
pptr = cptr = ppixClient;
2555
/* If we have all the new pixels, we don't have to examine the
2556
* rest of the old ones */
2557
for(npix = 0; npix < npixNew; cptr++)
2559
if (*cptr != ~((Pixel)0))
2565
pptr = (Pixel *)xrealloc(ppixClient, npixNew * sizeof(Pixel));
2568
npixClient = npixNew;
2574
ppixClient = (Pixel *)NULL;
2580
pmap->clientPixelsRed[client] = ppixClient;
2581
pmap->numPixelsRed[client] = npixClient;
2584
pmap->clientPixelsGreen[client] = ppixClient;
2585
pmap->numPixelsGreen[client] = npixClient;
2588
pmap->clientPixelsBlue[client] = ppixClient;
2589
pmap->numPixelsBlue[client] = npixClient;
2598
/* Redefine color values */
2600
StoreColors (pmap, count, defs)
2606
register xColorItem *pdef;
2607
register EntryPtr pent, pentT, pentLast;
2608
register VisualPtr pVisual;
2609
SHAREDCOLOR *pred, *pgreen, *pblue;
2610
int n, ChgRed, ChgGreen, ChgBlue, idef;
2611
int class, errVal = Success;
2615
class = pmap->class;
2616
if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
2620
pVisual = pmap->pVisual;
2623
if((class | DynamicClass) == DirectColor)
2625
int numred, numgreen, numblue;
2628
numred = NUMRED(pVisual);
2629
numgreen = NUMGREEN(pVisual);
2630
numblue = NUMBLUE(pVisual);
2631
rgbbad = ~RGBMASK(pVisual);
2632
for (pdef = defs, n = 0; n < count; pdef++, n++)
2635
(*pmap->pScreen->ResolveColor)
2636
(&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
2638
if (pdef->pixel & rgbbad)
2641
clientErrorValue = pdef->pixel;
2644
pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
2650
else if (pmap->red[pix].refcnt != AllocPrivate)
2655
else if (pdef->flags & DoRed)
2657
pmap->red[pix].co.local.red = pdef->red;
2661
pdef->red = pmap->red[pix].co.local.red;
2664
pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
2665
if (pix >= numgreen)
2670
else if (pmap->green[pix].refcnt != AllocPrivate)
2675
else if (pdef->flags & DoGreen)
2677
pmap->green[pix].co.local.green = pdef->green;
2681
pdef->green = pmap->green[pix].co.local.green;
2684
pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
2690
else if (pmap->blue[pix].refcnt != AllocPrivate)
2695
else if (pdef->flags & DoBlue)
2697
pmap->blue[pix].co.local.blue = pdef->blue;
2701
pdef->blue = pmap->blue[pix].co.local.blue;
2703
/* If this is an o.k. entry, then it gets added to the list
2704
* to be sent to the hardware. If not, skip it. Once we've
2705
* skipped one, we have to copy all the others.
2710
defs[idef] = defs[n];
2713
clientErrorValue = pdef->pixel;
2718
for (pdef = defs, n = 0; n < count; pdef++, n++)
2722
if (pdef->pixel >= pVisual->ColormapEntries)
2724
clientErrorValue = pdef->pixel;
2728
else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
2734
/* If this is an o.k. entry, then it gets added to the list
2735
* to be sent to the hardware. If not, skip it. Once we've
2736
* skipped one, we have to copy all the others.
2741
defs[idef] = defs[n];
2747
(*pmap->pScreen->ResolveColor)
2748
(&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
2750
pent = &pmap->red[pdef->pixel];
2752
if(pdef->flags & DoRed)
2756
pent->co.shco.red->color = pdef->red;
2757
if (pent->co.shco.red->refcnt > 1)
2761
pent->co.local.red = pdef->red;
2766
pdef->red = pent->co.shco.red->color;
2768
pdef->red = pent->co.local.red;
2770
if(pdef->flags & DoGreen)
2774
pent->co.shco.green->color = pdef->green;
2775
if (pent->co.shco.green->refcnt > 1)
2779
pent->co.local.green = pdef->green;
2784
pdef->green = pent->co.shco.green->color;
2786
pdef->green = pent->co.local.green;
2788
if(pdef->flags & DoBlue)
2792
pent->co.shco.blue->color = pdef->blue;
2793
if (pent->co.shco.blue->refcnt > 1)
2797
pent->co.local.blue = pdef->blue;
2802
pdef->blue = pent->co.shco.blue->color;
2804
pdef->blue = pent->co.local.blue;
2809
/* have to run through the colormap and change anybody who
2810
* shares this value */
2811
pred = pent->co.shco.red;
2812
pgreen = pent->co.shco.green;
2813
pblue = pent->co.shco.blue;
2814
ChgRed = pdef->flags & DoRed;
2815
ChgGreen = pdef->flags & DoGreen;
2816
ChgBlue = pdef->flags & DoBlue;
2817
pentLast = pmap->red + pVisual->ColormapEntries;
2819
for(pentT = pmap->red; pentT < pentLast; pentT++)
2821
if(pentT->fShared && (pentT != pent))
2825
/* There are, alas, devices in this world too dumb
2826
* to read their own hardware colormaps. Sick, but
2827
* true. So we're going to be really nice and load
2828
* the xColorItem with the proper value for all the
2829
* fields. We will only set the flags for those
2830
* fields that actually change. Smart devices can
2831
* arrange to change only those fields. Dumb devices
2832
* can rest assured that we have provided for them,
2833
* and can change all three fields */
2836
if(ChgRed && pentT->co.shco.red == pred)
2838
defChg.flags |= DoRed;
2840
if(ChgGreen && pentT->co.shco.green == pgreen)
2842
defChg.flags |= DoGreen;
2844
if(ChgBlue && pentT->co.shco.blue == pblue)
2846
defChg.flags |= DoBlue;
2848
if(defChg.flags != 0)
2850
defChg.pixel = pentT - pmap->red;
2851
defChg.red = pentT->co.shco.red->color;
2852
defChg.green = pentT->co.shco.green->color;
2853
defChg.blue = pentT->co.shco.blue->color;
2854
(*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
2862
/* Note that we use idef, the count of acceptable entries, and not
2863
* count, the count of proposed entries */
2865
( *pmap->pScreen->StoreColors) (pmap, idef, defs);
2870
IsMapInstalled(map, pWin)
2875
int imap, nummaps, found;
2877
pmaps = (Colormap *) ALLOCATE_LOCAL(
2878
pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap));
2881
nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
2882
(pWin->drawable.pScreen, pmaps);
2884
for(imap = 0; imap < nummaps; imap++)
2886
if(pmaps[imap] == map)
2892
DEALLOCATE_LOCAL(pmaps);