kcmap.c revision 6747b715
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_CONFIG_H
24#include <kdrive-config.h>
25#endif
26#include "kdrive.h"
27
28/*
29 * Put the entire colormap into the DAC
30 */
31
32void
33KdSetColormap (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, serverClient);
62
63    for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
64    {
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.depth),
74					     defs);
75
76    /* recolor hardware cursor */
77    if (pScreenPriv->card->cfuncs->recolorCursor)
78	(*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0);
79}
80
81/*
82 * When the hardware is enabled, save the hardware colors and store
83 * the current colormap
84 */
85void
86KdEnableColormap (ScreenPtr pScreen)
87{
88    KdScreenPriv(pScreen);
89    int	    i;
90
91    if (!pScreenPriv->card->cfuncs->putColors)
92	return;
93
94    if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
95    {
96	for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
97	    pScreenPriv->systemPalette[i].pixel = i;
98	(*pScreenPriv->card->cfuncs->getColors) (pScreen,
99						 (1 << pScreenPriv->screen->fb.depth),
100						 pScreenPriv->systemPalette);
101    }
102    KdSetColormap (pScreen);
103}
104
105void
106KdDisableColormap (ScreenPtr pScreen)
107{
108    KdScreenPriv(pScreen);
109
110    if (!pScreenPriv->card->cfuncs->putColors)
111	return;
112
113    if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
114    {
115	(*pScreenPriv->card->cfuncs->putColors) (pScreen,
116						 (1 << pScreenPriv->screen->fb.depth),
117						 pScreenPriv->systemPalette);
118    }
119}
120
121/*
122 * KdInstallColormap
123 *
124 * This function is called when the server receives a request to install a
125 * colormap or when the server needs to install one on its own, like when
126 * there's no window manager running and the user has moved the pointer over
127 * an X client window.  It needs to build an identity Windows palette for the
128 * colormap and realize it into the Windows system palette.
129 */
130void
131KdInstallColormap (ColormapPtr pCmap)
132{
133    KdScreenPriv(pCmap->pScreen);
134
135    if (pCmap == pScreenPriv->pInstalledmap)
136	return;
137
138    /* Tell X clients that the installed colormap is going away. */
139    if (pScreenPriv->pInstalledmap)
140	WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
141		 (pointer) &(pScreenPriv->pInstalledmap->mid));
142
143    /* Take note of the new installed colorscreen-> */
144    pScreenPriv->pInstalledmap = pCmap;
145
146    KdSetColormap (pCmap->pScreen);
147
148    /* Tell X clients of the new colormap */
149    WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
150}
151
152/*
153 * KdUninstallColormap
154 *
155 * This function uninstalls a colormap by either installing
156 * the default X colormap or erasing the installed colormap pointer.
157 * The default X colormap itself cannot be uninstalled.
158 */
159void
160KdUninstallColormap (ColormapPtr pCmap)
161{
162    KdScreenPriv(pCmap->pScreen);
163    Colormap	defMapID;
164    ColormapPtr defMap;
165
166    /* ignore if not installed */
167    if (pCmap != pScreenPriv->pInstalledmap)
168	return;
169
170    /* ignore attempts to uninstall default colormap */
171    defMapID = pCmap->pScreen->defColormap;
172    if ((Colormap) pCmap->mid == defMapID)
173	return;
174
175    /* install default */
176    dixLookupResourceByType((pointer *)&defMap, defMapID, RT_COLORMAP,
177			    serverClient, DixInstallAccess);
178    if (defMap)
179	(*pCmap->pScreen->InstallColormap)(defMap);
180    else
181    {
182	/* uninstall and clear colormap pointer */
183	WalkTree(pCmap->pScreen, TellLostMap,
184		 (pointer) &(pCmap->mid));
185	pScreenPriv->pInstalledmap = 0;
186    }
187}
188
189int
190KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
191{
192    KdScreenPriv(pScreen);
193    int		n = 0;
194
195    if (pScreenPriv->pInstalledmap)
196    {
197	*pCmaps++ = pScreenPriv->pInstalledmap->mid;
198	n++;
199    }
200    return n;
201}
202
203/*
204 * KdStoreColors
205 *
206 * This function is called whenever the server receives a request to store
207 * color values into one or more entries in the currently installed X
208 * colormap; it can be either the default colormap or a private colorscreen->
209 */
210void
211KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
212{
213    KdScreenPriv(pCmap->pScreen);
214    VisualPtr           pVisual;
215    xColorItem          expanddefs[KD_MAX_PSEUDO_SIZE];
216
217    if (pCmap != pScreenPriv->pInstalledmap)
218	return;
219
220    if (!pScreenPriv->card->cfuncs->putColors)
221	return;
222
223    if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
224	return;
225
226    if (!pScreenPriv->enabled)
227	return;
228
229    /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
230    pVisual = pCmap->pVisual;
231    if ((pVisual->class | DynamicClass) == DirectColor)
232    {
233	/*
234	 * Expand DirectColor or TrueColor color values into a PseudoColor
235	 * format.  Defer to the Color Framebuffer (CFB) code to do that.
236	 */
237	ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
238	pdefs = expanddefs;
239    }
240
241    (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
242
243    /* recolor hardware cursor */
244    if (pScreenPriv->card->cfuncs->recolorCursor)
245	(*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs);
246}
247