98N/A/*
98N/A* Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
98N/A*
98N/A* Permission is hereby granted, free of charge, to any person obtaining a
908N/A* copy of this software and associated documentation files (the "Software"),
733N/A* to deal in the Software without restriction, including without limitation
98N/A* the rights to use, copy, modify, merge, publish, distribute, sublicense,
98N/A* and/or sell copies of the Software, and to permit persons to whom the
98N/A* Software is furnished to do so, subject to the following conditions:
98N/A*
98N/A* The above copyright notice and this permission notice (including the next
98N/A* paragraph) shall be included in all copies or substantial portions of the
98N/A* Software.
98N/A*
98N/A* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
98N/A* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
98N/A* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
98N/A* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
98N/A* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
98N/A* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
98N/A* DEALINGS IN THE SOFTWARE.
98N/A*
98N/A*/
98N/A
98N/A
98N/A#include <stdio.h>
98N/A#ifndef SYSV
98N/A#include <alloca.h>
98N/A#endif
98N/A#include <X11/Xlib.h>
98N/A#include <X11/Xatom.h>
98N/A#include "cmc.h"
98N/A#include "cmcutil.h"
98N/A
235N/A#define MIN(a,b) ((a)<(b)?(a):(b))
156N/A
156N/A
156N/Astatic void
156N/Acmc_alloc (
98N/A Screen *screen,
98N/A int ncolors,
98N/A XColor *colors)
98N/A
493N/A{
493N/A register Colormap cmap = DefaultColormapOfScreen(screen);
98N/A register Pixel *p;
911N/A register XColor *c;
911N/A register int nalloc;
911N/A register int total_alloc = 0;
911N/A register int ntotal;
98N/A unsigned long mask;
235N/A Pixel *pixels;
493N/A int nc;
98N/A
98N/A ntotal = 1<<PlanesOfScreen(screen);
98N/A#ifdef SYSV
98N/A pixels = (Pixel *) malloc(ntotal * sizeof(Pixel));
606N/A#else
98N/A pixels = (Pixel *) alloca(ntotal * sizeof(Pixel));
98N/A#endif
98N/A
606N/A /* Grab as many private cells as we can */
606N/A for (nalloc=ntotal, p=pixels; nalloc > 0; nalloc>>=1) {
98N/A if (!XAllocColorCells(DisplayOfScreen(screen), cmap, 0, &mask, 0,
493N/A p, nalloc))
493N/A continue;
493N/A p += nalloc;
98N/A total_alloc += nalloc;
98N/A }
98N/A
98N/A /*
908N/A ** May not be able to get as many colors as requested.
591N/A */
493N/A nc = MIN(ncolors, total_alloc);
493N/A if (nc != ncolors) {
493N/A (void) fprintf(stderr, "Warning: can only allocate %d of the requested %d colors.\n", nc, ncolors);
493N/A (void) fprintf(stderr, "Continuing anyway.\n");
493N/A }
493N/A ncolors = nc;
493N/A
493N/A /* Free enough space for workspace colors */
493N/A nalloc = total_alloc - ncolors;
705N/A XFreeColors(DisplayOfScreen(screen), cmap, pixels+nalloc, ncolors, 0);
493N/A
557N/A /* Allocate the workspace colors */
557N/A for (c=colors+ncolors-1; c>=colors; c--)
493N/A if (!XAllocColor(DisplayOfScreen(screen), cmap, c))
493N/A fatal_error("attempt to allocate color failed");
606N/A
606N/A /* Free placeholder pixels */
851N/A XFreeColors(DisplayOfScreen(screen), cmap, pixels, nalloc, 0);
851N/A
851N/A /*
851N/A ** Tell everybody how many workspace colors there are.
851N/A ** Be sure to include white/black if they're at the
851N/A ** high end.
851N/A */
98N/A { Visual *vis = DefaultVisualOfScreen(screen);
591N/A int cmap_size = vis->map_entries;
910N/A if (WhitePixelOfScreen(screen) == cmap_size-1 ||
851N/A WhitePixelOfScreen(screen) == cmap_size-2)
591N/A ncolors++;
910N/A if (BlackPixelOfScreen(screen) == cmap_size-1 ||
910N/A BlackPixelOfScreen(screen) == cmap_size-2)
910N/A ncolors++;
910N/A prop_update(DisplayOfScreen(screen), RootWindowOfScreen(screen),
910N/A COUNT_PROP_NAME, XA_INTEGER, 32, ncolors, 1);
910N/A }
98N/A#ifdef SYSV
98N/A free(pixels);
910N/A#endif
910N/A}
910N/A
98N/A
606N/Astatic void
98N/Acmc_alloc_protected (screen, ncolors, colors)
606N/AScreen *screen;
98N/Aint ncolors;
591N/AXColor *colors;
851N/A
111N/A{
111N/A XGrabServer(DisplayOfScreen(screen));
111N/A cmc_alloc(screen, ncolors, colors);
111N/A XUngrabServer(DisplayOfScreen(screen));
111N/A}
606N/A
851N/A
851N/A/*
851N/A** For each screen for which there is saved workspace colors,
606N/A** allocates these colors as high as possible in the default
98N/A** colormap of the screen.
851N/A*/
733N/A
733N/Avoid
733N/Acmc_init (void)
733N/A
733N/A{
606N/A Display *dpy;
851N/A FILE *f;
606N/A const char *filename;
98N/A
851N/A /* Open display */
851N/A if (!(dpy = open_display(display_name)))
851N/A fatal_error("cannot open display '%s'\n", display_name);
851N/A
851N/A /* For some strange reason, cmc_alloc_protected fails if not
851N/A run synchronously */
851N/A XSynchronize(dpy, 1);
212N/A
851N/A /* Open file where workspace colors are stored */
606N/A filename = comp_colors_filename(basename_arg);
606N/A if ((f = fopen(filename, "r")) == NULL)
606N/A /* Do nothing if not found */
606N/A return;
212N/A
98N/A /* Check magic number and version */
98N/A cmc_header_test(f);
98N/A
98N/A /* Abandon any previously allocated workspace colors (all screens) */
182N/A resource_discard(dpy);
98N/A
908N/A /* For each screen of display ... */
908N/A for (;;) {
908N/A Screen *screen;
908N/A int scr_num;
908N/A int ncolors;
908N/A XColor *colors;
908N/A
908N/A if (!cmc_read(f, &scr_num, &ncolors, &colors))
908N/A break;
908N/A
908N/A /* See if screen is still present */
908N/A if (scr_num >= ScreenCount(dpy)) {
908N/A warning("Warning: cannot allocated saved colors for screen %d because\nthe display no longer has this many screens\n", scr_num);
908N/A continue;
908N/A }
908N/A screen = ScreenOfDisplay(dpy, scr_num);
908N/A
908N/A /*
908N/A ** Existence of workspace colors for the screen implies
908N/A ** that its default visual was dynamic indexed. Make sure
908N/A ** it still is.
908N/A */
908N/A if (!dynamic_indexed_default_visual(screen)) {
908N/A warning("default visual for screen %d is no longer dynamic indexed\nsaved colors not allocated for screen %d", scr_num, scr_num);
908N/A continue;
908N/A }
908N/A
908N/A /* Allocate workspace colors at high end of colormap */
908N/A cmc_alloc_protected(screen, ncolors, colors);
free((char *)colors);
}
/* Preserve newly allocated client resources */
resource_preserve(dpy);
XCloseDisplay(dpy);
}