00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <X11/Xlib.h>
00036 #include <X11/Xatom.h>
00037 #include <X11/Xutil.h>
00038 #include <X11/Xmu/StdCmap.h>
00039 #include <stdlib.h>
00040
00041
00042
00043
00044 static Status lookup(Display*, int, VisualID, Atom, XStandardColormap*, Bool);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 Status
00072 XmuLookupStandardColormap(Display *dpy, int screen, VisualID visualid,
00073 unsigned int depth, Atom property,
00074 Bool replace, Bool retain)
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 {
00085 Display *odpy;
00086 XStandardColormap *colormap;
00087 XVisualInfo vinfo_template, *vinfo;
00088 long vinfo_mask;
00089 unsigned long r_max, g_max, b_max;
00090 int count;
00091 Colormap cmap;
00092 Status status = 0;
00093
00094
00095
00096
00097 vinfo_template.visualid = visualid;
00098 vinfo_template.screen = screen;
00099 vinfo_template.depth = depth;
00100 vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
00101 if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
00102 NULL)
00103 return 0;
00104
00105
00106
00107 if (vinfo->colormap_size <= 2) {
00108 XFree((char *) vinfo);
00109 return 0;
00110 }
00111
00112
00113
00114
00115
00116
00117 if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
00118 replace) && !replace) {
00119 XFree((char *) vinfo);
00120 return 1;
00121 }
00122
00123
00124
00125
00126
00127
00128 if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
00129 XFree((char *) vinfo);
00130 return 0;
00131 }
00132
00133 cmap = (property == XA_RGB_DEFAULT_MAP &&
00134 visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
00135 ? DefaultColormap(dpy, screen) : None;
00136
00137
00138
00139 if (retain) {
00140 odpy = dpy;
00141 if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
00142 XFree((char *) vinfo);
00143 return 0;
00144 }
00145 }
00146
00147
00148
00149 colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
00150 cmap, r_max, g_max, b_max);
00151
00152
00153
00154 if (colormap) {
00155 XGrabServer(dpy);
00156
00157 if (lookup(dpy, screen, visualid, property, colormap, replace) &&
00158 !replace) {
00159
00160
00161
00162
00163
00164 if (colormap->killid == ReleaseByFreeingColormap)
00165 XFreeColormap(dpy, colormap->colormap);
00166 }
00167 else if (retain) {
00168 XSetCloseDownMode(dpy, RetainPermanent);
00169 }
00170 XUngrabServer(dpy);
00171 XFree((char *) colormap);
00172 status = 1;
00173 }
00174
00175 if (retain)
00176 XCloseDisplay(dpy);
00177 XFree((char *) vinfo);
00178 return status;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 static Status
00198 lookup(Display *dpy, int screen, VisualID visualid, Atom property,
00199 XStandardColormap *cnew, Bool replace)
00200
00201
00202
00203
00204
00205
00206
00207
00208 {
00209 register int i;
00210 int count;
00211 XStandardColormap *stdcmaps, *s;
00212 Window win = RootWindow(dpy, screen);
00213
00214
00215
00216 if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
00217 if (cnew)
00218 XSetRGBColormaps(dpy, win, cnew, 1, property);
00219 return 0;
00220 }
00221
00222
00223
00224 if (property != XA_RGB_DEFAULT_MAP) {
00225 if (replace) {
00226 XmuDeleteStandardColormap(dpy, screen, property);
00227 if (cnew)
00228 XSetRGBColormaps(dpy, win, cnew, 1, property);
00229 }
00230 XFree((char *)stdcmaps);
00231 return 1;
00232 }
00233
00234
00235
00236 for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
00237 ;
00238
00239
00240
00241 if (i == count) {
00242 if (cnew) {
00243 XStandardColormap *m, *maps;
00244
00245 s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
00246 (XStandardColormap)));
00247
00248 for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
00249 m->colormap = maps->colormap;
00250 m->red_max = maps->red_max;
00251 m->red_mult = maps->red_mult;
00252 m->green_max = maps->green_max;
00253 m->green_mult = maps->green_mult;
00254 m->blue_max = maps->blue_max;
00255 m->blue_mult = maps->blue_mult;
00256 m->base_pixel = maps->base_pixel;
00257 m->visualid = maps->visualid;
00258 m->killid = maps->killid;
00259 }
00260 m->colormap = cnew->colormap;
00261 m->red_max = cnew->red_max;
00262 m->red_mult = cnew->red_mult;
00263 m->green_max = cnew->green_max;
00264 m->green_mult = cnew->green_mult;
00265 m->blue_max = cnew->blue_max;
00266 m->blue_mult = cnew->blue_mult;
00267 m->base_pixel = cnew->base_pixel;
00268 m->visualid = cnew->visualid;
00269 m->killid = cnew->killid;
00270
00271 XSetRGBColormaps(dpy, win, s, ++count, property);
00272 free((char *) s);
00273 }
00274 XFree((char *) stdcmaps);
00275 return 0;
00276 }
00277
00278
00279
00280 if (replace) {
00281
00282
00283
00284
00285
00286
00287 if (count == 1) {
00288 XmuDeleteStandardColormap(dpy, screen, property);
00289 if (cnew)
00290 XSetRGBColormaps(dpy, win, cnew, 1, property);
00291 }
00292 else {
00293 XStandardColormap *map;
00294
00295
00296
00297 if (s->killid == ReleaseByFreeingColormap) {
00298 if ((s->colormap != None) &&
00299 (s->colormap != DefaultColormap(dpy, screen)))
00300 XFreeColormap(dpy, s->colormap);
00301 }
00302 else if (s->killid != None)
00303 XKillClient(dpy, s->killid);
00304
00305 map = (cnew) ? cnew : stdcmaps + --count;
00306
00307 s->colormap = map->colormap;
00308 s->red_max = map->red_max;
00309 s->red_mult = map->red_mult;
00310 s->green_max = map->green_max;
00311 s->green_mult = map->green_mult;
00312 s->blue_max = map->blue_max;
00313 s->blue_mult = map->blue_mult;
00314 s->visualid = map->visualid;
00315 s->killid = map->killid;
00316
00317 XSetRGBColormaps(dpy, win, stdcmaps, count, property);
00318 }
00319 }
00320 XFree((char *) stdcmaps);
00321 return 1;
00322 }