kcmap.c revision 35c4bbdf
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,
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    /* 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        for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
96            pScreenPriv->systemPalette[i].pixel = i;
97        (*pScreenPriv->card->cfuncs->getColors) (pScreen,
98                                                 (1 << pScreenPriv->screen->fb.
99                                                  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        (*pScreenPriv->card->cfuncs->putColors) (pScreen,
115                                                 (1 << pScreenPriv->screen->fb.
116                                                  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                 (void *) &(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, (void *) &(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((void **) &defMap, defMapID, RT_COLORMAP,
177                            serverClient, DixInstallAccess);
178    if (defMap)
179        (*pCmap->pScreen->InstallColormap) (defMap);
180    else {
181        /* uninstall and clear colormap pointer */
182        WalkTree(pCmap->pScreen, TellLostMap, (void *) &(pCmap->mid));
183        pScreenPriv->pInstalledmap = 0;
184    }
185}
186
187int
188KdListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmaps)
189{
190    KdScreenPriv(pScreen);
191    int n = 0;
192
193    if (pScreenPriv->pInstalledmap) {
194        *pCmaps++ = pScreenPriv->pInstalledmap->mid;
195        n++;
196    }
197    return n;
198}
199
200/*
201 * KdStoreColors
202 *
203 * This function is called whenever the server receives a request to store
204 * color values into one or more entries in the currently installed X
205 * colormap; it can be either the default colormap or a private colorscreen->
206 */
207void
208KdStoreColors(ColormapPtr pCmap, int ndef, xColorItem * pdefs)
209{
210    KdScreenPriv(pCmap->pScreen);
211    VisualPtr pVisual;
212    xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
213
214    if (pCmap != pScreenPriv->pInstalledmap)
215        return;
216
217    if (!pScreenPriv->card->cfuncs->putColors)
218        return;
219
220    if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
221        return;
222
223    if (!pScreenPriv->enabled)
224        return;
225
226    /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
227    pVisual = pCmap->pVisual;
228    if ((pVisual->class | DynamicClass) == DirectColor) {
229        /*
230         * Expand DirectColor or TrueColor color values into a PseudoColor
231         * format.  Defer to the Color Framebuffer (CFB) code to do that.
232         */
233        ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
234        pdefs = expanddefs;
235    }
236
237    (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
238
239    /* recolor hardware cursor */
240    if (pScreenPriv->card->cfuncs->recolorCursor)
241        (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef,
242                                                     pdefs);
243}
244