initial commit
[profile/ivi/xorg-x11-server.git] / hw / dmx / dmxcmap.c
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 {
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. */
64 Bool 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. */
88 Bool 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. */
111 Bool 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. */
128 void 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. */
147 void 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. */
166 void 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. */
209 Bool dmxCreateDefColormap(ScreenPtr pScreen)
210 {
211     return miCreateDefColormap(pScreen);
212 }