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