/*
 * Test program to draw lines in a window using the Xlib interface.
 * On the way to uptting X11 support into csound.
 * Second version: has a function process_xevents() to do all X event handling.
 * It should be called periodically.
 * mg@ukc.ac.uk, May 1990
 */

#include <stdio.h>

main(argc, argv)
char **argv;
{
	x_open();
	while (1) {
		sleep(1);
		x_process();
	}
	x_close();
	exit(0);
}

#include <X11/Xlib.h>
/* Variables for X use only */

Display *dpy;
Window window;
Window subwindow;
GC gc;
XGCValues xgcvalues;
int width = 100, height = 100;	/* current size of window */

x_open()
{
	/*
	 * Open up the world
	 */

	dpy = XOpenDisplay(NULL);	/* should use -display args etc */
	if (dpy == NULL) {
		fprintf(stderr, "Cannot open X display\n");
		exit(1);
	}

	/*
	 * Ask for a window to be created...
	 */

	window = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
			100, 100,	/* position of top left corner */
			width, height,	/* size of drawing area */
			0,		/* border width */
			0,		/* border colour */
			WhitePixel(dpy, 0));	/* background */

	subwindow = XCreateSimpleWindow(dpy, window,
			10, 10,	/* position of top left corner */
			width/2, height/2,	/* size of drawing area */
			1,			/* border width */
			BlackPixel(dpy, 0),	/* border colour */
			WhitePixel(dpy, 0));	/* background */
	
	/*
	 * Register an interest in events that make us redraw.
	 */
	XSelectInput(dpy, window, StructureNotifyMask | ExposureMask);

	/*
	 * ... map it ...
	 * This causes a ConfigureNotify event, which causes us to draw the
	 * graphic.  Do not try to draw on the object before this!
	 */

	XMapWindow(dpy, window);
	XMapWindow(dpy, subwindow);

	/*
	 * Get a graphic context for use in drawing operations
	 */
	xgcvalues.foreground = BlackPixel(dpy, 0);

	gc = XCreateGC(dpy, window, GCForeground, &xgcvalues);
}

x_process()
{
	XEvent event;
	int need_to_redraw = 0;

	while (XEventsQueued(dpy, QueuedAfterFlush) > 0) {

		XNextEvent(dpy, &event);

		switch (event.type) {
		/* Ignore the other events you get for free
		 * with ConfigureNotify */
		case CirculateNotify:
		case DestroyNotify:
		case GravityNotify:
		case MapNotify:
		case ReparentNotify:
			break;
		case ConfigureNotify:
			/* stash window size */
			width = event.xconfigure.width;
			height = event.xconfigure.height;
			need_to_redraw = 1;
			break;
		case Expose:
			need_to_redraw = 1;
			break;
		default:
			fprintf(stderr, "Strange event %d received.\n", event.type);
			break;
		}

	}

	if (need_to_redraw) {
		redraw(window);
		redraw(subwindow);
	}
}

x_close()
{
	XCloseDisplay(dpy);
}

#define NP 5

static struct {
	float fx, fy;
} fpoint[NP] = {
	{ 0, 0 },
	{ 0.16, 1 },
	{ 0.33, 0.75 },
	{ 0.84, 0.65 },
	{ 1.00, 0.0 }
};

redraw(window)
Window window;
{
	XPoint xpoint[NP];
	int i;
	int width, height;
	XWindowAttributes wa;
	
	XGetWindowAttributes(dpy, window, &wa);
	width = wa.width; height = wa.height;

	for (i=0; i<NP; i++) {
		/* scale 0-1 to window size, with origin at bottom left */
		xpoint[i].x = fpoint[i].fx * (width - 1);
		xpoint[i].y = (height - 1) - fpoint[i].fy * (height - 1);
	}
	XClearWindow(dpy, window);
	XDrawLines(dpy, window, gc, xpoint, NP, CoordModeOrigin);
	XDrawString(dpy, window, gc, width/2, height/2, "Hello", 5);
}
