]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbcmap.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbcmap.c
1 /* $XConsortium: cfbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
2 /* $XFree86: xc/programs/Xserver/cfb/cfbcmap.c,v 3.1.8.2 1997/05/11 05:04:17 dawes Exp $ */
3 /************************************************************
4 Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
5
6                     All Rights Reserved
7
8 Permission  to  use,  copy,  modify,  and  distribute   this
9 software  and  its documentation for any purpose and without
10 fee is hereby granted, provided that the above copyright no-
11 tice  appear  in all copies and that both that copyright no-
12 tice and this permission notice appear in  supporting  docu-
13 mentation,  and  that the names of Sun or X Consortium
14 not be used in advertising or publicity pertaining to 
15 distribution  of  the software  without specific prior 
16 written permission. Sun and X Consortium make no 
17 representations about the suitability of this software for 
18 any purpose. It is provided "as is" without any express or 
19 implied warranty.
20
21 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
22 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
23 NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
24 ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
25 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
26 PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
27 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
28 THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
30 ********************************************************/
31
32
33 #include "X.h"
34 #include "Xproto.h"
35 #include "scrnintstr.h"
36 #include "colormapst.h"
37 #include "resource.h"
38
39 #ifdef GLXEXT
40 #ifdef GLX_MODULE
41 Bool (*GlxInitVisualsPtr)(
42 #else
43 extern Bool GlxInitVisuals(
44 #endif
45 #if NeedFunctionPrototypes
46     VisualPtr *         /*visualp*/,
47     DepthPtr *          /*depthp*/,
48     int *               /*nvisualp*/,
49     int *               /*ndepthp*/,
50     int *               /*rootDepthp*/,
51     VisualID *          /*defaultVisp*/,
52     unsigned long       /*sizes*/,
53     int                 /*bitsPerRGB*/
54 #endif
55 #ifdef GLX_MODULE
56 ) = NULL;
57 #else
58 );
59 #endif
60 #endif
61
62 #ifdef  STATIC_COLOR
63
64 static ColormapPtr InstalledMaps[MAXSCREENS];
65
66 int
67 cfbListInstalledColormaps(pScreen, pmaps)
68     ScreenPtr   pScreen;
69     Colormap    *pmaps;
70 {
71     /* By the time we are processing requests, we can guarantee that there
72      * is always a colormap installed */
73     *pmaps = InstalledMaps[pScreen->myNum]->mid;
74     return (1);
75 }
76
77
78 void
79 cfbInstallColormap(pmap)
80     ColormapPtr pmap;
81 {
82     int index = pmap->pScreen->myNum;
83     ColormapPtr oldpmap = InstalledMaps[index];
84
85     if(pmap != oldpmap)
86     {
87         /* Uninstall pInstalledMap. No hardware changes required, just
88          * notify all interested parties. */
89         if(oldpmap != (ColormapPtr)None)
90             WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
91         /* Install pmap */
92         InstalledMaps[index] = pmap;
93         WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
94
95     }
96 }
97
98 void
99 cfbUninstallColormap(pmap)
100     ColormapPtr pmap;
101 {
102     int index = pmap->pScreen->myNum;
103     ColormapPtr curpmap = InstalledMaps[index];
104
105     if(pmap == curpmap)
106     {
107         if (pmap->mid != pmap->pScreen->defColormap)
108         {
109             curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
110                                                    RT_COLORMAP);
111             (*pmap->pScreen->InstallColormap)(curpmap);
112         }
113     }
114 }
115
116 #endif
117
118 void
119 cfbResolveColor(pred, pgreen, pblue, pVisual)
120     unsigned short      *pred, *pgreen, *pblue;
121     register VisualPtr  pVisual;
122 {
123     int shift = 16 - pVisual->bitsPerRGBValue;
124     unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
125
126     if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
127     {
128         /* rescale to rgb bits */
129         *pred = ((*pred >> shift) * 65535) / lim;
130         *pgreen = ((*pgreen >> shift) * 65535) / lim;
131         *pblue = ((*pblue >> shift) * 65535) / lim;
132     }
133     else if (pVisual->class == GrayScale)
134     {
135         /* rescale to gray then rgb bits */
136         *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
137         *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
138     }
139     else if (pVisual->class == StaticGray)
140     {
141         unsigned limg = pVisual->ColormapEntries - 1;
142         /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
143         *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
144         *pred = ((((*pred * (limg + 1))) >> 16) * 65535) / limg;
145         *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
146     }
147     else
148     {
149         unsigned limr, limg, limb;
150
151         limr = pVisual->redMask >> pVisual->offsetRed;
152         limg = pVisual->greenMask >> pVisual->offsetGreen;
153         limb = pVisual->blueMask >> pVisual->offsetBlue;
154         /* rescale to [0..limN] then [0..65535] then rgb bits */
155         *pred = ((((((*pred * (limr + 1)) >> 16) *
156                     65535) / limr) >> shift) * 65535) / lim;
157         *pgreen = ((((((*pgreen * (limg + 1)) >> 16) *
158                       65535) / limg) >> shift) * 65535) / lim;
159         *pblue = ((((((*pblue * (limb + 1)) >> 16) *
160                      65535) / limb) >> shift) * 65535) / lim;
161     }
162 }
163
164 Bool
165 cfbInitializeColormap(pmap)
166     register ColormapPtr        pmap;
167 {
168     register unsigned i;
169     register VisualPtr pVisual;
170     unsigned lim, maxent, shift;
171
172     pVisual = pmap->pVisual;
173     lim = (1 << pVisual->bitsPerRGBValue) - 1;
174     shift = 16 - pVisual->bitsPerRGBValue;
175     maxent = pVisual->ColormapEntries - 1;
176     if (pVisual->class == TrueColor)
177     {
178         unsigned limr, limg, limb;
179
180         limr = pVisual->redMask >> pVisual->offsetRed;
181         limg = pVisual->greenMask >> pVisual->offsetGreen;
182         limb = pVisual->blueMask >> pVisual->offsetBlue;
183         for(i = 0; i <= maxent; i++)
184         {
185             /* rescale to [0..65535] then rgb bits */
186             pmap->red[i].co.local.red =
187                 ((((i * 65535) / limr) >> shift) * 65535) / lim;
188             pmap->green[i].co.local.green =
189                 ((((i * 65535) / limg) >> shift) * 65535) / lim;
190             pmap->blue[i].co.local.blue =
191                 ((((i * 65535) / limb) >> shift) * 65535) / lim;
192         }
193     }
194     else if (pVisual->class == StaticColor)
195     {
196         unsigned limr, limg, limb;
197
198         limr = pVisual->redMask >> pVisual->offsetRed;
199         limg = pVisual->greenMask >> pVisual->offsetGreen;
200         limb = pVisual->blueMask >> pVisual->offsetBlue;
201         for(i = 0; i <= maxent; i++)
202         {
203             /* rescale to [0..65535] then rgb bits */
204             pmap->red[i].co.local.red =
205                 ((((((i & pVisual->redMask) >> pVisual->offsetRed)
206                     * 65535) / limr) >> shift) * 65535) / lim;
207             pmap->red[i].co.local.green =
208                 ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
209                     * 65535) / limg) >> shift) * 65535) / lim;
210             pmap->red[i].co.local.blue =
211                 ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
212                     * 65535) / limb) >> shift) * 65535) / lim;
213         }
214     }
215     else if (pVisual->class == StaticGray)
216     {
217         for(i = 0; i <= maxent; i++)
218         {
219             /* rescale to [0..65535] then rgb bits */
220             pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
221                                          * 65535) / lim;
222             pmap->red[i].co.local.green = pmap->red[i].co.local.red;
223             pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
224         }
225     }
226     return TRUE;
227 }
228
229 /* When simulating DirectColor on PseudoColor hardware, multiple
230    entries of the colormap must be updated
231  */
232
233 #define AddElement(mask) { \
234     pixel = red | green | blue; \
235     for (i = 0; i < nresult; i++) \
236         if (outdefs[i].pixel == pixel) \
237             break; \
238     if (i == nresult) \
239     { \
240         nresult++; \
241         outdefs[i].pixel = pixel; \
242         outdefs[i].flags = 0; \
243     } \
244     outdefs[i].flags |= (mask); \
245     outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
246     outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
247     outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
248 }
249
250 cfbExpandDirectColors (pmap, ndef, indefs, outdefs)
251     ColormapPtr pmap;
252     int         ndef;
253     xColorItem  *indefs, *outdefs;
254 {
255     int             minred, mingreen, minblue;
256     register int    red, green, blue;
257     int             maxred, maxgreen, maxblue;
258     int             stepred, stepgreen, stepblue;
259     VisualPtr       pVisual;
260     register int    pixel;
261     register int    nresult;
262     register int    i;
263
264     pVisual = pmap->pVisual;
265
266     stepred = 1 << pVisual->offsetRed;
267     stepgreen = 1 << pVisual->offsetGreen;
268     stepblue = 1 << pVisual->offsetBlue;
269     maxred = pVisual->redMask;
270     maxgreen = pVisual->greenMask;
271     maxblue = pVisual->blueMask;
272     nresult = 0;
273     for (;ndef--; indefs++)
274     {
275         if (indefs->flags & DoRed)
276         {
277             red = indefs->pixel & pVisual->redMask;
278             for (green = 0; green <= maxgreen; green += stepgreen)
279             {
280                 for (blue = 0; blue <= maxblue; blue += stepblue)
281                 {
282                     AddElement (DoRed)
283                 }
284             }
285         }
286         if (indefs->flags & DoGreen)
287         {
288             green = indefs->pixel & pVisual->greenMask;
289             for (red = 0; red <= maxred; red += stepred)
290             {
291                 for (blue = 0; blue <= maxblue; blue += stepblue)
292                 {
293                     AddElement (DoGreen)
294                 }
295             }
296         }
297         if (indefs->flags & DoBlue)
298         {
299             blue = indefs->pixel & pVisual->blueMask;
300             for (red = 0; red <= maxred; red += stepred)
301             {
302                 for (green = 0; green <= maxgreen; green += stepgreen)
303                 {
304                     AddElement (DoBlue)
305                 }
306             }
307         }
308     }
309     return nresult;
310 }
311
312 Bool
313 cfbCreateDefColormap(pScreen)
314     ScreenPtr pScreen;
315 {
316     unsigned short      zero = 0, ones = 0xFFFF;
317     VisualPtr   pVisual;
318     ColormapPtr cmap;
319     Pixel wp, bp;
320     
321     for (pVisual = pScreen->visuals;
322          pVisual->vid != pScreen->rootVisual;
323          pVisual++)
324         ;
325
326     if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
327                        (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
328                        0)
329         != Success)
330         return FALSE;
331     wp = pScreen->whitePixel;
332     bp = pScreen->blackPixel;
333     if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
334            Success) ||
335         (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
336            Success))
337         return FALSE;
338     pScreen->whitePixel = wp;
339     pScreen->blackPixel = bp;
340     (*pScreen->InstallColormap)(cmap);
341     return TRUE;
342 }
343
344 extern int defaultColorVisualClass;
345
346 #define _RZ(d) ((d + 2) / 3)
347 #define _RS(d) 0
348 #define _RM(d) ((1 << _RZ(d)) - 1)
349 #define _GZ(d) ((d - _RZ(d) + 1) / 2)
350 #define _GS(d) _RZ(d)
351 #define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
352 #define _BZ(d) (d - _RZ(d) - _GZ(d))
353 #define _BS(d) (_RZ(d) + _GZ(d))
354 #define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
355 #define _CE(d) (1 << _RZ(d))
356
357 #define MAX_PSEUDO_DEPTH    10      /* largest DAC size I know */
358
359 #define StaticGrayMask  (1 << StaticGray)
360 #define GrayScaleMask   (1 << GrayScale)
361 #define StaticColorMask (1 << StaticColor)
362 #define PseudoColorMask (1 << PseudoColor)
363 #define TrueColorMask   (1 << TrueColor)
364 #define DirectColorMask (1 << DirectColor)
365
366 #define ALL_VISUALS     (StaticGrayMask|\
367                          GrayScaleMask|\
368                          StaticColorMask|\
369                          PseudoColorMask|\
370                          TrueColorMask|\
371                          DirectColorMask)
372
373 #define LARGE_VISUALS   (TrueColorMask|\
374                          DirectColorMask)
375
376 typedef struct _cfbVisuals {
377     struct _cfbVisuals  *next;
378     int                 depth;
379     int                 bitsPerRGB;
380     int                 visuals;
381     int                 count;
382 } cfbVisualsRec, *cfbVisualsPtr;
383
384 static int  cfbVisualPriority[] = {
385     PseudoColor, DirectColor, GrayScale, StaticColor, TrueColor, StaticGray
386 };
387
388 #define NUM_PRIORITY    6
389
390 static cfbVisualsPtr    cfbVisuals;
391
392 Bool
393 cfbSetVisualTypes (depth, visuals, bitsPerRGB)
394     int     depth;
395     int     visuals;
396 {
397     cfbVisualsPtr   new, *prev, v;
398     int             count;
399
400     new = (cfbVisualsPtr) xalloc (sizeof *new);
401     if (!new)
402         return FALSE;
403     new->next = 0;
404     new->depth = depth;
405     new->visuals = visuals;
406     new->bitsPerRGB = bitsPerRGB;
407     count = (visuals >> 1) & 033333333333;
408     count = visuals - count - ((count >> 1) & 033333333333);
409     count = (((count + (count >> 3)) & 030707070707) % 077);    /* HAKMEM 169 */
410     new->count = count;
411     for (prev = &cfbVisuals; v = *prev; prev = &v->next);
412     *prev = new;
413     return TRUE;
414 }
415
416 /*
417  * Given a list of formats for a screen, create a list
418  * of visuals and depths for the screen which coorespond to
419  * the set which can be used with this version of cfb.
420  */
421
422 Bool
423 cfbInitVisuals (visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, sizes, bitsPerRGB)
424     VisualPtr   *visualp;
425     DepthPtr    *depthp;
426     int         *nvisualp, *ndepthp;
427     int         *rootDepthp;
428     VisualID    *defaultVisp;
429     unsigned long   sizes;
430     int         bitsPerRGB;
431 {
432     int         i, j, k;
433     VisualPtr   visual;
434     DepthPtr    depth;
435     VisualID    *vid;
436     int         d, b;
437     int         f;
438     int         ndepth, nvisual;
439     int         nvtype;
440     int         vtype;
441     VisualID    defaultVisual;
442     cfbVisualsPtr   visuals, nextVisuals;
443
444     /* none specified, we'll guess from pixmap formats */
445     if (!cfbVisuals) 
446     {
447         for (f = 0; f < screenInfo.numPixmapFormats; f++) 
448         {
449             d = screenInfo.formats[f].depth;
450             b = screenInfo.formats[f].bitsPerPixel;
451             if (sizes & (1 << (b - 1)))
452             {
453                 if (d > MAX_PSEUDO_DEPTH)
454                     vtype = LARGE_VISUALS;
455                 else if (d == 1)
456                     vtype = StaticGrayMask;
457                 else
458                     vtype = ALL_VISUALS;
459             }
460             else
461                 vtype = 0;
462             if (!cfbSetVisualTypes (d, vtype, bitsPerRGB))
463                 return FALSE;
464         }
465     }
466     nvisual = 0;
467     ndepth = 0;
468     for (visuals = cfbVisuals; visuals; visuals = nextVisuals) 
469     {
470         nextVisuals = visuals->next;
471         ndepth++;
472         nvisual += visuals->count;
473     }
474     depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
475     visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
476     if (!depth || !visual)
477     {
478         xfree (depth);
479         xfree (visual);
480         return FALSE;
481     }
482     *depthp = depth;
483     *visualp = visual;
484     *ndepthp = ndepth;
485     *nvisualp = nvisual;
486     for (visuals = cfbVisuals; visuals; visuals = nextVisuals) 
487     {
488         nextVisuals = visuals->next;
489         d = visuals->depth;
490         vtype = visuals->visuals;
491         nvtype = visuals->count;
492         vid = NULL;
493         if (nvtype)
494         {
495             vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
496             if (!vid)
497                 return FALSE;
498         }
499         depth->depth = d;
500         depth->numVids = nvtype;
501         depth->vids = vid;
502         depth++;
503         for (i = 0; i < NUM_PRIORITY; i++) {
504             if (! (vtype & (1 << cfbVisualPriority[i])))
505                 continue;
506             visual->class = cfbVisualPriority[i];
507             visual->bitsPerRGBValue = visuals->bitsPerRGB;
508             visual->ColormapEntries = 1 << d;
509             visual->nplanes = d;
510             visual->vid = *vid = FakeClientID (0);
511             switch (visual->class) {
512             case PseudoColor:
513             case GrayScale:
514             case StaticGray:
515                 visual->redMask = 0;
516                 visual->greenMask =  0;
517                 visual->blueMask =  0;
518                 visual->offsetRed  =  0;
519                 visual->offsetGreen = 0;
520                 visual->offsetBlue =  0;
521                 break;
522             case DirectColor:
523             case TrueColor:
524                 visual->ColormapEntries = _CE(d);
525                 /* fall through */
526             case StaticColor:
527                 visual->redMask =  _RM(d);
528                 visual->greenMask =  _GM(d);
529                 visual->blueMask =  _BM(d);
530                 visual->offsetRed  =  _RS(d);
531                 visual->offsetGreen = _GS(d);
532                 visual->offsetBlue =  _BS(d);
533             }
534             vid++;
535             visual++;
536         }
537         xfree (visuals);
538     }
539     cfbVisuals = NULL;
540     visual = *visualp;
541     depth = *depthp;
542     for (i = 0; i < ndepth; i++)
543     {
544         if (*rootDepthp && *rootDepthp != depth[i].depth)
545             continue;
546         for (j = 0; j < depth[i].numVids; j++)
547         {
548             for (k = 0; k < nvisual; k++)
549                 if (visual[k].vid == depth[i].vids[j])
550                     break;
551             if (k == nvisual)
552                 continue;
553             if (defaultColorVisualClass < 0 ||
554                 visual[k].class == defaultColorVisualClass)
555                 break;
556         }
557         if (j != depth[i].numVids)
558             break;
559     }
560     if (i == ndepth) {
561         i = 0;
562         j = 0;
563     }
564     *rootDepthp = depth[i].depth;
565     *defaultVisp = depth[i].vids[j];
566
567 #ifdef GLXEXT
568 #ifdef GLX_MODULE
569     if( GlxInitVisualsPtr != NULL ) 
570        return (*GlxInitVisualsPtr)
571 #else
572     return GlxInitVisuals
573 #endif
574            (
575                visualp, 
576                depthp,
577                nvisualp,
578                ndepthp,
579                rootDepthp,
580                defaultVisp,
581                sizes,
582                bitsPerRGB
583            );
584 #else
585     return TRUE;
586 #endif
587
588 }