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