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


/*
#define RELEASE_4
*/
#define RELEASE 3

/*global variables*/

Display *TheDisplay;
int TheScreen;
Window TheRootWindow;
unsigned long TheWhitePixel, TheBlackPixel;


void initialiseX11()
{
	/*open connection to the server*/
	TheDisplay = XOpenDisplay(NULL);

	/*default screen number*/
	TheScreen = DefaultScreen(TheDisplay);

	/*the root window - framebuffer*/
	TheRootWindow = DefaultRootWindow(TheDisplay);

	/*black and white pixels*/
	TheWhitePixel = WhitePixel(TheDisplay,TheScreen);
	TheBlackPixel = BlackPixel(TheDisplay,TheScreen);
}

#ifdef RELEASE_4

Window createWindow(parent,user,posx,posy,width,height,border,
		    win_title,icon_title)
/*If user is False then this creates a window with the
 given width and height, otherwise the size is determined
 interactively by the user. The window is created as a child of the given
 parent window, and has the titles as specified*/
Window parent;
Bool user;
int posx,posy,width,height;
unsigned int border;
char *win_title,*icon_title;
{
	Window newWindow;
	XTextProperty win_name,icon_name;
	XSizeHints hints;
	XEvent event;
	XSetWindowAttributes attr;

	/*create the new window*/
	newWindow = XCreateSimpleWindow(TheDisplay,parent,
					posx,posy,width,height,border,
					TheBlackPixel,TheWhitePixel);

	/*convert the names each to a TextProperty*/
	XStringListToTextProperty(&win_title,1,&win_name);
	XStringListToTextProperty(&icon_title,1,&icon_name);

	/*set the name of the window and icon*/
	XSetWMName(TheDisplay,newWindow,&win_name);
	XSetWMIconName(TheDisplay,newWindow,&icon_name);

	/*set the size hints (WM_NORMAL_HINTS) property*/
	if(user) hints.flags = USSize;
	else{
		hints.flags = PSize;
		hints.base_width = width;
		hints.base_height = height;
	}
	XSetWMNormalHints(TheDisplay,newWindow,&hints);

	/*make sure that this window accepts exposure events*/
	XSelectInput(TheDisplay,newWindow,ExposureMask);

	/*map the window and wait for an expose event*/
	XMapWindow(TheDisplay,newWindow);
	while(True){
		XNextEvent(TheDisplay,&event);
		if((event.type==Expose)&&(event.xexpose.window==newWindow))
			break;
	}

	/*if not user ensure that this window is not interfered with
	  by the window manager*/
	if(user) attr.override_redirect = False;
	else     attr.override_redirect = True;

	/*set the window attributes - to always use backing store*/
	attr.backing_store = Always;
	/*means that there will be an attempt to repaint window contents
	  on Expose events, but there is no guarantee*/
	XChangeWindowAttributes(TheDisplay,newWindow,
				CWOverrideRedirect|CWBackingStore,&attr);
	/*Note that if the window is resized then the contents may not
	  be restored. In any case there will be an Expose event generated
	  and the client should be prepared to handle this*/

	return(newWindow);
}
#else
/*release 3*/

Window createWindow(parent,user,posx,posy,width,height,border,
		    win_title,icon_title)
/*If user is False then this creates a window with the
 given width and height, otherwise the size is determined
 interactively by the user. The window is created as a child of the given
 parent window, and has the titles as specified*/
Window parent;
Bool user;
int posx,posy,width,height;
unsigned int border;
char *win_title,*icon_title;
{

	Window theWindow;
	XSizeHints hints;
	char **argv;
	int argc = 0;
	XWMHints wmhints;
	XSetWindowAttributes attr;
	XEvent event;
   	
	theWindow = XCreateSimpleWindow(TheDisplay,TheRootWindow,posx,posy,
			     width,height,border,TheBlackPixel,TheWhitePixel);
   	hints.flags = (PPosition | PSize);
   	hints.height = height;
   	hints.width = width;
   	hints.x = posx;
   	hints.y = posy;
      	XSetStandardProperties(TheDisplay,theWindow,win_title,
			  icon_title,None,argv,argc,&hints);

   	wmhints.flags = (InputHint | StateHint);
   	wmhints.input = False;
   	wmhints.initial_state = NormalState;
   	wmhints.icon_pixmap = 0;
   	wmhints.icon_window = 0;
   	wmhints.icon_x = wmhints.icon_y = 0;
   	wmhints.icon_mask = 0;
   	wmhints.window_group = 0;
   	XSetWMHints(TheDisplay,theWindow,&wmhints);

   	/*set up default colour map*/
   	attr.colormap = DefaultColormap(TheDisplay,TheScreen);
   	attr.bit_gravity = CenterGravity;
   	XChangeWindowAttributes(TheDisplay,theWindow,
                                      (CWColormap|CWBitGravity),&attr);


	XSelectInput(TheDisplay,theWindow,ExposureMask);

   	XMapWindow(TheDisplay,theWindow);

   	while(True){
    		XNextEvent(TheDisplay,&event);
		if((event.type==Expose)&&(event.xexpose.window==theWindow))
			break;
	}
	return(theWindow);
}

#endif

main()
{
	Window win;
	Bool fromUser = True, fromProgram = False;
	int posx = 100, posy = 100, width = 400, height = 400;
	unsigned int border = 10;
	XEvent event;

	initialiseX11();

	/*create a new window as a child of the root*/
	win = createWindow(TheRootWindow,fromProgram,
			   posx,posy,width,height,border,
			   "My Window","My Icon");

	/*draw a line into the window*/
	XDrawLine(TheDisplay,win,DefaultGC(TheDisplay,TheScreen),0,0,399,399);

	/*set the input mask on this window to accept Button presses*/
	XSelectInput(TheDisplay,win,ButtonPressMask);

	/*wait for a button press*/
	XWindowEvent(TheDisplay,win,ButtonPressMask,&event);

	/*close down*/
	XDestroyWindow(TheDisplay,win);
	XCloseDisplay(TheDisplay);
}









