2 * Copyright (c) 1990, 2015, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
31 #include <X11/Xlibint.h>
36 #define CELL_READONLY 1
40 ** Handle I/O errors when opening display
43 static int badaccess_error
;
46 ** Handle X request errors.
47 ** Just set a flag to let the routine making an X
48 ** call know that the call resulted in a BadAccess error.
49 ** Any other errors are processed normally.
57 if (err
->error_code
== BadAccess
)
60 return _XDefaultError(dpy
,err
);
66 ** Examines the given colormap to determine the number of
67 ** read-only cells, their locations, and their color values.
69 ** All non-read-only cells (privately allocated, unallocated
70 ** or reserved) are ignored.
79 register Colormap cmap
= DefaultColormapOfScreen(screen
);
80 register int i
, nalloc
;
84 unsigned long masks
; /* NOTUSED */
89 /* start out assuming all are read-only */
90 totalpix
= 1<<PlanesOfScreen(screen
);
92 /* allocate local scratch memory */
94 if (!(pixels
= (Pixel
*) malloc(totalpix
* sizeof(Pixel
))))
95 fatal_error("cannot allocate memory ");
96 if (!(pixtype
= (int *) malloc(totalpix
* sizeof(Pixel
))))
97 fatal_error("cannot allocate memory ");
99 if (!(pixels
= (Pixel
*) alloca(totalpix
* sizeof(Pixel
))))
100 fatal_error("cannot allocate memory on stack");
101 if (!(pixtype
= (int *) alloca(totalpix
* sizeof(Pixel
))))
102 fatal_error("cannot allocate memory on stack");
104 for (i
=0, p
=pixtype
; i
<totalpix
; i
++, p
++)
109 ** First, find the free cells by allocating them all private.
110 ** We allocate by decreasing powers of 2 so the allocation
111 ** time will be proportional to the number of display planes
112 ** instead of the number of display cells.
114 ** Mark the free cells we find. These allocations will
115 ** be freed when the connection is closed.
117 for (nalloc
=totalpix
; nalloc
> 0; nalloc
>>= 1) {
118 if(!XAllocColorCells(DisplayOfScreen(screen
), cmap
, 0, &masks
, 0,
121 for (i
=0; i
<nalloc
; i
++) {
122 pixtype
[pixels
[i
]] = CELL_IGNORE
;
128 ** Find the read-only cells (excluding white/black).
130 ** Get the Hardware color for the color of each allocated cell.
131 ** This can only work if the returned color is a previously
132 ** allocated r/o cell (we have all cells allocated).
134 XSetErrorHandler(bad_handler
);
135 for(i
=0, p
=pixtype
; i
<totalpix
; i
++, p
++) {
136 if(*p
!= CELL_IGNORE
) {
139 /* Eliminate reserved cells */
141 XQueryColor(DisplayOfScreen(screen
), cmap
, &color
);
142 XSync(DisplayOfScreen(screen
), 0); /* make sure any error is reported */
143 if (badaccess_error
) {
144 pixtype
[color
.pixel
] = CELL_IGNORE
;
148 XStoreColor(DisplayOfScreen(screen
), cmap
, &color
);
149 if (!badaccess_error
) {
150 /* Eliminate read/write cells */
151 pixtype
[color
.pixel
] = CELL_IGNORE
;
153 } else if (WHITE(&color
) || BLACK(&color
)) {
154 /* Eliminate white/black cells */
155 pixtype
[color
.pixel
] = CELL_IGNORE
;
158 /* else if alloc succeeded, it must be read-only */
162 XSync(DisplayOfScreen(screen
), 0);
163 XSetErrorHandler(NULL
);
165 /* allocate the memory for the read-only cells */
166 if (!(*colors
= (XColor
*) calloc(*ncolors
, sizeof(XColor
))))
167 fatal_error("not enough memory");
170 ** Get the color values for the read-only cells, ignoring private
171 ** cells, reserved cells, and white/black.
173 for (i
=0, c
=*colors
; i
<totalpix
; i
++) {
174 if (pixtype
[i
] != CELL_IGNORE
) {
178 XQueryColors(DisplayOfScreen(screen
), cmap
, *colors
, *ncolors
);
187 ** Examines the default colormap with the server grabbed
188 ** to prevent changes during the examination process.
192 cmc_record_protected (
197 XGrabServer(DisplayOfScreen(screen
));
198 cmc_record(screen
, ncolors
, colors
);
199 XUngrabServer(DisplayOfScreen(screen
));
204 ** For each screen for which the default colormap is dynamic indexed
205 ** record all read-only color cells in the default colormap.
211 register int scr_num
;
214 const char *filename
;
217 if (!(dpy
= open_display(display_name
)))
218 fatal_error("cannot open display '%s'", display_name
);
220 /* For some strange reason, colorscells_get_protected fails if not
222 XSynchronize(dpy
, 1);
224 /* Open file to save in */
225 filename
= comp_colors_filename(basename_arg
);
226 if ((f
= fopen(filename
, "w")) == NULL
)
227 fatal_error("cannot open file '%s' for writing", filename
);
229 /* Save magic number and version */
232 /* For each screen of display ... */
233 for (scr_num
= 0; scr_num
< ScreenCount(dpy
); scr_num
++) {
234 Screen
*screen
= ScreenOfDisplay(dpy
, scr_num
);
238 /* Do nothing if default visual is not dynamic */
239 if (!dynamic_indexed_default_visual(screen
)) {
241 warning("default visual for screen %d is not dynamic indexed",
243 warning("no colors saved for screen %d", scr_num
);
249 ** Discover what read-only cells are in the default colormap.
251 ** These will be considered the "workspace colors."
253 cmc_record_protected(screen
, &ncolors
, &colors
);
255 /* Save read-only cells for screen in workspace color file */
256 if (!cmc_write(f
, scr_num
, ncolors
, colors
))
257 fatal_error("cannot write to file %s", filename
);
259 free((char *)colors
);