open-src/app/cmap_compact/sun-src/cmcutil.c
author X gate hg captive account <xhg@xserver.us.oracle.com>
Wed, 19 Aug 2015 13:48:41 -0700
changeset 1484 bc8922b8e1d2
parent 1233 1134c9fd2fe6
permissions -rw-r--r--
Added tag s11u3_30 for changeset 221e9d9cc9cb

/*
* Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/


#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "cmcutil.h"
#include "cmc.h"


/*
** Common utility routines shared by the Workspace Colors programs
** cmcsave, cmcshow, cmcinit.
*/

/*ARGSUSED*/
static int 
disp_err_handler (Display *dpy)

{
	fatal_error("cannot open display \"%s\"", display_name);
}

/*
** Open display and handle any errors.
*/

Display *
open_display (dpyname)
char	*dpyname;

{
	Display *dpy;

	/*
	**  Catch errors opening display so user doesn't
	**  get confusing 'XIOError: Broken Pipe' message.
	*/
	XSetIOErrorHandler(disp_err_handler); 

	display_name = XDisplayName(dpyname);
	if (!(dpy = XOpenDisplay(dpyname))) 
		return NULL;

	XSync(dpy, 0);
	XSetIOErrorHandler(NULL); 

	return dpy;
}


/*
** Return true if default visual of screen is dynamic.
*/

int
dynamic_indexed_default_visual (screen)
Screen	*screen;

{
	int class = DefaultVisualOfScreen(screen)->class;

	return (class == GrayScale 	||
	        class == PseudoColor);
}

/*
** If file name is not already absolute, make absolute
** relative to home directory.
*/

static const char *
fn_absolutize (const char *relname)

{
	static char 	filename[256];
	const char	*homedir;

	if (*relname == '/') 
		return relname;

	if (!(homedir = (char *) getenv("HOME")))
		homedir = "/";
	sprintf(filename, "%s/%s", homedir, relname);
	return filename;
}


const char *
comp_colors_filename (const char *basename)

{
	if (!basename)
		basename = COMPACTED_COLORS_FILE;
	return fn_absolutize(basename);

}

int
cmc_write (
    FILE	*f,
    int		scr_num,
    int		ncolors,
    XColor	*colors)

{
	(void)fwrite(&scr_num, sizeof(int), 1, f);
	(void)fwrite(&ncolors, sizeof(int), 1, f);
	(void)fwrite(colors, sizeof(XColor), ncolors, f);

	return 1;
}


/*
** 0 is returned on EOF; 1 otherwise
*/

int
cmc_read (
    FILE	*f,
    int		*scr_num,
    int		*ncolors,
    XColor	**colors)

{
	if (!fread(scr_num, sizeof(int), 1, f)) 
		return 0;

	if (!fread(ncolors, sizeof(int), 1, f)) {
		fprintf(stderr, "error: premature end-of-file\n");
		fatal_error("cannot read number of saved colors");
	}

	if (!(*colors = (XColor *) malloc(*ncolors * sizeof(XColor)))) 
		fatal_error("not enough memory");

	if (!fread(*colors, sizeof(XColor), *ncolors, f)) {
		fprintf(stderr, "error: premature end-of-file\n");
		fatal_error("cannot read saved colors");
	}

	return 1;
}


void
cmc_header_write (
    FILE	*f)

{
	int	value;
	
	/* write magic number and version */
	value = CMC_MAGIC;
	(void)fwrite(&value, sizeof(int), 1, f);
	value = CMC_VERSION;
	(void)fwrite(&value, sizeof(int), 1, f);
}


void
cmc_header_test (
    FILE	*f)

{
	int	value;
	
	/* check magic number */
	if (!fread(&value, sizeof(int), 1, f) ||
	    value != CMC_MAGIC)
		fatal_error("Unrecognized colors file.  Expected magic number = %x,  \
Actual = %x", CMC_MAGIC, value);

	/* check version number */
	if (!fread(&value, sizeof(int), 1, f) ||
	    value != CMC_VERSION)
		fatal_error("Unrecognized colors file.  Expected version number = %x,  \
Actual = %x", CMC_VERSION, value);
}


void
prop_update (
    Display	*dpy,
    Window	w,
    const char	*name,
    Atom	type,
    int		format,
    int		data,
    int		nelem)

{
	/* intern the property name */
	Atom	atom = XInternAtom(dpy, name, 0);

	/* create or replace the property */
	XChangeProperty(dpy, w, atom, type, format, PropModeReplace, 
		(unsigned char *)&data, nelem);
}


/*
** Sets the close-down mode of the cmc client to 'RetainPermanent'
** so all client resources will be preserved after the client
** exits.  Puts a property on the default root window containing
** an XID of the client so that the resources can later be killed.
*/

void
resource_preserve (
    Display	*dpy)

{
	Window	w = DefaultRootWindow(dpy);

	/* create dummy resource */
	Pixmap	pm = XCreatePixmap(dpy, w, 1, 1, 1);
	
	/* create/replace the property */
	prop_update(dpy, w, RETAIN_PROP_NAME, XA_PIXMAP, 32, (int)pm, 1);
	
	/* retain all client resources until explicitly killed */
	XSetCloseDownMode(dpy, RetainPermanent);
}


/*
** Flushes any resources previously retained by a cmc client,
** if any exist.
*/

void
resource_discard (
    Display	*dpy)

{
	Pixmap	*pm;			
	Atom	actual_type;		/* NOTUSED */
	int	format;
	unsigned long	nitems;
	unsigned long	bytes_after;

	/* intern the property name */
	Atom	atom = XInternAtom(dpy, RETAIN_PROP_NAME, 0);

	/* look for existing resource allocation */
	if (XGetWindowProperty(dpy, DefaultRootWindow(dpy), atom, 0, 1,
		1/*delete*/, AnyPropertyType, &actual_type, &format, &nitems,
		&bytes_after, (unsigned char **) &pm) == Success
	    && nitems == 1) {

		if (actual_type == XA_PIXMAP && format == 32 &&
		    nitems == 1 && bytes_after == 0) {
			/* blast it away */
			XKillClient(dpy, *pm);
			XFree(pm);
		} else if (actual_type != None) {
		    extern char *program;
		    fprintf(stderr, "%s: warning: invalid format encountered for property %s\n",
				 RETAIN_PROP_NAME, program);
		}
	}
}