Index: /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/PixelBufferCocoa
===================================================================
--- /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/PixelBufferCocoa (revision 9879)
+++ /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/PixelBufferCocoa (revision 9879)
@@ -0,0 +1,119 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * OpenSceneGraph Public License for more details.
+*/
+
+
+
+#ifndef OSGVIEWER_PIXELBUFFERCOCOA
+#define OSGVIEWER_PIXELBUFFERCOCOA 1
+
+#ifdef __APPLE__
+
+#include <osg/GraphicsContext>
+#include <osgViewer/Export>
+
+
+#ifdef __OBJC__
+@class NSOpenGLContext;
+#else
+class NSOpenGLContext;
+#endif
+
+namespace osgViewer
+{
+
+class OSGVIEWER_EXPORT PixelBufferCocoa : public osg::GraphicsContext
+{
+    public:
+		struct Implementation;
+
+        PixelBufferCocoa(osg::GraphicsContext::Traits* traits):
+			_valid(false),
+			_initialized(false),
+            _realized(false),
+            _context(NULL)
+		{
+            _traits = traits;
+
+            init();
+            
+            if (valid())
+            {
+                setState( new osg::State );
+                getState()->setGraphicsContext(this);
+
+                if (_traits.valid() && _traits->sharedContext)
+                {
+                    getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
+                    incrementContextIDUsageCount( getState()->getContextID() );   
+                }
+                else
+                {
+                    getState()->setContextID( osg::GraphicsContext::createNewContextID() );
+                }
+
+            }
+        }
+    
+        virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const PixelBufferCocoa*>(object)!=0; }
+        virtual const char* libraryName() const { return "osgViewer"; }
+        virtual const char* className() const { return "PixelBufferCarbon"; }
+
+        virtual bool valid() const { return _valid; }
+
+        /** Realise the GraphicsContext.*/
+        virtual bool realizeImplementation();
+
+        /** Return true if the graphics context has been realised and is ready to use.*/
+        virtual bool isRealizedImplementation() const { return _realized; }
+
+        /** Close the graphics context.*/
+        virtual void closeImplementation();
+
+        /** Make this graphics context current.*/
+        virtual bool makeCurrentImplementation();
+
+        /** Make this graphics context current with specified read context implementation. */
+        virtual bool makeContextCurrentImplementation(osg::GraphicsContext* readContext);
+
+        /** Release the graphics context.*/
+        virtual bool releaseContextImplementation();
+
+        /** Bind the graphics context to associated texture implementation.*/
+        virtual void bindPBufferToTextureImplementation( GLenum buffer );
+
+        /** Swap the front and back buffers.*/
+        virtual void swapBuffersImplementation();
+        
+         NSOpenGLContext* getContext() { return _context; }
+    public:
+    
+
+    protected:
+		
+
+    
+        ~PixelBufferCocoa();
+    
+        void init();
+
+        bool            _valid;
+        bool            _initialized;
+        bool            _realized;  
+		NSOpenGLContext* _context;
+};
+
+}
+
+#endif
+
+#endif
Index: /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/GraphicsWindowCocoa
===================================================================
--- /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/GraphicsWindowCocoa (revision 9879)
+++ /OpenSceneGraph/trunk/include/osgViewer/api/Cocoa/GraphicsWindowCocoa (revision 9879)
@@ -0,0 +1,176 @@
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+ *
+ * This library is open source and may be redistributed and/or modified under  
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * OpenSceneGraph Public License for more details.
+*/
+
+/* Note, elements of GraphicsWindowX11 have used Prodcer/RenderSurface_X11.cpp as both
+ * a guide to use of X11/GLX and copiying directly in the case of setBorder().
+ * These elements are license under OSGPL as above, with Copyright (C) 2001-2004  Don Burns.
+ */
+
+#ifndef OSGVIEWER_GRAPHICSWINDOWCOCOA
+#define OSGVIEWER_GRAPHICSWINDOWCOCOA 1
+
+#ifdef __APPLE__
+
+#ifdef __OBJC__
+@class GraphicsWindowCocoaWindow;
+@class NSOpenGLContext;
+@class NSWindow;
+#else
+class GraphicsWindowCocoaWindow;
+class NSOpenGLContext;
+class NSWindow;
+#endif
+
+#include <osgViewer/GraphicsWindow>
+
+// we may not include any cocoa-header here, because this will pollute the name-sapce and tend to compile-errors
+
+namespace osgViewer
+{
+
+class GraphicsWindowCocoa : public osgViewer::GraphicsWindow
+{
+    public:
+	class Implementation;
+
+        GraphicsWindowCocoa(osg::GraphicsContext::Traits* traits):
+            _valid(false),
+            _initialized(false),
+            _realized(false),
+            _ownsWindow(true),
+            _currentCursor(RightArrowCursor)
+        {
+            _traits = traits;
+
+            init();
+            
+            if (valid())
+            {
+                setState( new osg::State );
+                getState()->setGraphicsContext(this);
+
+                if (_traits.valid() && _traits->sharedContext)
+                {
+                    getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
+                    incrementContextIDUsageCount( getState()->getContextID() );   
+                }
+                else
+                {
+                    getState()->setContextID( osg::GraphicsContext::createNewContextID() );
+                }
+            }
+        }
+    
+        virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindowCocoa*>(object)!=0; }
+        virtual const char* libraryName() const { return "osgViewer"; }
+        virtual const char* className() const { return "GraphicsWindowCarbon"; }
+
+        virtual bool valid() const { return _valid; }
+
+        /** Realise the GraphicsContext.*/
+        virtual bool realizeImplementation();
+
+        /** Return true if the graphics context has been realised and is ready to use.*/
+        virtual bool isRealizedImplementation() const { return _realized; }
+
+        /** Close the graphics context.*/
+        virtual void closeImplementation();
+
+        /** Make this graphics context current.*/
+        virtual bool makeCurrentImplementation();
+        
+        /** Release the graphics context.*/
+        virtual bool releaseContextImplementation();
+
+        /** Swap the front and back buffers.*/
+        virtual void swapBuffersImplementation();
+        
+        /** Check to see if any events have been generated.*/
+        virtual void checkEvents();
+
+        /** Set Window decoration.*/
+        virtual bool setWindowDecorationImplementation(bool flag);
+
+        /** Get focus.*/
+        virtual void grabFocus();
+        
+        /** Get focus on if the pointer is in this window.*/
+        virtual void grabFocusIfPointerInWindow();
+        
+        bool requestClose() { bool b = _closeRequested; _closeRequested = true; return b; }
+        
+        virtual void resizedImplementation(int x, int y, int width, int height);
+        
+        virtual bool setWindowRectangleImplementation(int x, int y, int width, int height);
+        
+        virtual void setWindowName (const std::string & name);
+        virtual void useCursor(bool cursorOn);
+        virtual void setCursor(MouseCursor mouseCursor);
+               
+        /** WindowData is used to pass in the Cocoa window handle attached the GraphicsContext::Traits structure. */
+        class WindowData : public osg::Referenced
+        {
+            public:
+                WindowData(NSWindow* window)
+				:	_window(window) 
+				{
+				}
+                
+                inline NSWindow* getNativeWindowRef() { return _window; }
+                                
+            private:
+                NSWindow*    _window;
+                bool         _installEventHandler;
+            
+        };
+        
+        NSOpenGLContext* getContext() { return _context; }
+        GraphicsWindowCocoaWindow* getWindow() { return _window; }
+                
+        void setVSync(bool f);
+		
+		/** adapts a resize / move of the window, coords in global screen space */
+		void adaptResize(int x, int y, int w, int h);
+        
+    protected:
+    
+        void init();
+        
+        void transformMouseXY(float& x, float& y);
+        void setupNSWindow(NSWindow* win);
+        
+        
+        virtual ~GraphicsWindowCocoa();
+
+
+        bool            _valid;
+        bool            _initialized;
+        bool            _realized;
+        bool            _useWindowDecoration;
+        bool            _ownsWindow;
+
+	
+         
+    private:        
+       
+        
+        bool				_closeRequested;
+        MouseCursor			_currentCursor;
+		GraphicsWindowCocoaWindow* _window;
+		NSOpenGLContext*	_context;
+};
+
+}
+
+#endif
+#endif
Index: /OpenSceneGraph/trunk/src/osgViewer/PixelBufferCocoa.mm
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/PixelBufferCocoa.mm (revision 9879)
+++ /OpenSceneGraph/trunk/src/osgViewer/PixelBufferCocoa.mm (revision 9879)
@@ -0,0 +1,150 @@
+/*
+ *  PixelBufferCocoa.cpp
+ *  OpenSceneGraph
+ *
+ *  Created by Stephan Huber on 27.06.08.
+ *  Copyright 2008 Stephan Maximilian Huber, digital mind. All rights reserved.
+ *
+ */
+
+#include <iostream>
+#include <osgViewer/api/Cocoa/PixelBufferCocoa>
+#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
+#include <Cocoa/Cocoa.h>
+
+namespace osgViewer {
+
+
+void PixelBufferCocoa::init()
+{
+	//std::cout << "PixelBufferCocoa :: init not implemented yet " << std::endl;
+	
+	_valid = _initialized = true;    
+	
+
+}
+
+bool PixelBufferCocoa::realizeImplementation() 
+{
+	std::cout << "PixelBufferCocoa :: realizeImplementation not implemented yet " << std::endl;
+	
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    	 
+	NSOpenGLPixelFormatAttribute attr[32];
+    int i = 0;
+    
+    attr[i++] = NSOpenGLPFADepthSize;
+    attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->depth);
+
+    if (_traits->doubleBuffer) {
+        attr[i++] = NSOpenGLPFADoubleBuffer;
+    }
+    
+    if (_traits->alpha) { 
+        attr[i++] = NSOpenGLPFAAlphaSize;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->alpha);
+    }
+
+    if (_traits->stencil) {
+        attr[i++] = NSOpenGLPFAStencilSize;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->stencil);
+    }
+  
+
+    if (_traits->sampleBuffers) {
+        attr[i++] = NSOpenGLPFASampleBuffers;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->sampleBuffers);
+        attr[i++] = NSOpenGLPFASamples;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->samples);
+    }
+
+    attr[i++] = NSOpenGLPFAPixelBuffer; // for pbuffer usage
+    attr[i++] = NSOpenGLPFAAccelerated;
+    attr[i] = static_cast<NSOpenGLPixelFormatAttribute>(0);
+    
+    // create the context
+    NSOpenGLContext* sharedContext = NULL;
+    
+    GraphicsWindowCocoa* graphicsWindowCocoa = dynamic_cast<GraphicsWindowCocoa*>(_traits->sharedContext);
+    if (graphicsWindowCocoa) 
+    {
+        sharedContext = graphicsWindowCocoa->getContext();
+    }
+    else
+    {
+        PixelBufferCocoa* pixelbuffer = dynamic_cast<PixelBufferCocoa*>(_traits->sharedContext);
+        if (pixelbuffer) {
+            sharedContext = pixelbuffer->getContext();
+        }
+    }
+	
+	NSOpenGLPixelFormat* pixelformat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr ];
+    _context = [[NSOpenGLContext alloc] initWithFormat: pixelformat shareContext: sharedContext];
+    NSOpenGLPixelBuffer* pbuffer = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget: _traits->target textureInternalFormat: _traits->format textureMaxMipMapLevel: _traits->level pixelsWide: _traits->width pixelsHigh: _traits->height];
+    
+    [_context setPixelBuffer: pbuffer cubeMapFace: _traits->face mipMapLevel:_traits->level currentVirtualScreen: nil];
+    
+    [pool release];
+    
+    _realized = (_context != nil);
+    return _realized;
+}
+
+
+void PixelBufferCocoa::closeImplementation()
+{
+	_realized = false;
+    
+    
+}
+
+
+
+/** Make this graphics context current.*/
+bool PixelBufferCocoa::makeCurrentImplementation()
+{
+	// osg::notify(osg::INFO) << "PixelBufferCocoa::makeCurrentImplementation" << std::endl;
+    
+    [_context makeCurrentContext];
+	return true;
+}
+
+
+/** Make this graphics context current with specified read context implementation. */
+bool PixelBufferCocoa::makeContextCurrentImplementation(osg::GraphicsContext* readContext)
+{
+	return makeCurrentImplementation();
+}
+
+/** Release the graphics context.*/
+bool PixelBufferCocoa::releaseContextImplementation()
+{
+	// osg::notify(osg::INFO) << "PixelBufferCocoa::releaseContextImplementation" << std::endl;
+    
+    [NSOpenGLContext clearCurrentContext];
+    return true;
+}
+
+/** Bind the graphics context to associated texture implementation.*/
+void PixelBufferCocoa::bindPBufferToTextureImplementation( GLenum buffer )
+{
+	std::cout << "PixelBufferCocoa :: bindPBufferToTextureImplementation not implemented yet " << std::endl;
+}
+
+/** Swap the front and back buffers.*/
+void PixelBufferCocoa::swapBuffersImplementation()
+{
+	osg::notify(osg::INFO) << "PixelBufferCocoa::swapBuffersImplementation" << std::endl;
+    [_context flushBuffer];
+}
+
+ PixelBufferCocoa::~PixelBufferCocoa()
+ {	
+    [_context release];
+ }
+
+
+
+
+}
+
Index: /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.h (revision 9879)
+++ /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.h (revision 9879)
@@ -0,0 +1,148 @@
+/*
+ *  DarwinUtils.h
+ *  OpenSceneGraph
+ *
+ *  Created by Stephan Huber on 27.06.08.
+ *  Copyright 2008 Stephan Maximilian Huber, digital mind. All rights reserved.
+ *
+ */
+
+#ifdef __APPLE__
+ 
+#ifndef DARWIN_UTILS_HEADER_
+#define DARWIN_UTILS_HEADER_
+
+#include <osg/DeleteHandler>
+#include <osg/GraphicsContext>
+#include <osgViewer/GraphicsWindow>
+#include <Carbon/Carbon.h>
+
+
+//#define USE_DARWIN_COCOA_IMPLEMENTATION 1
+//#define USE_DARWIN_CARBON_IMPLEMENTATION 1
+
+namespace osgDarwin {
+
+
+/** the MenubarController class checks all open windows if they intersect with the menubar / dock and hide the menubar/dock if necessary */
+class MenubarController : public osg::Referenced 
+{
+
+    public:
+		class WindowAdapter : public osg::Referenced {
+			
+			public:
+				WindowAdapter() : osg::Referenced() {}
+				
+				virtual bool valid() = 0;
+				virtual void getWindowBounds(CGRect& rect) = 0;
+				virtual osgViewer::GraphicsWindow* getWindow() = 0;
+				
+			protected:
+				virtual ~WindowAdapter() {}
+		};
+		
+        MenubarController();        
+        static MenubarController* instance();
+        
+        void attachWindow(WindowAdapter* win);
+        void update();
+        void detachWindow(osgViewer::GraphicsWindow* win);
+        
+    private: 
+        typedef std::list< osg::ref_ptr< WindowAdapter > > WindowList;
+        WindowList				_list;
+        bool					_menubarShown;
+        CGRect					_availRect;
+        CGRect					_mainScreenBounds;
+        OpenThreads::Mutex		_mutex;
+        
+};
+
+
+
+struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
+{
+    public:
+		DarwinWindowingSystemInterface();
+		
+		/** dtor */
+		~DarwinWindowingSystemInterface();
+		
+	/** @return a CGDirectDisplayID for a ScreenIdentifier */
+	CGDirectDisplayID getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si);
+	
+	/** @return count of attached screens */
+	virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) ;
+	
+	virtual void getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution);
+
+	virtual void enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList);
+
+	/** return the top left coord of a specific screen in global screen space */
+	void getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y);
+	
+	/** implementation of setScreenResolution */
+	virtual bool setScreenResolution(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) ;
+
+	/** implementation of setScreenRefreshRate */
+	virtual bool setScreenRefreshRate(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate);
+	
+	
+	/** returns screen-ndx containing rect x,y,w,h */
+	unsigned int getScreenContaining(int x, int y, int w, int h);
+	
+	protected:
+	
+		template<class PixelBufferImplementation, class GraphicsWindowImplementation>
+		osg::GraphicsContext* createGraphicsContextImplementation(osg::GraphicsContext::Traits* traits)
+		{
+			if (traits->pbuffer)
+			{
+				osg::ref_ptr<PixelBufferImplementation> pbuffer = new PixelBufferImplementation(traits);
+				if (pbuffer->valid()) return pbuffer.release();
+				else return 0;
+			}
+			else
+			{
+				osg::ref_ptr<GraphicsWindowImplementation> window = new GraphicsWindowImplementation(traits);
+				if (window->valid()) return window.release();
+				else return 0;
+			}
+		}
+	
+    
+	private:
+        CGDisplayCount        _displayCount;
+        CGDirectDisplayID*    _displayIds;
+
+
+};
+
+template <class WSI>
+struct RegisterWindowingSystemInterfaceProxy
+{
+    RegisterWindowingSystemInterfaceProxy()
+    {
+        osg::GraphicsContext::setWindowingSystemInterface(new WSI);
+    }
+
+    ~RegisterWindowingSystemInterfaceProxy()
+    {
+        if (osg::Referenced::getDeleteHandler())
+        {
+            osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
+            osg::Referenced::getDeleteHandler()->flushAll();
+        }
+
+        osg::GraphicsContext::setWindowingSystemInterface(0);
+    }
+};
+
+
+
+}
+
+#endif
+
+#endif // __APPLE__
Index: /OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCocoa.mm
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCocoa.mm (revision 9879)
+++ /OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCocoa.mm (revision 9879)
@@ -0,0 +1,1289 @@
+/*
+ *  GraphicsWindowCocoa.cpp
+ *  OpenSceneGraph
+ *
+ *  Created by Stephan Huber on 27.06.08.
+ *  Copyright 2008 Stephan Maximilian Huber, digital mind. All rights reserved.
+ * 
+ *  Some code borrowed from the implementation of CocoaViewer, 
+ *  Created by Eric Wing on 11/12/06. and ported by Martin Lavery 7/06/07
+ */
+
+#include <iostream>
+#include <osgViewer/api/Cocoa/PixelBufferCocoa>
+#include <osgViewer/api/Cocoa/GraphicsWindowCocoa>
+
+#include <Cocoa/Cocoa.h>
+
+#include "DarwinUtils.h"
+
+
+static bool s_quit_requested = false;
+
+
+// ----------------------------------------------------------------------------------------------------------
+// small helper class remapping key-codes
+// ----------------------------------------------------------------------------------------------------------
+// small helper class which maps the raw key codes to osgGA::GUIEventAdapter::Keys
+
+class CocoaKeyboardMap {
+
+    public:
+        CocoaKeyboardMap()
+        {
+            _keymap[27]     = osgGA::GUIEventAdapter::KEY_Escape;
+            _keymap[13]     = osgGA::GUIEventAdapter::KEY_KP_Enter;
+            _keymap[3]      = osgGA::GUIEventAdapter::KEY_Return;
+            _keymap[9]      = osgGA::GUIEventAdapter::KEY_Tab;
+            _keymap[32]     = osgGA::GUIEventAdapter::KEY_Space;
+            _keymap[127]    = osgGA::GUIEventAdapter::KEY_BackSpace;
+            
+            
+            _keymap[NSHomeFunctionKey]          = osgGA::GUIEventAdapter::KEY_Home;
+            _keymap[NSEndFunctionKey]           = osgGA::GUIEventAdapter::KEY_End;
+            _keymap[NSPageUpFunctionKey]        = osgGA::GUIEventAdapter::KEY_Page_Up;
+            _keymap[NSPageDownFunctionKey]      = osgGA::GUIEventAdapter::KEY_Page_Down;
+            _keymap[NSLeftArrowFunctionKey]     = osgGA::GUIEventAdapter::KEY_Left;
+            _keymap[NSRightArrowFunctionKey]    = osgGA::GUIEventAdapter::KEY_Right;
+            _keymap[NSUpArrowFunctionKey]       = osgGA::GUIEventAdapter::KEY_Up;
+            _keymap[NSDownArrowFunctionKey]     = osgGA::GUIEventAdapter::KEY_Down;
+            
+            _keymap[NSDeleteFunctionKey]        = osgGA::GUIEventAdapter::KEY_Delete;
+            
+            _keymap[NSF1FunctionKey]  = osgGA::GUIEventAdapter::KEY_F1;
+            _keymap[NSF2FunctionKey]  = osgGA::GUIEventAdapter::KEY_F2;
+            _keymap[NSF3FunctionKey]  = osgGA::GUIEventAdapter::KEY_F3;
+            _keymap[NSF4FunctionKey]  = osgGA::GUIEventAdapter::KEY_F4;
+            _keymap[NSF5FunctionKey]  = osgGA::GUIEventAdapter::KEY_F5;
+            _keymap[NSF6FunctionKey]  = osgGA::GUIEventAdapter::KEY_F6;
+            _keymap[NSF7FunctionKey]  = osgGA::GUIEventAdapter::KEY_F7;
+            _keymap[NSF8FunctionKey]  = osgGA::GUIEventAdapter::KEY_F8;
+            _keymap[NSF9FunctionKey]  = osgGA::GUIEventAdapter::KEY_F9;
+            
+            _keymap[NSF10FunctionKey]  = osgGA::GUIEventAdapter::KEY_F10;
+            _keymap[NSF11FunctionKey]  = osgGA::GUIEventAdapter::KEY_F11;
+            _keymap[NSF12FunctionKey]  = osgGA::GUIEventAdapter::KEY_F12;
+            _keymap[NSF13FunctionKey]  = osgGA::GUIEventAdapter::KEY_F13;
+            _keymap[NSF14FunctionKey]  = osgGA::GUIEventAdapter::KEY_F14;
+            _keymap[NSF15FunctionKey]  = osgGA::GUIEventAdapter::KEY_F15;
+            _keymap[NSF16FunctionKey]  = osgGA::GUIEventAdapter::KEY_F16;
+            _keymap[NSF17FunctionKey]  = osgGA::GUIEventAdapter::KEY_F17;
+            _keymap[NSF18FunctionKey]  = osgGA::GUIEventAdapter::KEY_F18;
+            _keymap[NSF19FunctionKey]  = osgGA::GUIEventAdapter::KEY_F19;
+           
+            _keymap[NSF20FunctionKey]  = osgGA::GUIEventAdapter::KEY_F20;
+            _keymap[NSF21FunctionKey]  = osgGA::GUIEventAdapter::KEY_F21;
+            _keymap[NSF22FunctionKey]  = osgGA::GUIEventAdapter::KEY_F22;
+            _keymap[NSF23FunctionKey]  = osgGA::GUIEventAdapter::KEY_F23;
+            _keymap[NSF24FunctionKey]  = osgGA::GUIEventAdapter::KEY_F24;
+            _keymap[NSF25FunctionKey]  = osgGA::GUIEventAdapter::KEY_F25;
+            _keymap[NSF26FunctionKey]  = osgGA::GUIEventAdapter::KEY_F26;
+            _keymap[NSF27FunctionKey]  = osgGA::GUIEventAdapter::KEY_F27;
+            _keymap[NSF28FunctionKey]  = osgGA::GUIEventAdapter::KEY_F28;
+            _keymap[NSF29FunctionKey]  = osgGA::GUIEventAdapter::KEY_F29;
+            
+            _keymap[NSF30FunctionKey]  = osgGA::GUIEventAdapter::KEY_F30;
+            _keymap[NSF31FunctionKey]  = osgGA::GUIEventAdapter::KEY_F31;
+            _keymap[NSF32FunctionKey]  = osgGA::GUIEventAdapter::KEY_F32;
+            _keymap[NSF33FunctionKey]  = osgGA::GUIEventAdapter::KEY_F33;
+            _keymap[NSF34FunctionKey]  = osgGA::GUIEventAdapter::KEY_F34;
+            _keymap[NSF35FunctionKey]  = osgGA::GUIEventAdapter::KEY_F35;
+                        
+            
+            _keypadmap['='] = osgGA::GUIEventAdapter::KEY_KP_Equal;
+            _keypadmap['*'] = osgGA::GUIEventAdapter::KEY_KP_Multiply;
+            _keypadmap['+'] = osgGA::GUIEventAdapter::KEY_KP_Add;
+            _keypadmap['-'] = osgGA::GUIEventAdapter::KEY_KP_Subtract;
+            _keypadmap['.'] = osgGA::GUIEventAdapter::KEY_KP_Decimal;
+            _keypadmap['/'] = osgGA::GUIEventAdapter::KEY_KP_Divide;
+            
+            _keypadmap['0'] = osgGA::GUIEventAdapter::KEY_KP_0;
+            _keypadmap['1'] = osgGA::GUIEventAdapter::KEY_KP_1;
+            _keypadmap['2'] = osgGA::GUIEventAdapter::KEY_KP_2;
+            _keypadmap['3'] = osgGA::GUIEventAdapter::KEY_KP_3;
+            _keypadmap['4'] = osgGA::GUIEventAdapter::KEY_KP_4;
+            _keypadmap['5'] = osgGA::GUIEventAdapter::KEY_KP_5;
+            _keypadmap['6'] = osgGA::GUIEventAdapter::KEY_KP_6;
+            _keypadmap['7'] = osgGA::GUIEventAdapter::KEY_KP_7;
+            _keypadmap['8'] = osgGA::GUIEventAdapter::KEY_KP_8;
+            _keypadmap['9'] = osgGA::GUIEventAdapter::KEY_KP_9;
+        }
+        
+        ~CocoaKeyboardMap() {
+        }
+        
+        unsigned int remapKey(unsigned int key, bool pressedOnKeypad = false)
+        {
+            if (pressedOnKeypad) {
+                 KeyMap::iterator itr = _keypadmap.find(key);
+                if (itr == _keypadmap.end()) return key;
+                else return itr->second;
+            }
+            
+            KeyMap::iterator itr = _keymap.find(key);
+            if (itr == _keymap.end()) return key;
+            else return itr->second;
+        }
+    private:
+        typedef std::map<unsigned int, osgGA::GUIEventAdapter::KeySymbol> KeyMap;
+        KeyMap _keymap, _keypadmap;
+};
+
+
+// ----------------------------------------------------------------------------------------------------------
+// remapCocoaKey
+// ----------------------------------------------------------------------------------------------------------
+static unsigned int remapCocoaKey(unsigned int key, bool pressedOnKeypad = false)
+{
+    static CocoaKeyboardMap s_CocoaKeyboardMap;
+    return s_CocoaKeyboardMap.remapKey(key, pressedOnKeypad);
+}
+
+
+std::ostream& operator<<(std::ostream& os, const NSRect& rect) 
+{
+	os << rect.origin.x << "/" << rect.origin.y << " " << rect.size.width << "x" << rect.size.height;
+	return os;
+}
+
+// ----------------------------------------------------------------------------------------------------------
+// Cocoa uses a coordinate system where its origin is in the bottom left corner, 
+// osg and quartz uses top left for the origin
+//
+// these 2 methods convets rects between the different coordinate systems
+// ----------------------------------------------------------------------------------------------------------
+
+static NSRect convertFromQuartzCoordinates(const NSRect& rect)  
+{
+    NSRect frame = [[[NSScreen screens] objectAtIndex: 0] frame];
+    float y = frame.size.height - rect.origin.y - rect.size.height;
+	NSRect converted = NSMakeRect(rect.origin.x, y, rect.size.width, rect.size.height);
+	
+	// std::cout << "converting from Quartz " << rect << " to " << converted << " using screen rect " << frame << std::endl;
+	
+    return converted;
+}
+
+static NSRect convertToQuartzCoordinates(const NSRect& rect)
+{
+    NSRect frame = [[[NSScreen screens] objectAtIndex: 0] frame];
+    
+    float y = frame.size.height - (rect.origin.y + rect.size.height);
+	NSRect converted = NSMakeRect(rect.origin.x, y, rect.size.width, rect.size.height);
+	
+	// std::cout << "converting To Quartz   " << rect << " to " << converted << " using screen rect " << frame << std::endl;
+	
+    return converted;
+}
+
+#pragma mark CocoaAppDelegate
+
+// ----------------------------------------------------------------------------------------------------------
+// the app-delegate, handling quit-requests
+// ----------------------------------------------------------------------------------------------------------
+
+@interface CocoaAppDelegate : NSObject 
+{
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end
+
+@implementation CocoaAppDelegate
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+    s_quit_requested = true;
+    // std::cout << "quit requested " << std::endl;
+    return NSTerminateNow;
+}
+
+@end
+
+#pragma mark GraphicsWindowCocoaWindow
+
+// ----------------------------------------------------------------------------------------------------------
+// GraphicsWindowCocoaWindow, implements canBecomeKeyWindow + canBecomeMainWindow
+// ----------------------------------------------------------------------------------------------------------
+
+@interface GraphicsWindowCocoaWindow : NSWindow
+{
+}
+
+- (BOOL) canBecomeKeyWindow;
+- (BOOL) canBecomeMainWindow;
+
+@end
+
+@implementation GraphicsWindowCocoaWindow
+
+
+- (BOOL) canBecomeKeyWindow
+{
+    return YES;
+}
+
+- (BOOL) canBecomeMainWindow
+{
+    return YES;
+}
+
+@end
+
+#pragma mark GraphicsWindowCocoaGLView
+
+
+// ----------------------------------------------------------------------------------------------------------
+// GraphicsWindowCocoaGLView
+// custom NSOpenGLView-class handling mouse- and keyboard-events, forwarding them to the EventQueue
+// some code borrowed from the example osgCocoaViewer from E.Wing
+// ----------------------------------------------------------------------------------------------------------
+
+@interface GraphicsWindowCocoaGLView : NSOpenGLView
+{
+    @private
+        osgViewer::GraphicsWindowCocoa* _win;
+        BOOL _isUsingCtrlClick, _isUsingOptionClick;
+        unsigned int _cachedModifierFlags;
+		BOOL _handleTabletEvents;
+        
+}
+- (void)setGraphicsWindowCocoa: (osgViewer::GraphicsWindowCocoa*) win;
+
+- (void)keyDown:(NSEvent *)theEvent;
+- (void)keyUp:(NSEvent *)theEvent;
+- (void)flagsChanged:(NSEvent *)theEvent;
+- (void) mouseMoved:(NSEvent*)theEvent;
+- (void) mouseDown:(NSEvent*)theEvent;
+- (void) mouseDragged:(NSEvent*)theEvent;
+- (void) mouseUp:(NSEvent*)theEvent;
+- (void) rightMouseDown:(NSEvent*)theEvent;
+- (void) rightMouseDragged:(NSEvent*)theEvent;
+- (void) rightMouseUp:(NSEvent*)theEvent;
+- (void) otherMouseDown:(NSEvent*)theEvent;
+- (void) otherMouseDragged:(NSEvent*)theEvent;
+- (void) otherMouseUp:(NSEvent*)theEvent;
+
+- (NSPoint) getLocalPoint: (NSEvent*)theEvent;
+- (void) handleModifiers: (NSEvent*)theEvent;
+- (void) setIsUsingCtrlClick:(BOOL)is_using_ctrl_click;
+- (BOOL) isUsingCtrlClick;
+- (void) setIsUsingOptionClick:(BOOL)is_using_option_click;
+- (BOOL) isUsingOptionClick;
+
+- (void) doLeftMouseButtonDown:(NSEvent*)theEvent;
+- (void) doLeftMouseButtonUp:(NSEvent*)theEvent;
+- (void) doRightMouseButtonDown:(NSEvent*)theEvent;
+- (void) doRightMouseButtonUp:(NSEvent*)theEvent;
+- (void) doMiddleMouseButtonDown:(NSEvent*)theEvent;
+- (void) doExtraMouseButtonDown:(NSEvent*)theEvent buttonNumber:(int)button_number;
+- (void) doMiddleMouseButtonUp:(NSEvent*)theEvent;
+- (void) doExtraMouseButtonUp:(NSEvent*)theEvent buttonNumber:(int)button_number;
+- (void) scrollWheel:(NSEvent*)theEvent;
+
+- (void)tabletPoint:(NSEvent *)theEvent;
+- (void)tabletProximity:(NSEvent *)theEvent;
+- (void)handleTabletEvents:(NSEvent*)theEvent;
+
+- (BOOL)acceptsFirstResponder;
+- (BOOL)becomeFirstResponder;
+- (BOOL)resignFirstResponder;
+
+@end
+
+@implementation GraphicsWindowCocoaGLView 
+
+
+-(void) setGraphicsWindowCocoa: (osgViewer::GraphicsWindowCocoa*) win
+{
+    _win = win;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+  return YES;
+}
+
+- (BOOL)becomeFirstResponder
+{
+  return YES;
+}
+
+- (BOOL)resignFirstResponder
+{
+  return YES;
+}
+
+
+- (NSPoint) getLocalPoint: (NSEvent*)theEvent
+{
+    return  [self convertPoint:[theEvent locationInWindow] fromView:nil];
+}
+
+
+- (void) handleModifiers: (NSEvent*)theEvent
+{
+    unsigned int flags = [theEvent modifierFlags];
+    
+    if (flags == _cachedModifierFlags) 
+        return;
+    
+    const unsigned int masks[] = { 
+        NSShiftKeyMask,
+        NSControlKeyMask,
+        NSAlternateKeyMask,
+        NSCommandKeyMask,
+        NSAlphaShiftKeyMask
+    };
+    
+    const unsigned int keys[] = { 
+        osgGA::GUIEventAdapter::KEY_Shift_L, 
+        osgGA::GUIEventAdapter::KEY_Control_L,
+        osgGA::GUIEventAdapter::KEY_Alt_L,
+        osgGA::GUIEventAdapter::KEY_Super_L,
+        osgGA::GUIEventAdapter::KEY_Caps_Lock
+    };
+    
+    for(unsigned int i = 0; i < 5; ++i) {
+        
+        if ((flags & masks[i]) && !(_cachedModifierFlags & masks[i]))
+        {
+            _win->getEventQueue()->keyPress(keys[i]);
+        }
+        
+        if (!(flags & masks[i]) && (_cachedModifierFlags & masks[i]))
+        {
+            _win->getEventQueue()->keyRelease(keys[i]);
+        }
+    }
+    
+    _cachedModifierFlags = flags;
+    
+}
+
+- (void)flagsChanged:(NSEvent *)theEvent {
+	[self handleModifiers: theEvent];
+}
+
+- (void) mouseMoved:(NSEvent*)theEvent 
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y);
+}
+
+
+
+- (void) mouseDown:(NSEvent*)theEvent
+{
+    // Because many Mac users have only a 1-button mouse, we should provide ways
+    // to access the button 2 and 3 actions of osgViewer.
+    // I will use the Ctrl modifer to represent right-clicking
+    // and Option modifier to represent middle clicking.
+    if([theEvent modifierFlags] & NSControlKeyMask)
+    {
+        [self setIsUsingCtrlClick:YES];
+        [self doRightMouseButtonDown:theEvent];
+    }
+    else if([theEvent modifierFlags] & NSAlternateKeyMask)
+    {
+        [self setIsUsingOptionClick:YES];
+        [self doMiddleMouseButtonDown:theEvent];
+    }
+    else
+    {
+        [self doLeftMouseButtonDown:theEvent];
+    }
+	
+	if ([theEvent subtype] == NSTabletPointEventSubtype) {
+		_handleTabletEvents = true;
+		[self handleTabletEvents:theEvent];
+	}
+}
+
+
+- (void) mouseDragged:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];    
+    _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y);
+	
+	if (_handleTabletEvents)
+		[self handleTabletEvents:theEvent];
+}
+
+
+- (void) mouseUp:(NSEvent*)theEvent
+{
+    // Because many Mac users have only a 1-button mouse, we should provide ways
+    // to access the button 2 and 3 actions of osgViewer.
+    // I will use the Ctrl modifer to represent right-clicking
+    // and Option modifier to represent middle clicking.
+    if([self isUsingCtrlClick] == YES)
+    {
+        [self setIsUsingCtrlClick:NO];
+        [self doRightMouseButtonUp:theEvent];
+    }
+    else if([self isUsingOptionClick] == YES)
+    {
+        [self setIsUsingOptionClick:NO];
+        [self doMiddleMouseButtonUp:theEvent];
+    }
+    else
+    {
+        [self doLeftMouseButtonUp:theEvent];
+    }
+	_handleTabletEvents = false;
+}
+
+- (void) rightMouseDown:(NSEvent*)theEvent
+{
+    [self doRightMouseButtonDown:theEvent];
+}
+
+- (void) rightMouseDragged:(NSEvent*)theEvent
+{
+   
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y);
+}
+
+- (void) rightMouseUp:(NSEvent*)theEvent
+{
+    [self doRightMouseButtonUp:theEvent];
+	_handleTabletEvents = false;
+}
+
+// "otherMouse" seems to capture middle button and any other buttons beyond (4th, etc).
+- (void) otherMouseDown:(NSEvent*)theEvent
+{
+    // Button 0 is left
+    // Button 1 is right
+    // Button 2 is middle
+    // Button 3 keeps going
+    // osgViewer expects 1 for left, 3 for right, 2 for middle
+    // osgViewer has a reversed number mapping for right and middle compared to Cocoa
+    if([theEvent buttonNumber] == 2)
+    {
+        [self doMiddleMouseButtonDown:theEvent];
+    }
+    else // buttonNumber should be 3,4,5,etc; must map to 4,5,6,etc in osgViewer
+    {
+        [self doExtraMouseButtonDown:theEvent buttonNumber:[theEvent buttonNumber]];
+    }
+}
+
+- (void) otherMouseDragged:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];    
+    _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y);
+   
+}
+
+// "otherMouse" seems to capture middle button and any other buttons beyond (4th, etc).
+- (void) otherMouseUp:(NSEvent*)theEvent
+{
+    
+    // Button 0 is left
+    // Button 1 is right
+    // Button 2 is middle
+    // Button 3 keeps going
+    // osgViewer expects 1 for left, 3 for right, 2 for middle
+    // osgViewer has a reversed number mapping for right and middle compared to Cocoa
+    if([theEvent buttonNumber] == 2)
+    {
+        [self doMiddleMouseButtonUp:theEvent];
+    }
+    else // buttonNumber should be 3,4,5,etc; must map to 4,5,6,etc in osgViewer
+    {
+        // I don't think osgViewer does anything for these additional buttons,
+        // but just in case, pass them along. But as a Cocoa programmer, you might 
+        // think about things you can do natively here instead of passing the buck.
+        [self doExtraMouseButtonUp:theEvent buttonNumber:[theEvent buttonNumber]];
+    }
+}
+
+- (void) setIsUsingCtrlClick:(BOOL)is_using_ctrl_click
+{
+    _isUsingCtrlClick = is_using_ctrl_click;
+}
+
+- (BOOL) isUsingCtrlClick
+{
+    return _isUsingCtrlClick;
+}
+
+- (void) setIsUsingOptionClick:(BOOL)is_using_option_click
+{
+    _isUsingOptionClick = is_using_option_click;
+}
+
+- (BOOL) isUsingOptionClick
+{
+    return _isUsingOptionClick;
+}
+
+
+- (void) doLeftMouseButtonDown:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    
+    if([theEvent clickCount] == 1)
+    {
+        _win->getEventQueue()->mouseButtonPress(converted_point.x, converted_point.y, 1);
+    }
+    else
+    {
+        _win->getEventQueue()->mouseDoubleButtonPress(converted_point.x, converted_point.y, 1);
+    }
+}
+
+- (void) doLeftMouseButtonUp:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    
+    _win->getEventQueue()->mouseButtonRelease(converted_point.x, converted_point.y, 1);
+
+}
+
+- (void) doRightMouseButtonDown:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    if([theEvent clickCount] == 1)
+    {
+        _win->getEventQueue()->mouseButtonPress(converted_point.x, converted_point.y, 3);
+    }
+    else
+    {
+        _win->getEventQueue()->mouseDoubleButtonPress(converted_point.x, converted_point.y, 3);
+    }
+
+}
+
+
+- (void) doRightMouseButtonUp:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];    
+    _win->getEventQueue()->mouseButtonRelease(converted_point.x, converted_point.y, 3);
+}
+
+- (void) doMiddleMouseButtonDown:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    
+    if([theEvent clickCount] == 1)
+    {
+        _win->getEventQueue()->mouseButtonPress(converted_point.x, converted_point.y, 2);
+    }
+    else
+    {
+        _win->getEventQueue()->mouseDoubleButtonPress(converted_point.x, converted_point.y, 2);
+    }
+}
+
+- (void) doExtraMouseButtonDown:(NSEvent*)theEvent buttonNumber:(int)button_number
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    if([theEvent clickCount] == 1)
+    {
+        _win->getEventQueue()->mouseButtonPress(converted_point.x, converted_point.y, button_number+1);
+    }
+    else
+    {
+        _win->getEventQueue()->mouseDoubleButtonPress(converted_point.x, converted_point.y, button_number+1);
+    }
+}
+
+
+- (void) doMiddleMouseButtonUp:(NSEvent*)theEvent
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    _win->getEventQueue()->mouseButtonRelease(converted_point.x, converted_point.y, 2);
+
+}
+
+- (void) doExtraMouseButtonUp:(NSEvent*)theEvent buttonNumber:(int)button_number
+{
+    NSPoint converted_point = [self getLocalPoint: theEvent];
+    _win->getEventQueue()->mouseButtonRelease(converted_point.x, converted_point.y, button_number+1);
+}
+
+
+
+- (void) scrollWheel:(NSEvent*)theEvent
+{
+    // Unfortunately, it turns out mouseScroll2D doesn't actually do anything.
+    // The camera manipulators don't seem to implement any code that utilize the scroll values.
+    // This this call does nothing.
+    _win->getEventQueue()->mouseScroll2D([theEvent deltaX], [theEvent deltaY]);
+}
+
+
+
+- (void)keyDown:(NSEvent *)theEvent 
+{
+    NSString* chars = [theEvent charactersIgnoringModifiers]; 
+    unsigned int keyCode = remapCocoaKey([chars characterAtIndex:0], ([theEvent modifierFlags] & NSFunctionKeyMask) );
+    // std::cout << "key dn: " <<[chars characterAtIndex:0] << "=" << keyCode << std::endl;   
+    _win->getEventQueue()->keyPress( remapCocoaKey(keyCode), [theEvent timestamp]);
+}
+
+
+- (void)keyUp:(NSEvent *)theEvent 
+{   
+    NSString* chars = [theEvent charactersIgnoringModifiers]; 
+    unsigned int keyCode = remapCocoaKey([chars characterAtIndex:0], ([theEvent modifierFlags] & NSFunctionKeyMask));
+    // std::cout << "key up: " <<[chars characterAtIndex:0] << "=" << keyCode << std::endl;   
+    _win->getEventQueue()->keyRelease( remapCocoaKey(keyCode), [theEvent timestamp]);
+}
+
+
+- (void)tabletPoint:(NSEvent *)theEvent
+{
+	//_handleTabletEvents = YES;
+	//[self handleTabletEvents:theEvent];
+}
+
+-(void)handleTabletEvents:(NSEvent *)theEvent
+{
+	float pressure = [theEvent pressure];
+	_win->getEventQueue()->penPressure(pressure);
+	NSPoint tilt = [theEvent tilt];
+	
+	_win->getEventQueue()->penOrientation (tilt.x, tilt.y, [theEvent rotation]);
+}
+
+
+- (void)tabletProximity:(NSEvent *)theEvent
+{
+	osgGA::GUIEventAdapter::TabletPointerType pt(osgGA::GUIEventAdapter::UNKNOWN);
+	switch ([theEvent pointingDeviceType]) {
+		case NSPenPointingDevice:
+			pt = osgGA::GUIEventAdapter::PEN;
+			break;
+		case NSCursorPointingDevice:
+			pt = osgGA::GUIEventAdapter::PUCK;
+			break;
+		case NSEraserPointingDevice:
+			pt = osgGA::GUIEventAdapter::ERASER;
+			break;
+		default:
+			break;
+	}
+	_win->getEventQueue()->penProximity(pt, [theEvent isEnteringProximity]); 
+}
+
+
+@end
+
+
+#pragma mark GraphicsWindowCocoaDelegate
+
+
+// ----------------------------------------------------------------------------------------------------------
+// the window-delegate, handles moving/resizing of the window etc.
+// ----------------------------------------------------------------------------------------------------------
+
+@interface GraphicsWindowCocoaDelegate : NSObject
+{
+    @private
+        osgViewer::GraphicsWindowCocoa* _win;
+        BOOL                            _inDidMove;
+}
+
+- (id)initWith: (osgViewer::GraphicsWindowCocoa*) win;
+- (void)windowDidMove:(NSNotification *)notification;
+- (void)windowDidResize:(NSNotification *)notification;
+- (BOOL)windowShouldClose:(id)window;
+- (void)updateWindowBounds;
+
+@end
+
+
+@implementation GraphicsWindowCocoaDelegate
+
+- (id)initWith: (osgViewer::GraphicsWindowCocoa*) win
+{
+    _inDidMove = false;
+    _win = win;
+    return [super init];
+}
+
+
+- (void)windowDidMove:(NSNotification *)notification
+{
+    [self updateWindowBounds];
+}
+
+- (void)windowDidResize:(NSNotification *)notification
+{
+    [self updateWindowBounds];
+}
+
+-(void)updateWindowBounds
+{
+    if (_inDidMove) return;
+    _inDidMove = true;
+    
+    GraphicsWindowCocoaWindow* nswin = _win->getWindow();
+    NSRect bounds = [nswin contentRectForFrameRect: [nswin frame] ];
+    
+    // convert to quartz-coordinate-system
+    bounds = convertToQuartzCoordinates(bounds);
+    
+    // std::cout << "windowdidmove: " << bounds.origin.x << " " << bounds.origin.y << " " << bounds.size.width << " " << bounds.size.height << std::endl;
+   
+    _win->adaptResize(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
+    //_win->getEventQueue()->windowResize(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height, _win->getEventQueue()->getTime());
+    _win->requestRedraw();
+    _inDidMove = false;
+}
+
+- (BOOL)windowShouldClose:(id)window 
+{
+    return _win->requestClose();
+}
+
+@end
+
+
+#pragma mark CocoaWindowAdapter
+
+
+
+using namespace osgDarwin;
+namespace osgViewer {
+
+
+// ----------------------------------------------------------------------------------------------------------
+// small adapter class to handle the dock/menubar
+// ----------------------------------------------------------------------------------------------------------
+
+class CocoaWindowAdapter : public MenubarController::WindowAdapter {
+public:
+    CocoaWindowAdapter(GraphicsWindowCocoa* win) : MenubarController::WindowAdapter(), _win(win) {}
+    
+    virtual bool valid() { return (_win.valid() && _win->valid()); }
+	
+    virtual void getWindowBounds(CGRect& rect) 
+    {
+        NSRect nsrect = [_win->getWindow() frame];
+        nsrect = convertToQuartzCoordinates(nsrect);
+        
+        rect.origin.x = nsrect.origin.x;
+        rect.origin.y = nsrect.origin.y;
+        rect.size.width = nsrect.size.width;
+        rect.size.height = nsrect.size.height;
+    }
+	
+    virtual osgViewer::GraphicsWindow* getWindow() {return _win.get(); }
+private:
+    osg::observer_ptr<GraphicsWindowCocoa> _win;
+};
+
+#pragma mark GraphicsWindowCocoa
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// init
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::init()
+{
+    if (_initialized) return;
+
+    _closeRequested = false;
+    _ownsWindow = false;
+    _context = NULL;
+    _window = NULL;
+    _valid = _initialized = true;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setupNSWindow
+// sets up the NSWindow, adds delegates, etc
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::setupNSWindow(NSWindow* win)
+{
+
+    [win setReleasedWhenClosed:NO];
+	[win setDisplaysWhenScreenProfileChanges:YES];	
+    GraphicsWindowCocoaDelegate* delegate = [[GraphicsWindowCocoaDelegate alloc] initWith: this];
+    [win setDelegate: delegate ];
+    //[delegate autorelease];
+	    
+    [win makeKeyAndOrderFront:nil];
+    [win setAcceptsMouseMovedEvents: YES];
+
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// realizeImplementation, creates the window + context
+// ----------------------------------------------------------------------------------------------------------
+
+bool GraphicsWindowCocoa::realizeImplementation()
+{
+    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+    
+    unsigned int style(NSBorderlessWindowMask);
+    
+    if (_traits->windowDecoration) {
+        style = NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask;
+        
+        // supportsResize works only with windows with titlebar
+        if (_traits->supportsResize) 
+            style |= NSResizableWindowMask;
+    }
+    	
+    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface());
+    int screenLeft(0), screenTop(0);
+    if (wsi) {
+        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop);
+    }
+    
+	NSRect rect = NSMakeRect(_traits->x + screenLeft, _traits->y + screenTop, _traits->width, _traits->height);
+    
+	_window = [[GraphicsWindowCocoaWindow alloc] initWithContentRect: rect styleMask: style backing: NSBackingStoreBuffered defer: NO];
+	
+    if (!_window) {
+        osg::notify(osg::WARN) << "GraphicsWindowCocoa::realizeImplementation :: could not create window" << std::endl;
+        return false;
+    }
+    
+    rect = convertFromQuartzCoordinates(rect);
+    [_window setFrameOrigin: rect.origin];
+	 
+	NSOpenGLPixelFormatAttribute attr[32];
+    int i = 0;
+    
+    attr[i++] = NSOpenGLPFADepthSize;
+    attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->depth);
+
+    if (_traits->doubleBuffer) {
+        attr[i++] = NSOpenGLPFADoubleBuffer;
+    }
+    
+    if (_traits->alpha) { 
+        attr[i++] = NSOpenGLPFAAlphaSize;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->alpha);
+    }
+
+    if (_traits->stencil) {
+        attr[i++] = NSOpenGLPFAStencilSize;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->stencil);
+    }
+  
+
+    if (_traits->sampleBuffers) {
+        attr[i++] = NSOpenGLPFASampleBuffers;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->sampleBuffers);
+        attr[i++] = NSOpenGLPFASamples;
+        attr[i++] = static_cast<NSOpenGLPixelFormatAttribute>(_traits->samples);
+    }
+
+    
+    attr[i++] = NSOpenGLPFAAccelerated;
+    attr[i] = static_cast<NSOpenGLPixelFormatAttribute>(0);
+    
+    // create the context
+    NSOpenGLContext* sharedContext = NULL;
+    
+    GraphicsWindowCocoa* graphicsWindowCocoa = dynamic_cast<GraphicsWindowCocoa*>(_traits->sharedContext);
+    if (graphicsWindowCocoa) 
+    {
+        sharedContext = graphicsWindowCocoa->getContext();
+    }
+    else
+    {
+        PixelBufferCocoa* pixelbuffer = dynamic_cast<PixelBufferCocoa*>(_traits->sharedContext);
+        if (pixelbuffer) {
+            sharedContext = pixelbuffer->getContext();
+        }
+    }
+	
+	NSOpenGLPixelFormat* pixelformat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr ];
+    _context = [[NSOpenGLContext alloc] initWithFormat: pixelformat shareContext: sharedContext];
+    
+    if (!_context) {
+        osg::notify(osg::WARN) << "GraphicsWindowCocoa::realizeImplementation :: could not create context" << std::endl;
+        return false;
+    }
+	GraphicsWindowCocoaGLView* theView = [[ GraphicsWindowCocoaGLView alloc ] initWithFrame:[ _window frame ] ];
+    [theView setAutoresizingMask:  (NSViewWidthSizable | NSViewHeightSizable) ];
+    [theView setGraphicsWindowCocoa: this];
+    [theView setOpenGLContext:_context];
+	[_window setContentView: theView];
+	
+    setupNSWindow(_window);
+    
+    [theView release];
+    [pool release];
+	
+    MenubarController::instance()->attachWindow( new CocoaWindowAdapter(this) );
+    
+    useCursor(_traits->useCursor);
+    setWindowName(_traits->windowName);
+    setVSync(_traits->vsync);
+    
+    MenubarController::instance()->update();
+    
+    // Cocoa's origin is bottom/left:
+    getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
+    
+    _valid = _initialized = _realized = true;
+    return _valid;
+}
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// closeImplementation
+// ----------------------------------------------------------------------------------------------------------
+void GraphicsWindowCocoa::closeImplementation()
+{
+    _valid = false;
+    _realized = false;
+    
+    // there's a possibility that the MenubarController is destructed already, so prevent a crash:
+    MenubarController* mbc = MenubarController::instance();
+    if (mbc) mbc->detachWindow(this);
+    
+	[_window close];
+    [_window release];
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// makeCurrentImplementation
+// ----------------------------------------------------------------------------------------------------------
+
+bool GraphicsWindowCocoa:: makeCurrentImplementation()
+{
+	[_context makeCurrentContext];
+	return true;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// releaseContextImplementation
+// ----------------------------------------------------------------------------------------------------------
+
+bool GraphicsWindowCocoa::releaseContextImplementation()
+{
+	[NSOpenGLContext clearCurrentContext];
+	return true;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// swapBuffersImplementation
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::swapBuffersImplementation()
+{
+	[_context flushBuffer];
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// checkEvents
+// process all pending events 
+// ----------------------------------------------------------------------------------------------------------
+void GraphicsWindowCocoa::checkEvents()
+{
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    while(1)
+    {
+        /*  NOTE: It may be better to use something like
+            NSEventTrackingRunLoopMode since we don't necessarily want all
+            timers/sources/observers to run, only those which would
+            run while tracking events.  However, it should be noted that
+            NSEventTrackingRunLoopMode is in the common set of modes
+            so it may not effectively make much of a difference.
+         */
+        NSEvent *event = [ [NSApplication sharedApplication]
+                nextEventMatchingMask:NSAnyEventMask
+                untilDate:[NSDate distantPast]
+                inMode:NSDefaultRunLoopMode
+                dequeue: YES];
+        if(!event)
+            break;
+        [[NSApplication sharedApplication] sendEvent: event];
+    }	
+    
+    if (_closeRequested)
+        getEventQueue()->closeWindow();
+        
+    if (s_quit_requested) {
+        getEventQueue()->quitApplication();
+        s_quit_requested = false;
+    }
+        
+	[pool release];
+}
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setWindowDecorationImplementation
+//
+// unfortunately there's no way to change the decoration of a window, so we create an new one 
+// and swap the content
+// ----------------------------------------------------------------------------------------------------------
+
+bool GraphicsWindowCocoa::setWindowDecorationImplementation(bool flag)
+{
+    if (!_realized) return false;
+	
+    unsigned int style(NSBorderlessWindowMask);
+    
+    if (flag) {
+        style = NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask;
+        
+        // supportsResize works only with windows with titlebar
+        if (_traits->supportsResize) 
+            style |= NSResizableWindowMask;
+    }
+	NSRect rect = [_window contentRectForFrameRect: [_window frame] ];
+	GraphicsWindowCocoaWindow* new_win = [[GraphicsWindowCocoaWindow alloc] initWithContentRect: rect styleMask: style backing: NSBackingStoreBuffered defer: NO];
+    
+    if (new_win) {
+        [new_win setContentView: [_window contentView]];
+        setupNSWindow(new_win);
+        [new_win setTitle: [_window title]];
+        [_window close];
+        [_window release];
+
+        _window = new_win;
+        [_window makeKeyAndOrderFront: nil];
+    }
+    
+	return true;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// grabFocus
+// ----------------------------------------------------------------------------------------------------------
+void GraphicsWindowCocoa::grabFocus()
+{
+	[_window makeKeyAndOrderFront: nil];
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// grabFocusIfPointerInWindow
+// ----------------------------------------------------------------------------------------------------------
+void GraphicsWindowCocoa::grabFocusIfPointerInWindow()
+{
+	osg::notify(osg::INFO) << "GraphicsWindowCocoa :: grabFocusIfPointerInWindow not implemented yet " << std::endl;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// resizedImplementation
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::resizedImplementation(int x, int y, int width, int height)
+{
+	std::cout << "resized implementation" << x << " " << y << " " << width << " " << height << std::endl; 
+	GraphicsContext::resizedImplementation(x, y, width, height);
+   
+    [_context update];
+    MenubarController::instance()->update();
+	getEventQueue()->windowResize(x,y,width, height, getEventQueue()->getTime());
+}
+
+
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setWindowRectangleImplementation
+// ----------------------------------------------------------------------------------------------------------
+bool GraphicsWindowCocoa::setWindowRectangleImplementation(int x, int y, int width, int height)
+{
+	DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface());
+    int screenLeft(0), screenTop(0);
+    if (wsi) {
+        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop);
+    }
+
+
+    NSRect rect = NSMakeRect(x+screenLeft,y+screenTop,width, height);
+    rect = convertFromQuartzCoordinates(rect);
+    
+    [_window setFrame: [NSWindow frameRectForContentRect: rect styleMask: [_window styleMask]] display: YES];
+    [_context update];
+    MenubarController::instance()->update();
+    
+    return true;
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// 
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::adaptResize(int x, int y, int w, int h)
+{
+
+	DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface());
+    int screenLeft(0), screenTop(0);
+    if (wsi) {
+		
+		// get the screen containing the window
+		unsigned int screenNdx = wsi->getScreenContaining(x,y,w,h);
+		
+		// update traits
+		_traits->screenNum = screenNdx;
+		
+		// get top left of screen
+        wsi->getScreenTopLeft((*_traits), screenLeft, screenTop);
+    }
+	
+	resized(x-screenLeft,y-screenTop,w,h);
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setWindowName
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::setWindowName (const std::string & name)
+{
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    NSString* title = [NSString stringWithCString: name.c_str() encoding: NSUTF8StringEncoding];
+	[_window setTitle: title];
+	[title release];
+    [pool release];
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// useCursor
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::useCursor(bool cursorOn)
+{
+	if (_traits.valid())
+        _traits->useCursor = cursorOn;
+    DarwinWindowingSystemInterface* wsi = dynamic_cast<DarwinWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface());
+    if (wsi == NULL) {
+        osg::notify(osg::WARN) << "GraphicsWindowCarbon::useCursor :: could not get OSXCarbonWindowingSystemInterface" << std::endl;
+        return;
+    }
+    
+    CGDirectDisplayID displayId = wsi->getDisplayID((*_traits));
+    CGDisplayErr err = kCGErrorSuccess;
+    switch (cursorOn)
+    {
+        case true:
+            err = CGDisplayShowCursor(displayId);
+            break;
+        case false:
+            err = CGDisplayHideCursor(displayId);
+            break;
+    }
+    if (err != kCGErrorSuccess) {
+        osg::notify(osg::WARN) << "GraphicsWindowCocoa::useCursor failed with " << err << std::endl;
+    }
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setCursor
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::setCursor(MouseCursor mouseCursor)
+{
+	switch (mouseCursor) 
+    {
+
+        case NoCursor:
+            [NSCursor hide];
+            break;
+    
+        case LeftArrowCursor:
+            [[NSCursor arrowCursor] set];
+            break;
+        
+        case TextCursor:
+            [[NSCursor IBeamCursor] set];
+            break;
+            
+        case CrosshairCursor:
+            [[NSCursor crosshairCursor] set];
+            break;
+        
+        default:
+            osg::notify(osg::INFO) << "GraphicsWindowCocoa::setCursor :: unsupported MouseCursor: " << mouseCursor << std::endl;    
+    }
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// setVSync
+// ----------------------------------------------------------------------------------------------------------
+
+void GraphicsWindowCocoa::setVSync(bool f) 
+{
+    GLint VBL(f?1:0);
+	[_context setValues:&VBL forParameter:NSOpenGLCPSwapInterval];
+}
+
+
+// ----------------------------------------------------------------------------------------------------------
+// d'tor
+// ----------------------------------------------------------------------------------------------------------
+
+GraphicsWindowCocoa::~GraphicsWindowCocoa() 
+{
+}
+
+
+
+#pragma mark CocoaWindowingSystemInterface
+
+// ----------------------------------------------------------------------------------------------------------
+// CocoaWindowingSystemInterface
+// ----------------------------------------------------------------------------------------------------------
+
+struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface {
+	
+	CocoaWindowingSystemInterface()
+	:	DarwinWindowingSystemInterface() 
+	{
+		localPool = [[NSAutoreleasePool alloc] init];
+        [[NSApplication sharedApplication] setDelegate: [[CocoaAppDelegate alloc] init] ];
+	}
+	
+	virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) 
+	{
+		return createGraphicsContextImplementation<PixelBufferCocoa, GraphicsWindowCocoa>(traits);
+	}
+	
+	virtual ~CocoaWindowingSystemInterface() 
+	{
+		[localPool release];
+	}
+	
+	NSAutoreleasePool *localPool;
+
+};
+
+
+}
+
+#ifdef USE_DARWIN_COCOA_IMPLEMENTATION
+RegisterWindowingSystemInterfaceProxy<osgViewer::CocoaWindowingSystemInterface> createWindowingSystemInterfaceProxy;
+#endif
+
+// declare C entry point for static compilation.
+extern "C" void graphicswindow_Cocoa(void)
+{
+    osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::CocoaWindowingSystemInterface());
+}
Index: /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.mm
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.mm (revision 9879)
+++ /OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.mm (revision 9879)
@@ -0,0 +1,316 @@
+/*
+ *  DarwinUtils.cpp
+ *  OpenSceneGraph
+ *
+ *  Created by Stephan Huber on 27.06.08.
+ *  Copyright 2008 Stephan Maximilian Huber, digital mind. All rights reserved.
+ *
+ */
+
+#include <osg/Referenced>
+#include <osg/DeleteHandler>
+#include "DarwinUtils.h"
+#include <Cocoa/Cocoa.h>
+
+namespace osgDarwin {
+
+
+static inline CGRect toCGRect(NSRect nsRect)
+{
+	CGRect cgRect;
+
+	cgRect.origin.x = nsRect.origin.x;
+	cgRect.origin.y = nsRect.origin.y;
+	cgRect.size.width = nsRect.size.width;
+	cgRect.size.height = nsRect.size.height;
+
+	return cgRect;
+}
+
+
+MenubarController::MenubarController()
+:	osg::Referenced(), 
+    _list(), 
+    _menubarShown(false),
+    _mutex() 
+{
+	// the following code will query the system for the available rect on the main-display (typically the displaying showing the menubar + the dock
+
+	NSRect rect = [[[NSScreen screens] objectAtIndex: 0] visibleFrame];
+	_availRect = toCGRect(rect);
+	
+	// now we need the rect of the main-display including the menubar and the dock
+	_mainScreenBounds = CGDisplayBounds( CGMainDisplayID() );
+
+
+	// NSRect 0/0 is bottom/left, _mainScreenBounds 0/0 is top/left
+	_availRect.origin.y = _mainScreenBounds.size.height - _availRect.size.height - _availRect.origin.y;
+	
+		
+	// hide the menubar initially
+	SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+}
+
+
+
+
+MenubarController* MenubarController::instance() 
+{
+    static osg::ref_ptr<MenubarController> s_menubar_controller = new MenubarController();
+    return s_menubar_controller.get();
+}
+
+
+void MenubarController::attachWindow(WindowAdapter* win)
+{
+    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
+    _list.push_back(win);
+    update();
+}
+
+
+void MenubarController::detachWindow(osgViewer::GraphicsWindow* win) 
+{
+    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
+    for(WindowList::iterator i = _list.begin(); i != _list.end(); ) {
+        if ((*i)->getWindow() == win)
+            i = _list.erase(i);
+        else 
+            ++i;
+    }
+    update();
+}
+
+// iterate through all open windows and check, if they intersect the area occupied by the menubar/dock, and if so, hide the menubar/dock
+
+void MenubarController::update() 
+{
+    OSErr error(noErr);
+    unsigned int windowsCoveringMenubarArea = 0;    
+    unsigned int windowsIntersectingMainScreen = 0;
+    for(WindowList::iterator i = _list.begin(); i != _list.end(); ) {
+		WindowAdapter* wi = (*i).get();
+        if (wi->valid()) {
+            CGRect windowBounds;
+			wi->getWindowBounds(windowBounds);
+			
+			if (CGRectIntersectsRect(_mainScreenBounds, windowBounds))
+            {
+                ++windowsIntersectingMainScreen;
+                // osg::notify(osg::ALWAYS) << "testing rect " << windowBounds.origin.x << "/" << windowBounds.origin.y << " " << windowBounds.size.width << "x" << windowBounds.size.height << std::endl;
+				// osg::notify(osg::ALWAYS) << "against      " << _availRect.origin.x << "/" << _availRect.origin.y << " " << _availRect.size.width << "x" << _availRect.size.height << std::endl;
+                // the window intersects the main-screen, does it intersect with the menubar/dock?
+                if (((_availRect.origin.y > _mainScreenBounds.origin.y) && (_availRect.origin.y > windowBounds.origin.y)) ||
+                    ((_availRect.origin.x > _mainScreenBounds.origin.x) && (_availRect.origin.x > windowBounds.origin.x)) || 
+                    ((_availRect.size.width < _mainScreenBounds.size.width) && (_availRect.origin.x + _availRect.size.width < windowBounds.origin.x + windowBounds.size.width)) || 
+                    ((_availRect.size.height < _mainScreenBounds.size.height) && (_availRect.origin.y + _availRect.size.height < windowBounds.origin.y + windowBounds.size.height) ))
+                {
+                    ++windowsCoveringMenubarArea;
+                }
+            }
+            
+            ++i;
+        }
+        else
+            i= _list.erase(i);
+    }
+    
+    // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar
+        
+    if (windowsCoveringMenubarArea && _menubarShown)
+        error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+    
+    if (!windowsCoveringMenubarArea && !_menubarShown)
+        error = SetSystemUIMode(kUIModeNormal, 0);
+        _menubarShown = !windowsCoveringMenubarArea;
+    
+    // osg::notify(osg::DEBUG_INFO) << "MenubarController:: " << windowsCoveringMenubarArea << " windows covering the menubar/dock area, " << windowsIntersectingMainScreen << " intersecting mainscreen" << std::endl;
+}
+
+
+
+/** Helper method to get a double value out of a CFDictionary */
+static double getDictDouble (CFDictionaryRef refDict, CFStringRef key)
+{
+	double value;
+	CFNumberRef number_value = (CFNumberRef) CFDictionaryGetValue(refDict, key);
+	if (!number_value) // if can't get a number for the dictionary
+		return -1;  // fail
+	if (!CFNumberGetValue(number_value, kCFNumberDoubleType, &value)) // or if cant convert it
+		return -1; // fail
+	return value; // otherwise return the long value
+}
+
+/** Helper method to get a long value out of a CFDictionary */
+static long getDictLong(CFDictionaryRef refDict, CFStringRef key)        // const void* key?
+{
+	long value = 0;
+	CFNumberRef number_value = (CFNumberRef)CFDictionaryGetValue(refDict, key); 
+	if (!number_value) // if can't get a number for the dictionary
+		return -1;  // fail
+	if (!CFNumberGetValue(number_value, kCFNumberLongType, &value)) // or if cant convert it
+		return -1; // fail
+	return value;
+}
+
+
+
+/** ctor, get a list of all attached displays */
+DarwinWindowingSystemInterface::DarwinWindowingSystemInterface() :
+	_displayCount(0),
+	_displayIds(NULL)
+{
+	ProcessSerialNumber sn = { 0, kCurrentProcess };
+	TransformProcessType(&sn,kProcessTransformToForegroundApplication);
+	SetFrontProcess(&sn);
+	
+	if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr )
+		osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: could not get # of screens" << std::endl;
+		
+	_displayIds = new CGDirectDisplayID[_displayCount];
+	if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr )
+		osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl;
+	
+	}
+
+/** dtor */
+DarwinWindowingSystemInterface::~DarwinWindowingSystemInterface()
+{
+	if (osg::Referenced::getDeleteHandler())
+	{
+		osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
+		osg::Referenced::getDeleteHandler()->flushAll();
+	}
+
+	if (_displayIds) delete[] _displayIds;
+	_displayIds = NULL;
+}
+
+/** @return a CGDirectDisplayID for a ScreenIdentifier */
+CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) {
+	if (si.screenNum < static_cast<int>(_displayCount))
+		return _displayIds[si.screenNum];
+	else {
+		osg::notify(osg::WARN) << "GraphicsWindowCarbon :: invalid screen # " << si.screenNum << ", returning main-screen instead" << std::endl;
+		return _displayIds[0];
+	}
+}
+
+/** @return count of attached screens */
+unsigned int DarwinWindowingSystemInterface::getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) 
+{
+	return _displayCount;
+}
+
+void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution)
+{
+	CGDirectDisplayID id = getDisplayID(si);
+	resolution.width = CGDisplayPixelsWide(id);
+	resolution.height = CGDisplayPixelsHigh(id);
+	resolution.colorDepth = CGDisplayBitsPerPixel(id);
+	resolution.refreshRate = getDictDouble (CGDisplayCurrentMode(id), kCGDisplayRefreshRate);        // Not tested
+	if (resolution.refreshRate<0) resolution.refreshRate = 0;
+}
+
+
+void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) {
+        // Warning! This method has not been tested.
+        resolutionList.clear();
+
+        CGDirectDisplayID displayID = getDisplayID(screenIdentifier);
+        CFArrayRef availableModes = CGDisplayAvailableModes(displayID);
+        unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes);
+        for (unsigned int i=0; i<numberOfAvailableModes; ++i) {
+            // look at each mode in the available list
+            CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, i);
+            osg::GraphicsContext::ScreenSettings tmpSR;
+
+            long width = getDictLong(mode, kCGDisplayWidth);
+            tmpSR.width = width<=0 ? 0 : width;
+            long height = getDictLong(mode, kCGDisplayHeight);
+            tmpSR.height = height<=0 ? 0 : height;
+            long rate = getDictLong(mode, kCGDisplayRefreshRate);
+            tmpSR.refreshRate = rate<=0 ? 0 : rate;
+            long depth = getDictLong(mode, kCGDisplayBitsPerPixel);
+            tmpSR.colorDepth = depth<=0 ? 0 : depth;
+
+            resolutionList.push_back(tmpSR);
+        }
+    }
+
+/** return the top left coord of a specific screen in global screen space */
+void DarwinWindowingSystemInterface::getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y) {
+	CGRect bounds = CGDisplayBounds( getDisplayID(si) );
+	x = static_cast<int>(bounds.origin.x);
+	y = static_cast<int>(bounds.origin.y);
+	
+	// osg::notify(osg::DEBUG_INFO) << "topleft of screen " << si.screenNum <<" " << bounds.origin.x << "/" << bounds.origin.y << std::endl;
+}
+
+
+
+/** implementation of setScreenResolution */
+bool DarwinWindowingSystemInterface::setScreenResolution(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) 
+{ 
+	CGDirectDisplayID displayID = getDisplayID(screenIdentifier);
+	
+	// add next line and on following line replace hard coded depth and refresh rate
+	CGRefreshRate refresh =  getDictDouble (CGDisplayCurrentMode(displayID), kCGDisplayRefreshRate);  
+	CFDictionaryRef display_mode_values =
+		CGDisplayBestModeForParametersAndRefreshRate(
+						displayID, 
+						CGDisplayBitsPerPixel(displayID), 
+						width, height,  
+						refresh,  
+						NULL);
+
+									  
+	CGDisplaySwitchToMode(displayID, display_mode_values);    
+	return true; 
+}
+
+/** implementation of setScreenRefreshRate */
+bool DarwinWindowingSystemInterface::setScreenRefreshRate(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) { 
+	
+	boolean_t  success(false);
+	unsigned width, height;
+	getScreenResolution(screenIdentifier, width, height);
+	
+	CGDirectDisplayID displayID = getDisplayID(screenIdentifier);
+	
+	// add next line and on following line replace hard coded depth and refresh rate
+	CFDictionaryRef display_mode_values =
+		CGDisplayBestModeForParametersAndRefreshRate(
+						displayID, 
+						CGDisplayBitsPerPixel(displayID), 
+						width, height,  
+						refreshRate,  
+						&success);
+
+									  
+	if (success)
+		CGDisplaySwitchToMode(displayID, display_mode_values);    
+		
+	return (success != 0);
+}
+
+
+unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, int w, int h)
+{
+	CGRect rect = CGRectMake(x,y,w,h);
+	for(unsigned int i = 0; i < _displayCount; ++i) {
+		CGRect bounds = CGDisplayBounds( getDisplayID(i) );
+		if (CGRectIntersectsRect(bounds, rect)) {
+			return i;
+		}
+	}
+	
+	return 0;
+}
+
+
+
+
+
+
+}
Index: /OpenSceneGraph/trunk/src/osgViewer/CMakeLists.txt
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/CMakeLists.txt (revision 9671)
+++ /OpenSceneGraph/trunk/src/osgViewer/CMakeLists.txt (revision 9879)
@@ -67,85 +67,102 @@
 
     IF(APPLE)
