xref: /OK3568_Linux_fs/external/xserver/hw/kdrive/src/kcmap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 1999 Keith Packard
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that
7*4882a593Smuzhiyun  * copyright notice and this permission notice appear in supporting
8*4882a593Smuzhiyun  * documentation, and that the name of Keith Packard not be used in
9*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
10*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
11*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
12*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
24*4882a593Smuzhiyun #include <dix-config.h>
25*4882a593Smuzhiyun #endif
26*4882a593Smuzhiyun #include "kdrive.h"
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun  * Put the entire colormap into the DAC
30*4882a593Smuzhiyun  */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun static void
KdSetColormap(ScreenPtr pScreen)33*4882a593Smuzhiyun KdSetColormap(ScreenPtr pScreen)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun     KdScreenPriv(pScreen);
36*4882a593Smuzhiyun     ColormapPtr pCmap = pScreenPriv->pInstalledmap;
37*4882a593Smuzhiyun     Pixel pixels[KD_MAX_PSEUDO_SIZE];
38*4882a593Smuzhiyun     xrgb colors[KD_MAX_PSEUDO_SIZE];
39*4882a593Smuzhiyun     xColorItem defs[KD_MAX_PSEUDO_SIZE];
40*4882a593Smuzhiyun     int i;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun     if (!pScreenPriv->card->cfuncs->putColors)
43*4882a593Smuzhiyun         return;
44*4882a593Smuzhiyun     if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
45*4882a593Smuzhiyun         return;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun     if (!pScreenPriv->enabled)
48*4882a593Smuzhiyun         return;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun     if (!pCmap)
51*4882a593Smuzhiyun         return;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun     /*
54*4882a593Smuzhiyun      * Make DIX convert pixels into RGB values -- this handles
55*4882a593Smuzhiyun      * true/direct as well as pseudo/static visuals
56*4882a593Smuzhiyun      */
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun     for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
59*4882a593Smuzhiyun         pixels[i] = i;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun     QueryColors(pCmap, (1 << pScreenPriv->screen->fb.depth), pixels, colors,
62*4882a593Smuzhiyun                 serverClient);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun     for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++) {
65*4882a593Smuzhiyun         defs[i].pixel = i;
66*4882a593Smuzhiyun         defs[i].red = colors[i].red;
67*4882a593Smuzhiyun         defs[i].green = colors[i].green;
68*4882a593Smuzhiyun         defs[i].blue = colors[i].blue;
69*4882a593Smuzhiyun         defs[i].flags = DoRed | DoGreen | DoBlue;
70*4882a593Smuzhiyun     }
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun     (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
73*4882a593Smuzhiyun                                              (1 << pScreenPriv->screen->fb.
74*4882a593Smuzhiyun                                               depth), defs);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /*
78*4882a593Smuzhiyun  * When the hardware is enabled, save the hardware colors and store
79*4882a593Smuzhiyun  * the current colormap
80*4882a593Smuzhiyun  */
81*4882a593Smuzhiyun void
KdEnableColormap(ScreenPtr pScreen)82*4882a593Smuzhiyun KdEnableColormap(ScreenPtr pScreen)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun     KdScreenPriv(pScreen);
85*4882a593Smuzhiyun     int i;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun     if (!pScreenPriv->card->cfuncs->putColors)
88*4882a593Smuzhiyun         return;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun     if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH) {
91*4882a593Smuzhiyun         for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
92*4882a593Smuzhiyun             pScreenPriv->systemPalette[i].pixel = i;
93*4882a593Smuzhiyun         (*pScreenPriv->card->cfuncs->getColors) (pScreen,
94*4882a593Smuzhiyun                                                  (1 << pScreenPriv->screen->fb.
95*4882a593Smuzhiyun                                                   depth),
96*4882a593Smuzhiyun                                                  pScreenPriv->systemPalette);
97*4882a593Smuzhiyun     }
98*4882a593Smuzhiyun     KdSetColormap(pScreen);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun void
KdDisableColormap(ScreenPtr pScreen)102*4882a593Smuzhiyun KdDisableColormap(ScreenPtr pScreen)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun     KdScreenPriv(pScreen);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     if (!pScreenPriv->card->cfuncs->putColors)
107*4882a593Smuzhiyun         return;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun     if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH) {
110*4882a593Smuzhiyun         (*pScreenPriv->card->cfuncs->putColors) (pScreen,
111*4882a593Smuzhiyun                                                  (1 << pScreenPriv->screen->fb.
112*4882a593Smuzhiyun                                                   depth),
113*4882a593Smuzhiyun                                                  pScreenPriv->systemPalette);
114*4882a593Smuzhiyun     }
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun /*
118*4882a593Smuzhiyun  * KdInstallColormap
119*4882a593Smuzhiyun  *
120*4882a593Smuzhiyun  * This function is called when the server receives a request to install a
121*4882a593Smuzhiyun  * colormap or when the server needs to install one on its own, like when
122*4882a593Smuzhiyun  * there's no window manager running and the user has moved the pointer over
123*4882a593Smuzhiyun  * an X client window.  It needs to build an identity Windows palette for the
124*4882a593Smuzhiyun  * colormap and realize it into the Windows system palette.
125*4882a593Smuzhiyun  */
126*4882a593Smuzhiyun void
KdInstallColormap(ColormapPtr pCmap)127*4882a593Smuzhiyun KdInstallColormap(ColormapPtr pCmap)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun     KdScreenPriv(pCmap->pScreen);
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun     if (pCmap == pScreenPriv->pInstalledmap)
132*4882a593Smuzhiyun         return;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun     /* Tell X clients that the installed colormap is going away. */
135*4882a593Smuzhiyun     if (pScreenPriv->pInstalledmap)
136*4882a593Smuzhiyun         WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
137*4882a593Smuzhiyun                  (void *) &(pScreenPriv->pInstalledmap->mid));
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun     /* Take note of the new installed colorscreen-> */
140*4882a593Smuzhiyun     pScreenPriv->pInstalledmap = pCmap;
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun     KdSetColormap(pCmap->pScreen);
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun     /* Tell X clients of the new colormap */
145*4882a593Smuzhiyun     WalkTree(pCmap->pScreen, TellGainedMap, (void *) &(pCmap->mid));
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /*
149*4882a593Smuzhiyun  * KdUninstallColormap
150*4882a593Smuzhiyun  *
151*4882a593Smuzhiyun  * This function uninstalls a colormap by either installing
152*4882a593Smuzhiyun  * the default X colormap or erasing the installed colormap pointer.
153*4882a593Smuzhiyun  * The default X colormap itself cannot be uninstalled.
154*4882a593Smuzhiyun  */
155*4882a593Smuzhiyun void
KdUninstallColormap(ColormapPtr pCmap)156*4882a593Smuzhiyun KdUninstallColormap(ColormapPtr pCmap)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun     KdScreenPriv(pCmap->pScreen);
159*4882a593Smuzhiyun     Colormap defMapID;
160*4882a593Smuzhiyun     ColormapPtr defMap;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun     /* ignore if not installed */
163*4882a593Smuzhiyun     if (pCmap != pScreenPriv->pInstalledmap)
164*4882a593Smuzhiyun         return;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun     /* ignore attempts to uninstall default colormap */
167*4882a593Smuzhiyun     defMapID = pCmap->pScreen->defColormap;
168*4882a593Smuzhiyun     if ((Colormap) pCmap->mid == defMapID)
169*4882a593Smuzhiyun         return;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun     /* install default */
172*4882a593Smuzhiyun     dixLookupResourceByType((void **) &defMap, defMapID, RT_COLORMAP,
173*4882a593Smuzhiyun                             serverClient, DixInstallAccess);
174*4882a593Smuzhiyun     if (defMap)
175*4882a593Smuzhiyun         (*pCmap->pScreen->InstallColormap) (defMap);
176*4882a593Smuzhiyun     else {
177*4882a593Smuzhiyun         /* uninstall and clear colormap pointer */
178*4882a593Smuzhiyun         WalkTree(pCmap->pScreen, TellLostMap, (void *) &(pCmap->mid));
179*4882a593Smuzhiyun         pScreenPriv->pInstalledmap = 0;
180*4882a593Smuzhiyun     }
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun int
KdListInstalledColormaps(ScreenPtr pScreen,Colormap * pCmaps)184*4882a593Smuzhiyun KdListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmaps)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun     KdScreenPriv(pScreen);
187*4882a593Smuzhiyun     int n = 0;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun     if (pScreenPriv->pInstalledmap) {
190*4882a593Smuzhiyun         *pCmaps++ = pScreenPriv->pInstalledmap->mid;
191*4882a593Smuzhiyun         n++;
192*4882a593Smuzhiyun     }
193*4882a593Smuzhiyun     return n;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /*
197*4882a593Smuzhiyun  * KdStoreColors
198*4882a593Smuzhiyun  *
199*4882a593Smuzhiyun  * This function is called whenever the server receives a request to store
200*4882a593Smuzhiyun  * color values into one or more entries in the currently installed X
201*4882a593Smuzhiyun  * colormap; it can be either the default colormap or a private colorscreen->
202*4882a593Smuzhiyun  */
203*4882a593Smuzhiyun void
KdStoreColors(ColormapPtr pCmap,int ndef,xColorItem * pdefs)204*4882a593Smuzhiyun KdStoreColors(ColormapPtr pCmap, int ndef, xColorItem * pdefs)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun     KdScreenPriv(pCmap->pScreen);
207*4882a593Smuzhiyun     VisualPtr pVisual;
208*4882a593Smuzhiyun     xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun     if (pCmap != pScreenPriv->pInstalledmap)
211*4882a593Smuzhiyun         return;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun     if (!pScreenPriv->card->cfuncs->putColors)
214*4882a593Smuzhiyun         return;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun     if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
217*4882a593Smuzhiyun         return;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun     if (!pScreenPriv->enabled)
220*4882a593Smuzhiyun         return;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun     /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
223*4882a593Smuzhiyun     pVisual = pCmap->pVisual;
224*4882a593Smuzhiyun     if ((pVisual->class | DynamicClass) == DirectColor) {
225*4882a593Smuzhiyun         /*
226*4882a593Smuzhiyun          * Expand DirectColor or TrueColor color values into a PseudoColor
227*4882a593Smuzhiyun          * format.  Defer to the Color Framebuffer (CFB) code to do that.
228*4882a593Smuzhiyun          */
229*4882a593Smuzhiyun         ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
230*4882a593Smuzhiyun         pdefs = expanddefs;
231*4882a593Smuzhiyun     }
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun     (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
234*4882a593Smuzhiyun }
235