#include <stdio.h>
#include <math.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/*
This is a quick and dirty hack.  It uses globals everywhere and only
supports one window.  But it was quick to write.
*/

#define DEFAULT_BGCOLOR "white"
#define DEFAULT_FGCOLOR "black"

char *theBGcolor = DEFAULT_BGCOLOR,
  *theFGcolor = DEFAULT_FGCOLOR;

Display *GblDisplay = NULL;
Window GblWindow;
Visual *GblVisual;
Window GblRootWindow;
float *GblImageSrc = NULL;
int GblImageSrcSize;
GC GblGC;
unsigned long theBGpix, theFGpix;

int GblNumColors = 2;
int GblBaseColor;

Colormap GblColorMap;
unsigned long GblMasks[256];
unsigned long GblPixels[256];
XColor GblColors[256];

imageXregister( a,N)
float *a;
int N;
{
    GblImageSrc = a;
    GblImageSrcSize=N;
}


imageXdraw( a, N)
float *a;
int N;
{
    char*			pPix;
    int				i,j;
    int				value;


    XClearWindow(GblDisplay, GblWindow);    
    for(i=0;i<N;i++){
	for(j=0;j<N;j++){
	    if(a[i*N+j]>0){
		XDrawPoint(GblDisplay, GblWindow, GblGC, i, j);
	    }
	}
    }

    listenX();
}

openX( N)
    int N;
{
    int rgbOfs, rgbRange, i;

    Screen GblScreen;
    int GblScreenNum;
    Status st;
    XColor color;

    GblDisplay = XOpenDisplay( NULL);
    if ( GblDisplay == NULL ) {
	fprintf( stderr, "Couldnt open display %\n",
		XDisplayName(NULL));
	exit(-1);
    }
    GblScreenNum = XDefaultScreen( GblDisplay);
    GblRootWindow = XRootWindow( GblDisplay, GblScreenNum);
    GblColorMap = DefaultColormap( GblDisplay, GblScreenNum);

    if (XParseColor(GblDisplay, GblColorMap, theBGcolor,
		    &color) == 0 ||
	XAllocColor(GblDisplay, GblColorMap, &color) == 0 ){
	/* Use white background in case of failure */
	theBGpix = WhitePixel(GblDisplay, DefaultScreen(GblDisplay));
    }
    else {
	theBGpix = color.pixel;
    }
    if (XParseColor(GblDisplay, GblColorMap, theFGcolor,
		    &color) == 0 ||
	XAllocColor(GblDisplay, GblColorMap, &color) == 0 ){
	/* Use white background in case of failure */
	theFGpix = WhitePixel(GblDisplay, DefaultScreen(GblDisplay));
    }
    else {
	theFGpix = color.pixel;
    }
 
    GblVisual = DefaultVisual( GblDisplay, GblScreenNum);
    GblGC = DefaultGC( GblDisplay, GblScreenNum);
    listenX();
}


openWindow( N, winName)
    int N;
    char *winName;
{
    XSizeHints size_hints;

    GblWindow = XCreateSimpleWindow( GblDisplay, GblRootWindow,
      100, 100, N, N,
      5, theFGpix, theBGpix);
    if ( GblWindow == (Window)NULL ) {
	fprintf( stderr, "Couldnt open window\n");
	exit(1);
    }
    size_hints.flags = PPosition | PSize | PMinSize;
    size_hints.x = 100;
    size_hints.y = 100;
    size_hints.width = N;
    size_hints.height = N;
    size_hints.min_width = N;
    size_hints.min_height = N;
    XSetStandardProperties( GblDisplay, GblWindow,
      winName, winName, None, NULL, 0, &size_hints);
    XSelectInput( GblDisplay, GblWindow, 
      ExposureMask);
    XMapWindow( GblDisplay, GblWindow);
    listenX();
}


listenX()
{
    int N;
    XPoint p1, p2;
    /* XPending() does flush */
    while( XPending(GblDisplay) > 0 ) {
	XEvent event;
	XNextEvent( GblDisplay, &event);
	switch ( event.type ) {
	case Expose:
	    /* purge other exposes */
	    while ( XCheckTypedEvent( GblDisplay, Expose, &event) )
		;
	    if ( GblImageSrc )
	        imageXdraw( GblImageSrc, GblImageSrcSize);
 	    break;
        }
    }
}