xref: /OK3568_Linux_fs/external/xserver/hw/dmx/dmxcmap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
49 static Bool
dmxAllocateColormapPrivates(ColormapPtr pColormap)50 dmxAllocateColormapPrivates(ColormapPtr pColormap)
51 {
52     dmxColormapPrivPtr pCmapPriv;
53 
54     pCmapPriv = (dmxColormapPrivPtr) malloc(sizeof(*pCmapPriv));
55     if (!pCmapPriv)
56         return FALSE;
57     pCmapPriv->cmap = (Colormap) 0;
58 
59     DMX_SET_COLORMAP_PRIV(pColormap, pCmapPriv);
60 
61     return TRUE;
62 }
63 
64 /** Create \a pColormap on the back-end server. */
65 Bool
dmxBECreateColormap(ColormapPtr pColormap)66 dmxBECreateColormap(ColormapPtr pColormap)
67 {
68     ScreenPtr pScreen = pColormap->pScreen;
69     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
70     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
71     VisualPtr pVisual = pColormap->pVisual;
72     Visual *visual = dmxLookupVisual(pScreen, pVisual);
73 
74     if (visual) {
75         pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
76                                           dmxScreen->scrnWin,
77                                           visual,
78                                           (pVisual->class & DynamicClass ?
79                                            AllocAll : AllocNone));
80         return pCmapPriv->cmap != 0;
81     }
82     else {
83         dmxLog(dmxWarning, "dmxBECreateColormap: No visual found\n");
84         return 0;
85     }
86 }
87 
88 /** Create colormap on back-end server associated with \a pColormap's
89  *  screen. */
90 Bool
dmxCreateColormap(ColormapPtr pColormap)91 dmxCreateColormap(ColormapPtr pColormap)
92 {
93     ScreenPtr pScreen = pColormap->pScreen;
94     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
95     Bool ret = TRUE;
96 
97     if (!dmxAllocateColormapPrivates(pColormap))
98         return FALSE;
99 
100     if (dmxScreen->beDisplay) {
101         if (!dmxBECreateColormap(pColormap))
102             return FALSE;
103     }
104 
105     DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
106     if (pScreen->CreateColormap)
107         ret = pScreen->CreateColormap(pColormap);
108     DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
109 
110     return ret;
111 }
112 
113 /** Destroy \a pColormap on the back-end server. */
114 Bool
dmxBEFreeColormap(ColormapPtr pColormap)115 dmxBEFreeColormap(ColormapPtr pColormap)
116 {
117     ScreenPtr pScreen = pColormap->pScreen;
118     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
119     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
120 
121     if (pCmapPriv->cmap) {
122         XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
123         pCmapPriv->cmap = (Colormap) 0;
124         return TRUE;
125     }
126 
127     return FALSE;
128 }
129 
130 /** Destroy colormap on back-end server associated with \a pColormap's
131  *  screen. */
132 void
dmxDestroyColormap(ColormapPtr pColormap)133 dmxDestroyColormap(ColormapPtr pColormap)
134 {
135     ScreenPtr pScreen = pColormap->pScreen;
136     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
137     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
138 
139     if (dmxScreen->beDisplay)
140         dmxBEFreeColormap(pColormap);
141     free(pCmapPriv);
142     DMX_SET_COLORMAP_PRIV(pColormap, NULL);
143 
144     DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
145     if (pScreen->DestroyColormap)
146         pScreen->DestroyColormap(pColormap);
147     DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
148 }
149 
150 /** Install colormap on back-end server associated with \a pColormap's
151  *  screen. */
152 void
dmxInstallColormap(ColormapPtr pColormap)153 dmxInstallColormap(ColormapPtr pColormap)
154 {
155     ScreenPtr pScreen = pColormap->pScreen;
156     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
157     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
158 
159     DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
160     if (pScreen->InstallColormap)
161         pScreen->InstallColormap(pColormap);
162     DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
163 
164     if (dmxScreen->beDisplay) {
165         XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
166         dmxSync(dmxScreen, FALSE);
167     }
168 }
169 
170 /** Store colors in \a pColormap on back-end server associated with \a
171  *  pColormap's screen. */
172 void
dmxStoreColors(ColormapPtr pColormap,int ndef,xColorItem * pdef)173 dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem * pdef)
174 {
175     ScreenPtr pScreen = pColormap->pScreen;
176     DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
177     dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
178 
179     if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) {
180         XColor *color = xallocarray(ndef, sizeof(*color));
181         int i;
182 
183         if (color) {
184             for (i = 0; i < ndef; i++) {
185                 color[i].pixel = pdef[i].pixel;
186                 color[i].red = pdef[i].red;
187                 color[i].blue = pdef[i].blue;
188                 color[i].green = pdef[i].green;
189                 color[i].flags = pdef[i].flags;
190                 color[i].pad = pdef[i].pad;
191             }
192             XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef);
193             free(color);
194         }
195         else {                  /* xalloc failed, so fallback */
196             XColor c;
197 
198             for (i = 0; i < ndef; i++) {
199                 c.pixel = pdef[i].pixel;
200                 c.red = pdef[i].red;
201                 c.blue = pdef[i].blue;
202                 c.green = pdef[i].green;
203                 c.flags = pdef[i].flags;
204                 c.pad = pdef[i].pad;
205                 XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c);
206             }
207         }
208         dmxSync(dmxScreen, FALSE);
209     }
210 
211     DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
212     if (pScreen->StoreColors)
213         pScreen->StoreColors(pColormap, ndef, pdef);
214     DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
215 }
216 
217 /** Create the DMX server's default colormap. */
218 Bool
dmxCreateDefColormap(ScreenPtr pScreen)219 dmxCreateDefColormap(ScreenPtr pScreen)
220 {
221     return miCreateDefColormap(pScreen);
222 }
223