kcmap.c revision 05b261ec
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, int fb) 34{ 35 KdScreenPriv(pScreen); 36 ColormapPtr pCmap = pScreenPriv->pInstalledmap[fb]; 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[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[fb].depth); i++) 59 pixels[i] = i; 60 61 QueryColors (pCmap, (1 << pScreenPriv->screen->fb[fb].depth), pixels, colors); 62 63 for (i = 0; i < (1 << pScreenPriv->screen->fb[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, fb, 73 (1 << pScreenPriv->screen->fb[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 int fb; 91 Bool done = FALSE; 92 93 if (!pScreenPriv->card->cfuncs->putColors) 94 return; 95 for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) 96 { 97 if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH && !done) 98 { 99 for (i = 0; i < (1 << pScreenPriv->screen->fb[fb].depth); i++) 100 pScreenPriv->systemPalette[i].pixel = i; 101 (*pScreenPriv->card->cfuncs->getColors) (pScreen, fb, 102 (1 << pScreenPriv->screen->fb[fb].depth), 103 pScreenPriv->systemPalette); 104 done = TRUE; 105 } 106 KdSetColormap (pScreen, fb); 107 } 108} 109 110void 111KdDisableColormap (ScreenPtr pScreen) 112{ 113 KdScreenPriv(pScreen); 114 int fb; 115 116 if (!pScreenPriv->card->cfuncs->putColors) 117 return; 118 for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) 119 { 120 if (pScreenPriv->screen->fb[fb].depth <= KD_MAX_PSEUDO_DEPTH) 121 { 122 (*pScreenPriv->card->cfuncs->putColors) (pScreen, fb, 123 (1 << pScreenPriv->screen->fb[fb].depth), 124 pScreenPriv->systemPalette); 125 break; 126 } 127 } 128} 129 130static int 131KdColormapFb (ColormapPtr pCmap) 132{ 133 ScreenPtr pScreen = pCmap->pScreen; 134 KdScreenPriv (pScreen); 135 KdScreenInfo *screen = pScreenPriv->screen; 136 int d; 137 DepthPtr depth; 138 int v; 139 VisualID vid = pCmap->pVisual->vid; 140 int fb; 141 142 if (screen->fb[1].depth) 143 { 144 for (d = 0; d < pScreen->numDepths; d++) 145 { 146 depth = &pScreen->allowedDepths[d]; 147 for (v = 0; v < depth->numVids; v++) 148 { 149 if (depth->vids[v] == vid) 150 { 151 for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) 152 { 153 if (depth->depth == screen->fb[fb].depth) 154 return fb; 155 } 156 } 157 } 158 } 159 } 160 return 0; 161} 162 163/* 164 * KdInstallColormap 165 * 166 * This function is called when the server receives a request to install a 167 * colormap or when the server needs to install one on its own, like when 168 * there's no window manager running and the user has moved the pointer over 169 * an X client window. It needs to build an identity Windows palette for the 170 * colormap and realize it into the Windows system palette. 171 */ 172void 173KdInstallColormap (ColormapPtr pCmap) 174{ 175 KdScreenPriv(pCmap->pScreen); 176 int fb = KdColormapFb (pCmap); 177 178 if (pCmap == pScreenPriv->pInstalledmap[fb]) 179 return; 180 181 /* Tell X clients that the installed colormap is going away. */ 182 if (pScreenPriv->pInstalledmap[fb]) 183 WalkTree(pScreenPriv->pInstalledmap[fb]->pScreen, TellLostMap, 184 (pointer) &(pScreenPriv->pInstalledmap[fb]->mid)); 185 186 /* Take note of the new installed colorscreen-> */ 187 pScreenPriv->pInstalledmap[fb] = pCmap; 188 189 KdSetColormap (pCmap->pScreen, fb); 190 191 /* Tell X clients of the new colormap */ 192 WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid)); 193} 194 195/* 196 * KdUninstallColormap 197 * 198 * This function uninstalls a colormap by either installing 199 * the default X colormap or erasing the installed colormap pointer. 200 * The default X colormap itself cannot be uninstalled. 201 */ 202void 203KdUninstallColormap (ColormapPtr pCmap) 204{ 205 KdScreenPriv(pCmap->pScreen); 206 int fb = KdColormapFb (pCmap); 207 Colormap defMapID; 208 ColormapPtr defMap; 209 210 /* ignore if not installed */ 211 if (pCmap != pScreenPriv->pInstalledmap[fb]) 212 return; 213 214 /* ignore attempts to uninstall default colormap */ 215 defMapID = pCmap->pScreen->defColormap; 216 if ((Colormap) pCmap->mid == defMapID) 217 return; 218 219 /* install default if on same fb */ 220 defMap = (ColormapPtr) LookupIDByType(defMapID, RT_COLORMAP); 221 if (defMap && KdColormapFb (defMap) == fb) 222 (*pCmap->pScreen->InstallColormap)(defMap); 223 else 224 { 225 /* uninstall and clear colormap pointer */ 226 WalkTree(pCmap->pScreen, TellLostMap, 227 (pointer) &(pCmap->mid)); 228 pScreenPriv->pInstalledmap[fb] = 0; 229 } 230} 231 232int 233KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps) 234{ 235 KdScreenPriv(pScreen); 236 int fb; 237 int n = 0; 238 239 for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++) 240 { 241 if (pScreenPriv->pInstalledmap[fb]) 242 { 243 *pCmaps++ = pScreenPriv->pInstalledmap[fb]->mid; 244 n++; 245 } 246 } 247 return n; 248} 249 250/* 251 * KdStoreColors 252 * 253 * This function is called whenever the server receives a request to store 254 * color values into one or more entries in the currently installed X 255 * colormap; it can be either the default colormap or a private colorscreen-> 256 */ 257void 258KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs) 259{ 260 KdScreenPriv(pCmap->pScreen); 261 VisualPtr pVisual; 262 xColorItem expanddefs[KD_MAX_PSEUDO_SIZE]; 263 int fb = KdColormapFb (pCmap); 264 265 if (pCmap != pScreenPriv->pInstalledmap[fb]) 266 return; 267 268 if (!pScreenPriv->card->cfuncs->putColors) 269 return; 270 271 if (pScreenPriv->screen->fb[fb].depth > KD_MAX_PSEUDO_DEPTH) 272 return; 273 274 if (!pScreenPriv->enabled) 275 return; 276 277 /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */ 278 pVisual = pCmap->pVisual; 279 if ((pVisual->class | DynamicClass) == DirectColor) 280 { 281 /* 282 * Expand DirectColor or TrueColor color values into a PseudoColor 283 * format. Defer to the Color Framebuffer (CFB) code to do that. 284 */ 285 ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs); 286 pdefs = expanddefs; 287 } 288 289 (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, fb, ndef, pdefs); 290 291 /* recolor hardware cursor */ 292 if (pScreenPriv->card->cfuncs->recolorCursor) 293 (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs); 294} 295