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 32static void 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 77/* 78 * When the hardware is enabled, save the hardware colors and store 79 * the current colormap 80 */ 81void 82KdEnableColormap(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 101void 102KdDisableColormap(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 */ 126void 127KdInstallColormap(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 */ 155void 156KdUninstallColormap(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 183int 184KdListInstalledColormaps(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 */ 203void 204KdStoreColors(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