#define MAXCOLORS 256

#include <stdio.h>
#include <stdlib.h>
#include <xil/xil.h>

#define NCOLORS 216

extern Display *xdisplay;
extern Window xwindow;

int        errhandler(Display *);

int
open_window(width, height, vinfo)
    u_int width, height;
    XVisualInfo *vinfo;
{
    XSetWindowAttributes setwinattr;
    Colormap colormap;
    unsigned long pixels[MAXCOLORS], pmask[1], pixel[1];
    int i, j, k, index;
    XColor colors[MAXCOLORS];
    int base;

    xdisplay = XOpenDisplay(NULL);
    if (xdisplay == NULL) {
        fprintf(stderr, "Unable to connect to server\n");
        return(0);
    }

    XSetIOErrorHandler(errhandler);

    /* Find best visual */
    if (XMatchVisualInfo(xdisplay, DefaultScreen(xdisplay), 24, 
	TrueColor, vinfo) &&
	(DefaultDepth(xdisplay, DefaultScreen(xdisplay)) == 24)) {}
    else if (XMatchVisualInfo(xdisplay, DefaultScreen(xdisplay), 8, 
	GrayScale, vinfo))  {}
    else if (XMatchVisualInfo(xdisplay, DefaultScreen(xdisplay), 8, 
	StaticGray, vinfo)) {}
    else if (XMatchVisualInfo(xdisplay, DefaultScreen(xdisplay), 1, 
	StaticGray, vinfo)) {}
    else 
    {
	return(0);
    }

   colormap = XCreateColormap(xdisplay, DefaultRootWindow(xdisplay), 
		vinfo->visual, AllocNone);
   setwinattr.colormap = colormap;

   xwindow = XCreateWindow(xdisplay, DefaultRootWindow(xdisplay),
        20, 20, width, height, 0, vinfo->depth, InputOutput, vinfo->visual,
	CWColormap, &setwinattr);

    if (xwindow == NULL) {
        fprintf(stderr, "Unable to create window\n");
        return(0);
    }
    if (vinfo->class == GrayScale)  {
        base = MAXCOLORS - NCOLORS;

        i = XAllocColorCells(xdisplay, colormap, 1, pmask, 0, pixels, 256);

        for (pixel[0] = 0; pixel[0] < base; pixel[0]++) {
            XFreeColors(xdisplay, colormap, pixel, 1, 0);
        }
    
        /* Fill the colormap */
        index = 0;
        for (i = 0; i <NCOLORS; i++) {
            colors[index].pixel = index + base ;
            colors[index].blue = colors[index].green = colors[index].red =
                (255 * i/(NCOLORS-1)) * 256;
            colors[index].flags = DoRed | DoGreen | DoBlue;
            index++;
        }
        XStoreColors(xdisplay, colormap, colors, NCOLORS);
    }
    /* List window events used */
    XSelectInput(xdisplay, xwindow, ExposureMask | ButtonPressMask |
        KeyPressMask);

    /* Make the window visible */
    XMapWindow(xdisplay, xwindow);
    return(1);
}

int errhandler(display)
Display *display;
{
        exit(0);
}
