/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2002 Topi Mäenpää
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.4 $
 *********************************************************************/

#include "XWindows.h"
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>

using namespace std;

namespace prapi
{
	XDisplay::XDisplay() throw (XException&)
	{
		_pDisplay = XOpenDisplay(NULL);
		if (!_pDisplay)
			throw XException("XDisplay::XDisplay(): cannot open default display.");
	}

	XDisplay::XDisplay(string display) throw (XException&)
	{
		_pDisplay = XOpenDisplay(display.c_str());
		if (!_pDisplay)
			throw XException("XDisplay::XDisplay(string): cannot open " + display + ".");
	}
	
	void XWindows::Displayer::run()
	{
		int blackColor = XBlackPixel(_display, XDefaultScreen(_display));

		//Create the window
		Window window = XCreateSimpleWindow(_display, DefaultRootWindow((Display*)_display), 0, 0, 
																				_iWidth, _iHeight, 0, blackColor, blackColor);

		//Select tracked events
		XSelectInput(_display, window,
								 StructureNotifyMask|ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask);

		//"Map" the window (that is, make it appear on the screen)
		XMapWindow(_display, window);

		// Create a "Graphics Context"
		GC gc = XCreateGC(_display, window, 0, NULL);
		XPutImage(_display, window, gc, _pImage, 0, 0, 0, 0, _iWidth, _iHeight);
		XFlush(_display);
		XStoreName(_display, window, _strTitle.c_str());

		Atom WM_DELETE_WINDOW;
		WM_DELETE_WINDOW = XInternAtom(_display, "WM_DELETE_WINDOW", True);
		XSetWMProtocols(_display, window, &WM_DELETE_WINDOW, 1);
		
		bool loop = true;
		do
			{
				XEvent e;
				//XWindowEvent(_display, window, -1, &e);
				XNextEvent(_display, &e);
				switch(e.type)
					{
					case KeyPress:
						//loop = false;
						break;
					case Expose:
						XPutImage(_display, window, gc, _pImage, 0, 0, 0, 0, _iWidth, _iHeight);
						XFlush(_display);
						break;
					case ButtonPress:
						loop = false;
						break;
					case ClientMessage:
						if ((Atom)e.xclient.data.l[0] == WM_DELETE_WINDOW)
							loop = false;
						break;
					}
			} while(loop);

		XDestroyImage(_pImage);
		XDestroyWindow(_display, window);
		XFlush(_display);
		_display.close();
	}
}
