open-src/app/xcolor/sun-src/xcolor.c
author Alan Coopersmith <Alan.Coopersmith@Oracle.COM>
Wed, 28 Apr 2010 18:08:17 -0700
changeset 943 294f64612d23
parent 919 425233ae7236
child 1131 7dc974a70bc8
permissions -rw-r--r--
6948254 Mass update of X gate sources to Oracle copyright format

/*-
 * xcolor.c - X11 client to display all colors in current colormap.
 *
 * Copyright (c) 1989, 1995, 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.
 *
 * Author: Patrick J. Naughton
 * [email protected]
 */


#include <stdio.h>
#include <math.h>
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

#define DEFX 256
#define DEFY 256
#define DEFW 128
#define DEFH 128

#define ICON_WIDTH 48
#define ICON_HEIGHT 48

Display    *dsp = NULL;		/* current display (must be inited) */
int         screen;
Visual	    *visual;
Window      win;		/* window used to cover screen */
Window	    icon;
GC	    gc;			/* graphics context */
int         height = 0,
            width = 0;
Colormap    cmap;
char       *pname;
Atom	    ATOM_WM_PROTOCOLS;
Atom	    ATOM_WM_DELETE_WINDOW;

int    	    cmap_size;


void
error(s1, s2)
    char       *s1,
               *s2;
{
    fprintf(stderr, s1, pname, s2);
    exit(1);
}

dumpCmap()
{
    register int i;
    XColor      color[256];

    for (i = 0; i < 256; i++)
	color[i].pixel = i;
    XQueryColors(dsp, DefaultColormap(dsp, screen), color, 256);
    for (i = 0; i < 256; i++) {
	printf("/name%02x	%3d %3d %3d RGBcolor def\n",
	      i, color[i].red >> 8, color[i].green >> 8, color[i].blue >> 8);
    }
}

redisplay_indexed(window)
    Window window;
{
    int		 max;
    register int i,
                 j;
    register float fw;
    register float fh;

    switch (cmap_size) {
        case   2:   max = 2;   break;
        case  16:   max = 4;   break; 
        case 256:   max = 16;  break;
        default:    max = (int)sqrt((double)cmap_size);
    }

    if (window == win) {
	fw = (float) width / (float)max;
	fh = (float) height / (float)max;
    } else {
	fw = (float) ICON_WIDTH / (float)max;
	fh = (float) ICON_HEIGHT / (float)max;
    }

    for (i = 0; i < max; i++) {
	register int y = (int) (i * fh);
	register int h = (i + 1) * fh - y;
	for (j = 0; j < max; j++) {
	    register int x = (int) (j * fw);
	    register int w = (j + 1) * fw - x;
	    XSetForeground(dsp, gc, i * max + j);
	    XFillRectangle(dsp, window, gc, x, y, w, h);
	}
    }
}


redisplay_direct(window)
    Window window;
{
    register int i,
                j, k;
    register float fw;
    register float fh;
    static int roffset, goffset, boffset;
    static int got_offsets = 0;

    if (window == win) {
	fw = (float) width / 16.0;
	fh = (float) height / (3 * 16.0);
    } else {
	fw = (float) ICON_WIDTH / 16.0;
	fh = (float) ICON_HEIGHT / (3 * 16.0);
    }

    if (!got_offsets) {
	got_offsets = 1;
	roffset = ffs(visual->red_mask)-1;
	goffset = ffs(visual->green_mask)-1;
	boffset = ffs(visual->blue_mask)-1;
    }

    /* red channel */
    k = 0;
    for (i = 0; i < 16; i++, k++) {
	register int y = (int) (k * fh);
	register int h = (k + 1) * fh - y;
	for (j = 0; j < 16; j++) {
	    register int x = (int) (j * fw);
	    register int w = (j + 1) * fw - x;
	    XSetForeground(dsp, gc, (i * 16 + j)<<roffset);
	    XFillRectangle(dsp, window, gc, x, y, w, h);
	}
    }

    /* green channel */
    for (i = 0; i < 16; i++, k++) {
	register int y = (int) (k * fh);
	register int h = (k + 1) * fh - y;
	for (j = 0; j < 16; j++) {
	    register int x = (int) (j * fw);
	    register int w = (j + 1) * fw - x;
	    XSetForeground(dsp, gc, (i * 16 + j)<<goffset);
	    XFillRectangle(dsp, window, gc, x, y, w, h);
	}
    }

    /* blue channel */
    for (i = 0; i < 16; i++, k++) {
	register int y = (int) (k * fh);
	register int h = (k + 1) * fh - y;
	for (j = 0; j < 16; j++) {
	    register int x = (int) (j * fw);
	    register int w = (j + 1) * fw - x;
	    XSetForeground(dsp, gc, (i * 16 + j)<<boffset);
	    XFillRectangle(dsp, window, gc, x, y, w, h);
	}
    }
}


redisplay (w)
    Window w;
{
    if (visual->class == TrueColor || visual->class == DirectColor)
	    redisplay_direct(w);
    else
	    redisplay_indexed(w);
}


HandleEvents()
{
    XEvent      event;
    XConfigureEvent *xce = (XConfigureEvent *) & event;
    XKeyEvent  *xke = (XKeyEvent *) & event;

    while (1) {
	XNextEvent(dsp, &event);
	switch (event.type) {
	case Expose:
	    redisplay(event.xexpose.window);
	    continue;
	case GraphicsExpose:
	case NoExpose:
	case MapNotify:
	case UnmapNotify:
	    continue;
	case ConfigureNotify:
	    if ((height == xce->height) && (width == xce->width))
		continue;
	    height = xce->height;
	    width = xce->width;
	    redisplay(event.xconfigure.window);
	    continue;
	case KeyPress:
	    switch (XLookupKeysym(xke, 0)) {
	    case XK_Escape:
		return;
	    default:
		continue;
	    }
	case ClientMessage:
	    if (event.xclient.message_type == ATOM_WM_PROTOCOLS &&
		event.xclient.format == 32 &&
		event.xclient.data.l[0] == ATOM_WM_DELETE_WINDOW)
	    {
		return;
	    }
	    continue;
	}
    }
}


