~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to wrlib/LookupCmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XConsortium: LookupCmap.c,v 1.10 94/04/17 20:16:11 rws Exp $ */
 
2
 
 
3
/*
 
4
 
 
5
Copyright (c) 1989  X Consortium
 
6
 
 
7
Permission is hereby granted, free of charge, to any person obtaining a copy
 
8
of this software and associated documentation files (the "Software"), to deal
 
9
in the Software without restriction, including without limitation the rights
 
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
11
copies of the Software, and to permit persons to whom the Software is
 
12
furnished to do so, subject to the following conditions:
 
13
 
 
14
The above copyright notice and this permission notice shall be included in
 
15
all copies or substantial portions of the Software.
 
16
 
 
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
20
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
21
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
22
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 
 
24
Except as contained in this notice, the name of the X Consortium shall not be
 
25
used in advertising or otherwise to promote the sale, use or other dealings
 
26
in this Software without prior written authorization from the X Consortium.
 
27
 
 
28
*/
 
29
 
 
30
/*
 
31
 * Author:  Donna Converse, MIT X Consortium
 
32
 */
 
33
 
 
34
#include <stdlib.h>
 
35
#include <stdio.h>
 
36
#include <X11/Xlib.h>
 
37
#include <X11/Xatom.h>
 
38
#include <X11/Xutil.h>
 
39
#include "StdCmap.h"
 
40
 
 
41
 
 
42
static Status lookup();
 
43
 
 
44
/*
 
45
 * To create a standard colormap if one does not currently exist, or
 
46
 * replace the currently existing standard colormap, use
 
47
 * XmuLookupStandardColormap().
 
48
 *
 
49
 * Given a screen, a visual, and a property, XmuLookupStandardColormap()
 
50
 * will determine the best allocation for the property under the specified
 
51
 * visual, and determine the whether to create a new colormap or to use
 
52
 * the default colormap of the screen.  It will call XmuStandardColormap()
 
53
 * to create the standard colormap.
 
54
 *
 
55
 * If replace is true, any previous definition of the property will be
 
56
 * replaced.  If retain is true, the property and the colormap will be
 
57
 * made permanent for the duration of the server session.  However,
 
58
 * pre-existing property definitions which are not replaced cannot be made
 
59
 * permanent by a call to XmuLookupStandardColormap(); a request to retain
 
60
 * resources pertains to newly created resources.
 
61
 *
 
62
 * Returns 0 on failure, non-zero on success.  A request to create a
 
63
 * standard colormap upon a visual which cannot support such a map is
 
64
 * considered a failure.  An example of this would be requesting any
 
65
 * standard colormap property on a monochrome visual, or, requesting an
 
66
 * RGB_BEST_MAP on a display whose colormap size is 16.
 
67
 */
 
68
 
 
69
Status XmuLookupStandardColormap(dpy, screen, visualid, depth, property,
 
70
                                 replace, retain)
 
71
    Display             *dpy;           /* specifies X server connection */
 
72
    int                 screen;         /* specifies screen of display */
 
73
    VisualID            visualid;       /* specifies the visual type */
 
74
    unsigned int        depth;          /* specifies  the visual type */
 
75
    Atom                property;       /* a standard colormap property */
 
76
    Bool                replace;        /* specifies whether to replace */
 
77
    Bool                retain;         /* specifies whether to retain */
 
78
{
 
79
    Display             *odpy;          /* original display connection */
 
80
    XStandardColormap   *colormap;
 
81
    XVisualInfo         vinfo_template, *vinfo; /* visual */
 
82
    long                vinfo_mask;
 
83
    unsigned long       r_max, g_max, b_max;    /* allocation */
 
84
    int                 count;
 
85
    Colormap            cmap;                   /* colormap ID */
 
86
    Status              status = 0;
 
87
 
 
88
 
 
89
    /* Match the requested visual */
 
90
 
 
91
    vinfo_template.visualid = visualid;
 
92
    vinfo_template.screen = screen;
 
93
    vinfo_template.depth = depth;
 
94
    vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
 
95
    if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
 
96
        NULL)
 
97
        return 0;
 
98
 
 
99
    /* Monochrome visuals have no standard maps */
 
