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