main(argc, argv)
    int         argc;
    char       *argv[];
{
    XSetWindowAttributes xswa;
    XGCValues   xgcv;
    XSizeHints  size_hints;
    XWMHints	wmhints;
    int         i;
    int         geomStat;
    char       *geom = NULL;
    char       *displayName = NULL;
    Status      stat;
    int         dump = 0;
    int		nobw = 0;
    int		half = 0;
    int		install = 1;
    int		mask;
    int		useiconwin = 0;
    
    if (getenv("_SYNC")) { 
	extern int _Xdebug;
	_Xdebug = 1;
    }

    pname = argv[0];
    for (i = 1; i < argc; i++) {
	if (!strcmp(argv[i], "-geometry"))
	    geom = argv[++i];
	else if (!strcmp(argv[i], "-display"))
	    displayName = argv[++i];
	else if (!strcmp(argv[i], "-dump"))
	    dump = 1;
	else if (!strcmp(argv[i], "-nobw"))
	    nobw = 1;
	else if (!strcmp(argv[i], "-half"))
	    half = 1;
	else if (!strcmp(argv[i], "-noinst"))
	    install = 0;
	else if (!strcmp(argv[i], "-iconwin"))
	    useiconwin = 1;
	else
	    error("usage:  %s [-display dpystr] [-geometry geomstr]\n\
\t[-dump] [-nobw] [-half] [-noinst] [-iconwin]\n", NULL);
    }

    /* SUNSOFT_BUYBACK
    if (!(dsp = XOpenDisplay(displayName)))
	error("%s: unable to open display, %s.\n", displayName);
    **********/
    if (!(dsp = XOpenDisplay(displayName))) {
	if (displayName)
	    error("%s: unable to open display, %s.\n", displayName);
        else
	    error("unable to open display\n");
    }

    screen = DefaultScreen(dsp);
    visual = DefaultVisualOfScreen(DefaultScreenOfDisplay(dsp));
    cmap_size = visual->map_entries;

    ATOM_WM_PROTOCOLS = XInternAtom(dsp, "WM_PROTOCOLS", False);
    ATOM_WM_DELETE_WINDOW = XInternAtom(dsp, "WM_DELETE_WINDOW", False);

    if (dump)
	dumpCmap();

    if (install)  {
	    stat = XCreateHSBColormap(dsp, screen, &cmap, half 
					? (cmap_size>>1) : cmap_size,
				      0.0, 1.0, 1.0,
				      1.0, 1.0, 1.0, !nobw, &visual);
	    if (stat != Success)
		error("%s: unable create colormap (%d).\n", stat);
    }

    size_hints.x = DEFX;
    size_hints.y = DEFY;
    size_hints.width = DEFW;
    size_hints.height = DEFH;

    size_hints.flags = 0;
    if (geom) {
	geomStat = XParseGeometry(geom, &(size_hints.x),
				  &(size_hints.y),
				  (unsigned int *) &(size_hints.width),
				  (unsigned int *) &(size_hints.height));
	if (geomStat & (XValue | YValue)) {
	    size_hints.flags |= USPosition;
	}
	if (geomStat & (WidthValue | HeightValue)) {
	    size_hints.flags |= USSize;
	}
    }

    width = size_hints.width;
    height = size_hints.height;

    xswa.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask;
    mask = CWEventMask;

    if (install) {
	    xswa.colormap = cmap;
	    mask |= CWColormap;
    }
   
    win = XCreateWindow(
			dsp,
			DefaultRootWindow(dsp),
			size_hints.x,
			size_hints.y,
			size_hints.width,
			size_hints.height,
			1,	/* borderwidth */

			DefaultDepth(dsp, screen),	/* depth */
			InputOutput,	/* class */
			visual,	/* visual */
			mask,	/* window attribute mask */
			&xswa	/* the attributes */
	);

    XSetStandardProperties(dsp, win, " XColor ", " XCOLOR ",
			   NULL, argv, argc, &size_hints);

    wmhints.flags = InputHint;
    wmhints.input = True;

    if (useiconwin) {
	xswa.event_mask = ExposureMask;
	mask = CWEventMask;

	if (install) {
	    xswa.colormap = cmap;
	    mask |= CWColormap;
	}

	icon = XCreateWindow(dsp, DefaultRootWindow(dsp),
	    0, 0, ICON_WIDTH, ICON_HEIGHT, 0, DefaultDepth(dsp, screen),
	    InputOutput, visual, mask, &xswa);

	wmhints.flags |= IconWindowHint;
	wmhints.icon_window = icon;

	if (install) {
	    Window cmapwins[2];

	    cmapwins[0] = icon;
	    cmapwins[1] = win;
	    XSetWMColormapWindows(dsp, win, cmapwins, 2);
	}
    }

    XSetWMHints(dsp, win, &wmhints);
    XSetWMProtocols(dsp, win, &ATOM_WM_DELETE_WINDOW, 1);

    xgcv.foreground = BlackPixel(dsp, screen);
    xgcv.background = WhitePixel(dsp, screen);
    gc = XCreateGC(dsp, win, GCForeground | GCBackground, &xgcv);

    XMapWindow(dsp, win);

    HandleEvents();

    XUnmapWindow(dsp, win);
    XDestroyWindow(dsp, win);
    XFlush(dsp);
    XCloseDisplay(dsp);
    exit(0);
}