100
 
 
101
    if (vinfo->colormap_size <= 2) {
 
102
        XFree((char *) vinfo);
 
103
        return 0;
 
104
    }
 
105
 
 
106
    /* If the requested property already exists on this screen, and,
 
107
     * if the replace flag has not been set to true, return success.
 
108
     * lookup() will remove a pre-existing map if replace is true.
 
109
     */
 
110
 
 
111
    if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
 
112
               replace) && !replace) {
 
113
        XFree((char *) vinfo);
 
114
        return 1;
 
115
    }
 
116
 
 
117
    /* Determine the best allocation for this property under the requested
 
118
     * visualid and depth, and determine whether or not to use the default
 
119
     * colormap of the screen.
 
120
     */
 
121
 
 
122
    if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
 
123
        XFree((char *) vinfo);
 
124
        return 0;
 
125
    }
 
126
 
 
127
    cmap = (property == XA_RGB_DEFAULT_MAP &&
 
128
            visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
 
129
        ? DefaultColormap(dpy, screen) : None;
 
130
 
 
131
    /* If retaining resources, open a new connection to the same server */
 
132
 
 
133
    if (retain) {
 
134
        odpy = dpy;
 
135
        if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
 
136
            XFree((char *) vinfo);
 
137
            return 0;
 
138
        }
 
139
    }
 
140
 
 
141
    /* Create the standard colormap */
 
142
 
 
143
    colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
 
144
                                   cmap, r_max, g_max, b_max);
 
145
 
 
146
    /* Set the standard colormap property */
 
147
 
 
148
    if (colormap) {
 
149
        XGrabServer(dpy);
 
150
 
 
151
        if (lookup(dpy, screen, visualid, property, colormap, replace) &&
 
152
            !replace) {
 
153
            /* Someone has defined the property since we last looked.
 
154
             * Since we will not replace it, release our own resources.
 
155
             * If this is the default map, our allocations will be freed
 
156
             * when this connection closes.
 
157
             */
 
158
            if (colormap->killid == ReleaseByFreeingColormap)
 
159
                XFreeColormap(dpy, colormap->colormap);
 
160
        }
 
161
        else if (retain) {
 
162
            XSetCloseDownMode(dpy, RetainPermanent);
 
163
        }
 
164
        XUngrabServer(dpy);
 
165
        XFree((char *) colormap);
 
166
        status = 1;
 
167
    }
 
168
 
 
169
    if (retain)
 
170
        XCloseDisplay(dpy);
 
171
    XFree((char *) vinfo);
 
172
    return status;
 
173
}
 
174
 
 
175
/***************************************************************************/
 
176
 
 
177
/* Lookup a standard colormap property.  If the property is RGB_DEFAULT_MAP,
 
178
 * the visualid is used to determine whether the indicated standard colormap
 
179
 * exists.  If the map exists and replace is true, delete the resources used
 
180
 * by the map and remove the property.  Return true if the map exists,
 
181
 * or did exist and was deleted; return false if the map was not found.
 
182
 *
 
183
 * Note that this is not the way that a Status return is normally used.
 
184
 *
 
185
 * If new is not NULL, new points to an XStandardColormap structure which
 
186
 * describes a standard colormap of the specified property.  It will be made
 
187
 * a standard colormap of the screen if none already exists, or if replace
 
188
 * is true.
 
189
 */
 
190
 
 
191
static Status lookup(dpy, screen, visualid, property, new, replace)
 
192
    Display             *dpy;           /* specifies display connection */
 
193
    int                 screen;         /* specifies screen number */
 
194
    VisualID            visualid;       /* specifies visualid for std map */
 
195
    Atom                property;       /* specifies colormap property name */
 
196
    XStandardColormap   *new;           /* specifies a standard colormap */
 
197
    Bool                replace;        /* specifies whether to replace */
 
198
{
 
199
    register int        i;
 
200
    int                 count;
 
201
    XStandardColormap   *stdcmaps, *s;
 
202
    Window              win = RootWindow(dpy, screen);
 
203
 
 
204
    /* The property does not already exist */
 
205
 
 
206
    if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
 
207
        if (new)
 
208
            XSetRGBColormaps(dpy, win, new, 1, property);
 
209
        return 0;
 
210
    }
 
