//--------------------------------------------------------------------------------//
void GLXProc( const XEvent &event )
{
	//We have to find appropriate window based on window id ( kindof hackish :/,
	//but at least this only happens when there is a Window's event - and not that often
	WindowEventUtilities::Windows::iterator i = WindowEventUtilities::_msWindows.begin(),
						e = WindowEventUtilities::_msWindows.end();
	RenderWindow* win = 0;
	for(; i != e; ++i )
	{
		std::size_t wind = 0;
		(*i)->getCustomAttribute("WINDOW", &wind);
		if( event.xany.window == wind )
		{
			win = *i;
			break;
		}
	}

	//Sometimes, seems we get other windows, so just ignore
	if( win == 0 ) return;

	//Now that we have the correct RenderWindow for the generated Event, get an iterator for the listeners
	WindowEventUtilities::WindowEventListeners::iterator 
		start = WindowEventUtilities::_msListeners.lower_bound(win),
		end   = WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window Closed (via X button)
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			for( ; start != end; ++start )
				(start->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:	//Moving or Resizing
		unsigned int width, height, depth;
		int left, top;
		win->getMetrics(width, height, depth, left, top);

		//determine if moving or sizing:
		if( left == event.xconfigure.x && top == event.xconfigure.y )
		{	//Resize width, height
			win->windowMovedOrResized();
			for( ; start != end; ++start )
				(start->second)->windowResized(win);
		}
		else if( width == event.xconfigure.width && height == event.xconfigure.height )
		{	//Moving x, y
			win->windowMovedOrResized();
			for( ; start != end; ++start )
				(start->second)->windowMoved(win);
		}
		break;
	case MapNotify:   //Restored
		win->setActive( true );
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}

		//Notify Listeners that focus of window has changed in some way
		for( ; start != end; ++start )
			(start->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}
    int main(int argc, char **argv)
#endif
{
    //-----------------------------------------------------
    // 1 enter ogre
    //-----------------------------------------------------
    Root* root = new Root;
 
    //-----------------------------------------------------
    // 2 configure resource paths
    //-----------------------------------------------------
    // Load resource paths from config file
 
    // File format is:
    //  [ResourceGroupName]
    //  ArchiveType=Path
    //  .. repeat
    // For example:
    //  [General]
    //  FileSystem=media/
    //  Zip=packages/level1.zip
 
    ConfigFile cf;
    cf.load("./resources.cfg");
 
    // Go through all sections & settings in the file
    ConfigFile::SectionIterator seci = cf.getSectionIterator();
 
    String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        ConfigFile::SettingsMultiMap *settings = seci.getNext();
        ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
    //-----------------------------------------------------
    // 3 Configures the application and creates the window
    //-----------------------------------------------------
    if(!root->showConfigDialog())
    {
        //Ogre
        delete root;
        return false; // Exit the application on cancel
    }
 
    RenderWindow* window = root->initialise(true, "Simple Ogre App");
 
    ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
 
    //-----------------------------------------------------
    // 4 Create the SceneManager
    //
    //        ST_GENERIC = octree
    //        ST_EXTERIOR_CLOSE = simple terrain
    //        ST_EXTERIOR_FAR = nature terrain (depreciated)
    //        ST_EXTERIOR_REAL_FAR = paging landscape
    //        ST_INTERIOR = Quake3 BSP
    //----------------------------------------------------- 
    SceneManager* sceneMgr = root->createSceneManager(ST_GENERIC); 
 
    //----------------------------------------------------- 
    // 5 Create the camera 
    //----------------------------------------------------- 
    Camera* camera = sceneMgr->createCamera("SimpleCamera"); 
 
    //----------------------------------------------------- 
    // 6 Create one viewport, entire window 
    //----------------------------------------------------- 
    Viewport* viewPort = window->addViewport(camera);
 
    //---------------------------------------------------- 
    // 7 add OIS input handling 
    //----------------------------------------------------
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;
 
    //tell OIS about the Ogre window
    window->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 
    //setup the manager, keyboard and mouse to handle input
    OIS::InputManager* inputManager = OIS::InputManager::createInputSystem(pl);
    OIS::Keyboard* keyboard = static_cast<OIS::Keyboard*>(inputManager->createInputObject(OIS::OISKeyboard, true));
    OIS::Mouse*    mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse, true));
 
    //tell OIS about the window's dimensions
    unsigned int width, height, depth;
    int top, left;
    window->getMetrics(width, height, depth, left, top);
    const OIS::MouseState &ms = mouse->getMouseState();
    ms.width = width;
    ms.height = height;
 
    // everything is set up, now we listen for input and frames (replaces while loops)
    //key events
    SimpleKeyListener* keyListener = new SimpleKeyListener();
    keyboard->setEventCallback(keyListener);
    //mouse events
    SimpleMouseListener* mouseListener = new SimpleMouseListener();
    mouse->setEventCallback(mouseListener);
    //render events
    SimpleFrameListener* frameListener = new SimpleFrameListener(keyboard, mouse);
    root->addFrameListener(frameListener); 
 
    //----------------------------------------------------
    // 8 start rendering 
    //----------------------------------------------------
    root->startRendering(); // blocks until a frame listener returns false. eg from pressing escape in this example
 
    //----------------------------------------------------
    // 9 clean 
    //----------------------------------------------------
    //OIS
    inputManager->destroyInputObject(mouse); mouse = 0;
    inputManager->destroyInputObject(keyboard); keyboard = 0;
    OIS::InputManager::destroyInputSystem(inputManager); inputManager = 0;
    //listeners
    delete frameListener; 
    delete mouseListener; 
    delete keyListener;
    //Ogre
    delete root;
 
    return 0; 
}