-        SET(OSG_WINDOWING_SYSTEM "Carbon" CACHE STRING "Windowing system type for graphics window creation, options Carbon or X11.")
+        SET(OSG_WINDOWING_SYSTEM "Carbon" CACHE STRING "Windowing system type for graphics window creation, options Carbon, Cocoa or X11.")
     ELSE(APPLE)
         SET(OSG_WINDOWING_SYSTEM "X11" CACHE STRING "Windowing system type for graphics window creation. options only X11")
     ENDIF(APPLE)
     
-
-    IF(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")
-
-        # FIXME: OS X needs selection mechanism for Cocoa, Carbon, X11
+    IF(${OSG_WINDOWING_SYSTEM} STREQUAL "Cocoa")
+		ADD_DEFINITIONS(-DUSE_DARWIN_COCOA_IMPLEMENTATION)
         SET(LIB_PUBLIC_HEADERS ${LIB_PUBLIC_HEADERS} 
-            ${HEADER_PATH}/api/Carbon/GraphicsWindowCarbon
-            ${HEADER_PATH}/api/Carbon/PixelBufferCarbon
+            ${HEADER_PATH}/api/Cocoa/GraphicsWindowCocoa
+            ${HEADER_PATH}/api/Cocoa/PixelBufferCocoa
         )
         SET(LIB_COMMON_FILES ${LIB_COMMON_FILES} 
-            GraphicsWindowCarbon.cpp
-            PixelBufferCarbon.cpp
+            GraphicsWindowCocoa.mm
+            DarwinUtils.h
+            DarwinUtils.mm
+            PixelBufferCocoa.mm
         )
 
-    ELSE(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")
-
-        # X11 for everybody else
-
-
-        INCLUDE(FindPkgConfig OPTIONAL)
-        IF (PKG_CONFIG_FOUND)
-
-            PKG_CHECK_MODULES(XRANDR xrandr)
+	SET(LIB_EXTRA_LIBS ${COCOA_LIBRARY} ${LIB_EXTRA_LIBS})
+
+    ELSE(${OSG_WINDOWING_SYSTEM} STREQUAL "Cocoa")
+        IF(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")	
+			ADD_DEFINITIONS(-DUSE_DARWIN_CARBON_IMPLEMENTATION)
+            SET(LIB_PUBLIC_HEADERS ${LIB_PUBLIC_HEADERS} 
+                ${HEADER_PATH}/api/Carbon/GraphicsWindowCarbon
+                ${HEADER_PATH}/api/Carbon/PixelBufferCarbon
+            )
+            SET(LIB_COMMON_FILES ${LIB_COMMON_FILES} 
+                GraphicsWindowCarbon.cpp
+                DarwinUtils.h
+                DarwinUtils.mm
+                PixelBufferCarbon.cpp
+            )
+	    SET(LIB_EXTRA_LIBS ${COCOA_LIBRARY} ${LIB_EXTRA_LIBS})
+
+        ELSE(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")
+
+            # X11 for everybody else
+
+
+            INCLUDE(FindPkgConfig OPTIONAL)
+            IF (PKG_CONFIG_FOUND)
+
+                PKG_CHECK_MODULES(XRANDR xrandr)
+                
+                IF (XRANDR_FOUND) 
+                    OPTION(OSGVIEWER_USE_XRANDR "Set to ON to enable Xrandr support for GraphicsWindowX11." ON)
+                ELSE(XRANDR_FOUND) 
+                    SET(OSGVIEWER_USE_XRANDR OFF)
+                ENDIF (XRANDR_FOUND)
+            ELSE(PKG_CONFIG_FOUND)
+                SET(OSGVIEWER_USE_XRANDR OFF)
+            ENDIF(PKG_CONFIG_FOUND)
+
+
+            SET(LIB_PUBLIC_HEADERS ${LIB_PUBLIC_HEADERS}
+                ${HEADER_PATH}/api/X11/GraphicsWindowX11
+                ${HEADER_PATH}/api/X11/PixelBufferX11
+            )
+
+
+            SET(LIB_COMMON_FILES ${LIB_COMMON_FILES} 
+                GraphicsWindowX11.cpp 
+                PixelBufferX11.cpp
+            )
             
-            IF (XRANDR_FOUND) 
-                OPTION(OSGVIEWER_USE_XRANDR "Set to ON to enable Xrandr support for GraphicsWindowX11." ON)
-            ELSE(XRANDR_FOUND) 
-                SET(OSGVIEWER_USE_XRANDR OFF)
-            ENDIF (XRANDR_FOUND)
-        ELSE(PKG_CONFIG_FOUND)
-            SET(OSGVIEWER_USE_XRANDR OFF)
-        ENDIF(PKG_CONFIG_FOUND)
-
-
-        SET(LIB_PUBLIC_HEADERS ${LIB_PUBLIC_HEADERS}
-            ${HEADER_PATH}/api/X11/GraphicsWindowX11
-            ${HEADER_PATH}/api/X11/PixelBufferX11
-        )
-
-
-        SET(LIB_COMMON_FILES ${LIB_COMMON_FILES} 
-            GraphicsWindowX11.cpp 
-            PixelBufferX11.cpp
-        )
-        
-        IF(OSGVIEWER_USE_XRANDR)
-        
-            ADD_DEFINITIONS(-DOSGVIEWER_USE_XRANDR)
-            SET(LIB_PRIVATE_HEADERS ${LIB_PRIVATE_HEADERS} ${XRANDR_INCLUDE_DIRS} )
-
-            IF  (X11_Xrandr_LIB)
-                SET(LIB_EXTRA_LIBS ${X11_Xrandr_LIB} ${LIB_EXTRA_LIBS})
-            ELSE(X11_Xrandr_LIB)
-                SET(LIB_EXTRA_LIBS ${XRANDR_LIBRARIES} ${LIB_EXTRA_LIBS})
-            ENDIF(X11_Xrandr_LIB)
+            IF(OSGVIEWER_USE_XRANDR)
             
-        ENDIF(OSGVIEWER_USE_XRANDR)
-
-        # X11 on Apple requires X11 library plus OpenGL linking hack on Leopard
-        IF(APPLE)
-            # Find GL/glx.h 
-            IF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11/include/GL/glx.h)
-                SET(OPENGL_INCLUDE_DIR /usr/X11/include)
-                SET(OPENGL_LIBRARIES /usr/X11/lib/libGL.dylib)
-            ELSEIF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11R6/include/GL/glx.h)
-                SET(OPENGL_INCLUDE_DIR /usr/X11R6/include)
-                SET(OPENGL_LIBRARIES /usr/X11R6/lib/libGL.dylib)
-            ENDIF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11/include/GL/glx.h)
-            INCLUDE_DIRECTORIES(BEFORE SYSTEM ${OPENGL_INCLUDE_DIR})
-
-            SET(LIB_EXTRA_LIBS ${X11_X11_LIB} ${OPENGL_LIBRARIES} ${LIB_EXTRA_LIBS})
-            SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:${CMAKE_OSX_SYSROOT}/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib")
-        ENDIF(APPLE)
-            
-
-    ENDIF(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")
-
+                ADD_DEFINITIONS(-DOSGVIEWER_USE_XRANDR)
+                SET(LIB_PRIVATE_HEADERS ${LIB_PRIVATE_HEADERS} ${XRANDR_INCLUDE_DIRS} )
+
+                IF  (X11_Xrandr_LIB)
+                    SET(LIB_EXTRA_LIBS ${X11_Xrandr_LIB} ${LIB_EXTRA_LIBS})
+                ELSE(X11_Xrandr_LIB)
+                    SET(LIB_EXTRA_LIBS ${XRANDR_LIBRARIES} ${LIB_EXTRA_LIBS})
+                ENDIF(X11_Xrandr_LIB)
+                
+            ENDIF(OSGVIEWER_USE_XRANDR)
+
+            # X11 on Apple requires X11 library plus OpenGL linking hack on Leopard
+            IF(APPLE)
+                # Find GL/glx.h 
+                IF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11/include/GL/glx.h)
+                    SET(OPENGL_INCLUDE_DIR /usr/X11/include)
+                    SET(OPENGL_LIBRARIES /usr/X11/lib/libGL.dylib)
+                ELSEIF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11R6/include/GL/glx.h)
+                    SET(OPENGL_INCLUDE_DIR /usr/X11R6/include)
+                    SET(OPENGL_LIBRARIES /usr/X11R6/lib/libGL.dylib)
+                ENDIF(EXISTS ${CMAKE_OSX_SYSROOT}/usr/X11/include/GL/glx.h)
+                INCLUDE_DIRECTORIES(BEFORE SYSTEM ${OPENGL_INCLUDE_DIR})
+
+                SET(LIB_EXTRA_LIBS ${X11_X11_LIB} ${OPENGL_LIBRARIES} ${LIB_EXTRA_LIBS})
+                SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:${CMAKE_OSX_SYSROOT}/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib")
+            ENDIF(APPLE)
+                
+
+        ENDIF(${OSG_WINDOWING_SYSTEM} STREQUAL "Carbon")
+    ENDIF(${OSG_WINDOWING_SYSTEM} STREQUAL "Cocoa")
 ENDIF(WIN32)
 