211
 
 
212
    /* The property exists and is not describing the RGB_DEFAULT_MAP */
 
213
 
 
214
    if (property != XA_RGB_DEFAULT_MAP) {
 
215
        if (replace) {
 
216
            XmuDeleteStandardColormap(dpy, screen, property);
 
217
            if (new)
 
218
                XSetRGBColormaps(dpy, win, new, 1, property);
 
219
        }
 
220
        XFree((char *)stdcmaps);
 
221
        return 1;
 
222
    }
 
223
 
 
224
    /* The property exists and is RGB_DEFAULT_MAP */
 
225
 
 
226
    for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
 
227
        ;
 
228
 
 
229
    /* No RGB_DEFAULT_MAP property matches the given visualid */
 
230
 
 
231
    if (i == count) {
 
232
        if (new) {
 
233
            XStandardColormap   *m, *maps;
 
234
 
 
235
            s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
 
236
                                                         (XStandardColormap)));
 
237
 
 
238
            for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
 
239
                m->colormap   = maps->colormap;
 
240
                m->red_max    = maps->red_max;
 
241
                m->red_mult   = maps->red_mult;
 
242
                m->green_max  = maps->green_max;
 
243
                m->green_mult = maps->green_mult;
 
244
                m->blue_max   = maps->blue_max;
 
245
                m->blue_mult  = maps->blue_mult;
 
246
                m->base_pixel = maps->base_pixel;
 
247
                m->visualid   = maps->visualid;
 
248
                m->killid     = maps->killid;
 
249
            }
 
250
            m->colormap   = new->colormap;
 
251
            m->red_max    = new->red_max;
 
252
            m->red_mult   = new->red_mult;
 
253
            m->green_max  = new->green_max;
 
254
            m->green_mult = new->green_mult;
 
255
            m->blue_max   = new->blue_max;
 
256
            m->blue_mult  = new->blue_mult;
 
257
            m->base_pixel = new->base_pixel;
 
258
            m->visualid   = new->visualid;
 
259
            m->killid     = new->killid;
 
260
 
 
261
            XSetRGBColormaps(dpy, win, s, ++count, property);
 
262
            free((char *) s);
 
263
        }
 
264
        XFree((char *) stdcmaps);
 
265
        return 0;
 
266
    }
 
267
 
 
268
    /* Found an RGB_DEFAULT_MAP property with a matching visualid */
 
269
 
 
270
    if (replace) {
 
271
        /* Free old resources first - we may need them, particularly in
 
272
         * the default colormap of the screen.  However, because of this,
 
273
         * it is possible that we will destroy the old resource and fail
 
274
         * to create a new one if XmuStandardColormap() fails.
 
275
         */
 
276
 
 
277
        if (count == 1) {
 
278
            XmuDeleteStandardColormap(dpy, screen, property);
 
279
            if (new)
 
280
                XSetRGBColormaps(dpy, win, new, 1, property);
 
281
        }
 
282
        else {
 
283
            XStandardColormap   *map;
 
284
 
 
285
            /* s still points to the matching standard colormap */
 
286
 
 
287
            if (s->killid == ReleaseByFreeingColormap) {
 
288
                if ((s->colormap != None) &&
 
289
                    (s->colormap != DefaultColormap(dpy, screen)))
 
290
                    XFreeColormap(dpy, s->colormap);
 
291
            }
 
292
            else if (s->killid != None)
 
293
                XKillClient(dpy, s->killid);
 
294
 
 
295
            map = (new) ? new : stdcmaps + --count;
 
296
 
 
297
            s->colormap   = map->colormap;
 
298
            s->red_max    = map->red_max;
 
299
            s->red_mult   = map->red_mult;
 
300
            s->green_max  = map->green_max;
 
301
            s->green_mult = map->green_mult;
 
302
            s->blue_max   = map->blue_max;
 
303
            s->blue_mult  = map->blue_mult;
 
304
            s->visualid   = map->visualid;
 
305
            s->killid     = map->killid;
 
306
 
 
307
            XSetRGBColormaps(dpy, win, stdcmaps, count, property);
 
308
        }
 
309
    }
 
310
    XFree((char *) stdcmaps);
 
311
    return 1;
 
312
}
 
313