1/* 2 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. 3 * 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation on the rights to use, copy, modify, merge, 10 * publish, distribute, sublicense, and/or sell copies of the Software, 11 * and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial 16 * portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 * SOFTWARE. 26 */ 27 28/* 29 * Authors: 30 * Kevin E. Martin <kem@redhat.com> 31 * 32 */ 33 34/** \file 35 * Colormap support. */ 36 37#ifdef HAVE_DMX_CONFIG_H 38#include <dmx-config.h> 39#endif 40 41#include "dmx.h" 42#include "dmxlog.h" 43#include "dmxsync.h" 44#include "dmxcmap.h" 45#include "dmxvisual.h" 46 47#include "micmap.h" 48 49static Bool dmxAllocateColormapPrivates(ColormapPtr pColormap) 50{ 51 dmxColormapPrivPtr pCmapPriv; 52 53 pCmapPriv = (dmxColormapPrivPtr)malloc(sizeof(*pCmapPriv)); 54 if (!pCmapPriv) 55 return FALSE; 56 pCmapPriv->cmap = (Colormap)0; 57 58 DMX_SET_COLORMAP_PRIV(pColormap, pCmapPriv); 59 60 return TRUE; 61} 62 63/** Create \a pColormap on the back-end server. */ 64Bool dmxBECreateColormap(ColormapPtr pColormap) 65{ 66 ScreenPtr pScreen = pColormap->pScreen; 67 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 68 dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); 69 VisualPtr pVisual = pColormap->pVisual; 70 Visual *visual = dmxLookupVisual(pScreen, pVisual); 71 72 if (visual) { 73 pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay, 74 dmxScreen->scrnWin, 75 visual, 76 (pVisual->class & DynamicClass ? 77 AllocAll : AllocNone)); 78 return pCmapPriv->cmap != 0; 79 } 80 else { 81 dmxLog(dmxWarning, "dmxBECreateColormap: No visual found\n"); 82 return 0; 83 } 84} 85 86/** Create colormap on back-end server associated with \a pColormap's 87 * screen. */ 88Bool dmxCreateColormap(ColormapPtr pColormap) 89{ 90 ScreenPtr pScreen = pColormap->pScreen; 91 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 92 Bool ret = TRUE; 93 94 if (!dmxAllocateColormapPrivates(pColormap)) 95 return FALSE; 96 97 if (dmxScreen->beDisplay) { 98 if (!dmxBECreateColormap(pColormap)) 99 return FALSE; 100 } 101 102 DMX_UNWRAP(CreateColormap, dmxScreen, pScreen); 103 if (pScreen->CreateColormap) 104 ret = pScreen->CreateColormap(pColormap); 105 DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen); 106 107 return ret; 108} 109 110/** Destroy \a pColormap on the back-end server. */ 111Bool dmxBEFreeColormap(ColormapPtr pColormap) 112{ 113 ScreenPtr pScreen = pColormap->pScreen; 114 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 115 dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); 116 117 if (pCmapPriv->cmap) { 118 XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap); 119 pCmapPriv->cmap = (Colormap)0; 120 return TRUE; 121 } 122 123 return FALSE; 124} 125 126/** Destroy colormap on back-end server associated with \a pColormap's 127 * screen. */ 128void dmxDestroyColormap(ColormapPtr pColormap) 129{ 130 ScreenPtr pScreen = pColormap->pScreen; 131 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 132 dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); 133 134 if (dmxScreen->beDisplay) 135 dmxBEFreeColormap(pColormap); 136 free(pCmapPriv); 137 DMX_SET_COLORMAP_PRIV(pColormap, NULL); 138 139 DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen); 140 if (pScreen->DestroyColormap) 141 pScreen->DestroyColormap(pColormap); 142 DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen); 143} 144 145/** Install colormap on back-end server associated with \a pColormap's 146 * screen. */ 147void dmxInstallColormap(ColormapPtr pColormap) 148{ 149 ScreenPtr pScreen = pColormap->pScreen; 150 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 151 dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); 152 153 DMX_UNWRAP(InstallColormap, dmxScreen, pScreen); 154 if (pScreen->InstallColormap) 155 pScreen->InstallColormap(pColormap); 156 DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen); 157 158 if (dmxScreen->beDisplay) { 159 XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap); 160 dmxSync(dmxScreen, FALSE); 161 } 162} 163 164/** Store colors in \a pColormap on back-end server associated with \a 165 * pColormap's screen. */ 166void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef) 167{ 168 ScreenPtr pScreen = pColormap->pScreen; 169 DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 170 dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); 171 172 if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) { 173 XColor *color = malloc(sizeof(*color) * ndef); 174 int i; 175 176 if (color) { 177 for (i = 0; i < ndef; i++) { 178 color[i].pixel = pdef[i].pixel; 179 color[i].red = pdef[i].red; 180 color[i].blue = pdef[i].blue; 181 color[i].green = pdef[i].green; 182 color[i].flags = pdef[i].flags; 183 color[i].pad = pdef[i].pad; 184 } 185 XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef); 186 free(color); 187 } else { /* xalloc failed, so fallback */ 188 XColor c; 189 for (i = 0; i < ndef; i++) { 190 c.pixel = pdef[i].pixel; 191 c.red = pdef[i].red; 192 c.blue = pdef[i].blue; 193 c.green = pdef[i].green; 194 c.flags = pdef[i].flags; 195 c.pad = pdef[i].pad; 196 XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c); 197 } 198 } 199 dmxSync(dmxScreen, FALSE); 200 } 201 202 DMX_UNWRAP(StoreColors, dmxScreen, pScreen); 203 if (pScreen->StoreColors) 204 pScreen->StoreColors(pColormap, ndef, pdef); 205 DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen); 206} 207 208/** Create the DMX server's default colormap. */ 209Bool dmxCreateDefColormap(ScreenPtr pScreen) 210{ 211 return miCreateDefColormap(pScreen); 212} 213