diff --git a/src/osgViewer/DarwinUtils.h b/src/osgViewer/DarwinUtils.h index cf8ffc2b1..bed2ffa4d 100755 --- a/src/osgViewer/DarwinUtils.h +++ b/src/osgViewer/DarwinUtils.h @@ -90,9 +90,7 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy unsigned int getScreenContaining(int x, int y, int w, int h); protected: - - virtual void _init(); - + /** implementation of setScreenResolution */ bool setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) ; @@ -119,8 +117,6 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy private: - - bool _initialized; CGDisplayCount _displayCount; CGDirectDisplayID* _displayIds; diff --git a/src/osgViewer/DarwinUtils.mm b/src/osgViewer/DarwinUtils.mm index 1bcacfd39..fa909d09e 100755 --- a/src/osgViewer/DarwinUtils.mm +++ b/src/osgViewer/DarwinUtils.mm @@ -221,11 +221,21 @@ static long getDictLong(CFDictionaryRef refDict, CFStringRef key) // cons /** ctor, get a list of all attached displays */ DarwinWindowingSystemInterface::DarwinWindowingSystemInterface() : - _initialized(false), _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() @@ -240,51 +250,12 @@ DarwinWindowingSystemInterface::~DarwinWindowingSystemInterface() _displayIds = NULL; } -void DarwinWindowingSystemInterface::_init() -{ - if (_initialized) return; - - 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; - _displayCount = 0; - - _initialized = true; - return; - } - - _displayIds = new CGDirectDisplayID[_displayCount]; - - if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr ) - { - osg::notify(osg::WARN) << "DarwinWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl; - } - - _initialized = true; -} - /** @return a CGDirectDisplayID for a ScreenIdentifier */ -CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) -{ - _init(); - - if (_displayCount==0) - { - osg::notify(osg::WARN) << "DarwinWindowingSystemInterface::getDisplayID(..) no valid screens available returning 0 instead." << std::endl; - return 0; - } - +CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) { if (si.screenNum < static_cast(_displayCount)) - { return _displayIds[si.screenNum]; - } - else - { - osg::notify(osg::WARN) << "DarwinWindowingSystemInterface::getDisplayID(..) invalid screen # " << si.screenNum << ", returning main-screen instead." << std::endl; + else { + osg::notify(osg::WARN) << "GraphicsWindowCarbon :: invalid screen # " << si.screenNum << ", returning main-screen instead" << std::endl; return _displayIds[0]; } } @@ -292,24 +263,11 @@ CGDirectDisplayID DarwinWindowingSystemInterface::getDisplayID(const osg::Graphi /** @return count of attached screens */ unsigned int DarwinWindowingSystemInterface::getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) { - _init(); - return _displayCount; } void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution) { - _init(); - - if (_displayCount==0) - { - resolution.width = 0; - resolution.height = 0; - resolution.colorDepth = 0; - resolution.refreshRate = 0; - return; - } - CGDirectDisplayID id = getDisplayID(si); resolution.width = CGDisplayPixelsWide(id); resolution.height = CGDisplayPixelsHigh(id); @@ -319,51 +277,33 @@ void DarwinWindowingSystemInterface::getScreenSettings(const osg::GraphicsContex } -void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) -{ - _init(); +void DarwinWindowingSystemInterface::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList) { + // Warning! This method has not been tested. + resolutionList.clear(); - // 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(bounds.origin.x); y = static_cast(bounds.origin.y); @@ -376,10 +316,8 @@ bool DarwinWindowingSystemInterface::setScreenSettings(const osg::GraphicsContex { bool result = setScreenResolutionImpl(si, settings.width, settings.height); if (result) - { setScreenRefreshRateImpl(si, settings.refreshRate); - } - + return result; } @@ -388,13 +326,6 @@ bool DarwinWindowingSystemInterface::setScreenSettings(const osg::GraphicsContex /** implementation of setScreenResolution */ bool DarwinWindowingSystemInterface::setScreenResolutionImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height) { - _init(); - - if (_displayCount==0) - { - return false; - } - CGDirectDisplayID displayid = getDisplayID(screenIdentifier); // add next line and on following line replace hard coded depth and refresh rate @@ -413,15 +344,8 @@ bool DarwinWindowingSystemInterface::setScreenResolutionImpl(const osg::Graphics } /** implementation of setScreenRefreshRate */ -bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) -{ - _init(); - - if (_displayCount==0) - { - return false; - } - +bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, double refreshRate) { + boolean_t success(false); unsigned width, height; getScreenResolution(screenIdentifier, width, height); @@ -447,13 +371,6 @@ bool DarwinWindowingSystemInterface::setScreenRefreshRateImpl(const osg::Graphic unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, int w, int h) { - _init(); - - if (_displayCount==0) - { - return 0; - } - CGRect rect = CGRectMake(x,y,w,h); for(unsigned int i = 0; i < _displayCount; ++i) { CGRect bounds = CGDisplayBounds( getDisplayID(i) ); @@ -465,4 +382,9 @@ unsigned int DarwinWindowingSystemInterface::getScreenContaining(int x, int y, i return 0; } + + + + + } diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index 5e321a1ae..fd93fa1ca 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -11,8 +11,7 @@ * OpenSceneGraph Public License for more details. */ -#if defined (__APPLE__) && (!__LP64__) - +#ifdef __APPLE__ #include #include @@ -25,10 +24,7 @@ #include -#include "DarwinUtils.h" - using namespace osgViewer; -using namespace osgDarwin; // Carbon-Eventhandler to handle the click in the close-widget and the resize of windows @@ -69,7 +65,8 @@ static pascal OSStatus GraphicsWindowEventHandler(EventHandlerCallRef nextHandle // left the code for live-resizing, but it is not used, because of window-refreshing issues... GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds ); - w->adaptResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); + w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); + w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime()); w->requestRedraw(); result = noErr; break; @@ -77,7 +74,8 @@ static pascal OSStatus GraphicsWindowEventHandler(EventHandlerCallRef nextHandle case kEventWindowBoundsChanged: InvalWindowRect(window, GetWindowPortBounds(window, &bounds)); GetWindowBounds(window, kWindowContentRgn, &bounds); - w->adaptResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); + w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); + w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime()); result = noErr; break; @@ -137,10 +135,10 @@ namespace osgViewer // small helper class which maps the raw key codes to osgGA::GUIEventAdapter::Keys -class CarbonKeyboardMap { +class OSXKeyboardMap { public: - CarbonKeyboardMap() + OSXKeyboardMap() { _keymap[53 ] = osgGA::GUIEventAdapter::KEY_Escape; _keymap[115 ] = osgGA::GUIEventAdapter::KEY_Home; @@ -189,7 +187,7 @@ class CarbonKeyboardMap { } - ~CarbonKeyboardMap() { + ~OSXKeyboardMap() { } unsigned int remapKey(unsigned int key, unsigned int rawkey) @@ -204,33 +202,311 @@ class CarbonKeyboardMap { }; /** remaps a native os x keycode to a GUIEventAdapter-keycode */ -static unsigned int remapCarbonKey(unsigned int key, unsigned int rawkey) +static unsigned int remapOSXKey(unsigned int key, unsigned int rawkey) { - static CarbonKeyboardMap s_CarbonKeyboardMap; - return s_CarbonKeyboardMap.remapKey(key,rawkey); + static OSXKeyboardMap s_OSXKeyboardMap; + return s_OSXKeyboardMap.remapKey(key,rawkey); } -class CarbonWindowAdapter : public MenubarController::WindowAdapter { -public: - CarbonWindowAdapter(GraphicsWindowCarbon* win) : MenubarController::WindowAdapter(), _win(win) {} - virtual bool valid() {return (_win.valid() && _win->valid()); } - virtual void getWindowBounds(CGRect& rect) - { - Rect windowBounds; - OSErr error = GetWindowBounds(_win->getNativeWindowRef(), kWindowStructureRgn, &windowBounds); - rect.origin.x = windowBounds.left; - rect.origin.y = windowBounds.top; - rect.size.width = windowBounds.right - windowBounds.left; - rect.size.height = windowBounds.bottom - windowBounds.top; - } + + +#pragma mark * * * MenubarController * * * + +/** 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: + 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 + + GDHandle mainScreenDevice; + + DMGetGDeviceByDisplayID((DisplayIDType) CGMainDisplayID(), &mainScreenDevice, true); + GetAvailableWindowPositioningBounds (mainScreenDevice, &_availRect); + + // now we need the rect of the main-display including the menubar and the dock + _mainScreenBounds = CGDisplayBounds( CGMainDisplayID() ); + + // hide the menubar initially + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + } + + static MenubarController* instance(); + + void attachWindow(GraphicsWindowCarbon* win); + void update(); + void detachWindow(GraphicsWindowCarbon* win); + + private: + typedef std::list< osg::observer_ptr< GraphicsWindowCarbon > > WindowList; + WindowList _list; + bool _menubarShown; + Rect _availRect; + CGRect _mainScreenBounds; + OpenThreads::Mutex _mutex; - osgViewer::GraphicsWindow* getWindow() { return _win.get(); } -private: - osg::observer_ptr _win; }; +MenubarController* MenubarController::instance() +{ + static osg::ref_ptr s_menubar_controller = new MenubarController(); + return s_menubar_controller.get(); +} + + +void MenubarController::attachWindow(GraphicsWindowCarbon* win) +{ + OpenThreads::ScopedLock lock(_mutex); + _list.push_back(win); + update(); +} + + +void MenubarController::detachWindow(GraphicsWindowCarbon* win) +{ + OpenThreads::ScopedLock lock(_mutex); + for(WindowList::iterator i = _list.begin(); i != _list.end(); ) { + if ((*i).get() == 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(); ) { + if ((*i).valid()) { + GraphicsWindowCarbon* w = (*i).get(); + Rect windowBounds; + error = GetWindowBounds(w->getNativeWindowRef(), kWindowStructureRgn, &windowBounds); + + bool intersect = !( (_mainScreenBounds.origin.x > windowBounds.right) || + (_mainScreenBounds.origin.x + _mainScreenBounds.size.width < windowBounds.left) || + (_mainScreenBounds.origin.y > windowBounds.bottom) || + (_mainScreenBounds.origin.y + _mainScreenBounds.size.height < windowBounds.top)); + if (intersect && !error) + { + ++windowsIntersectingMainScreen; + + // the window intersects the main-screen, does it intersect with the menubar/dock? + if (((_availRect.top > _mainScreenBounds.origin.y) && (_availRect.top > windowBounds.top)) || + ((_availRect.left > _mainScreenBounds.origin.x) && (_availRect.left > windowBounds.left)) || + ((_availRect.right < _mainScreenBounds.origin.x + _mainScreenBounds.size.width) && (_availRect.right < windowBounds.right)) || + ((_availRect.bottom < _mainScreenBounds.origin.y + _mainScreenBounds.size.height) && (_availRect.bottom < windowBounds.bottom) )) + { + ++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; +} + + +#pragma mark * * * OSXWindowingSystemInterface * * * + +struct OSXCarbonWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface +{ + + /** ctor, get a list of all attached displays */ + OSXCarbonWindowingSystemInterface() : + _displayCount(0), + _displayIds(NULL) + { + ProcessSerialNumber sn = { 0, kCurrentProcess }; + TransformProcessType(&sn,kProcessTransformToForegroundApplication); + SetFrontProcess(&sn); + + if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr ) + osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: could not get # of screens" << std::endl; + + _displayIds = new CGDirectDisplayID[_displayCount]; + if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr ) + osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl; + + // register application event handler and AppleEventHandler to get quit-events: + static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess}; + OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL); + status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false); + } + + /** dtor */ + ~OSXCarbonWindowingSystemInterface() + { + 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 */ + inline CGDirectDisplayID getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) { + if (si.screenNum < _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 */ + virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) + { + return _displayCount; + } + + /** returns the resolution of a specific display */ + virtual void 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; + } + + /** return the top left coord of a specific screen in global screen space */ + void getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y) { + CGRect bounds = CGDisplayBounds( getDisplayID(si) ); + x = static_cast(bounds.origin.x); + y = static_cast(bounds.origin.y); + + // osg::notify(osg::DEBUG_INFO) << "topleft of screen " << si.screenNum <<" " << bounds.origin.x << "/" << bounds.origin.y << 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; + } + + /** implementation of setScreenSettings */ + virtual bool setScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, const osg::GraphicsContext::ScreenSettings & resolution) + { + CGDirectDisplayID displayID = getDisplayID(screenIdentifier); + + CGRefreshRate refresh = resolution.refreshRate>0 ? resolution.refreshRate : getDictDouble (CGDisplayCurrentMode(displayID), kCGDisplayRefreshRate); + size_t depth = resolution.colorDepth>0 ? resolution.colorDepth : CGDisplayBitsPerPixel(displayID); + CFDictionaryRef display_mode_values = + CGDisplayBestModeForParametersAndRefreshRate( + displayID, + depth, + resolution.width, resolution.height, + refresh, + NULL); + + + CGDisplaySwitchToMode(displayID, display_mode_values); + return true; + } + + virtual void 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; ipbuffer) + { + osg::ref_ptr pbuffer = new PixelBufferCarbon(traits); + if (pbuffer->valid()) return pbuffer.release(); + else return 0; + } + else + { + osg::ref_ptr window = new GraphicsWindowCarbon(traits); + if (window->valid()) return window.release(); + else return 0; + } + } + + + + private: + CGDisplayCount _displayCount; + CGDirectDisplayID* _displayIds; +}; + +} + + +#pragma mark * * * GraphicsWindowCarbon * * * + + + void GraphicsWindowCarbon::init() { @@ -354,11 +630,13 @@ bool GraphicsWindowCarbon::realizeImplementation() useCursor(_traits->useCursor); // move the window to the right screen - DarwinWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); + OSXCarbonWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); int screenLeft(0), screenTop(0); - if (wsi) - { + if (wsi) { + wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); + _traits->y += screenTop; + _traits->x += screenLeft; } WindowData *windowData = ( _traits.get() && _traits->inheritedWindowData.get() ) ? static_cast(_traits->inheritedWindowData.get()) : 0; @@ -368,7 +646,7 @@ bool GraphicsWindowCarbon::realizeImplementation() if (_ownsWindow) { // create the window - Rect bounds = {_traits->y + screenTop, _traits->x + screenLeft, _traits->y + _traits->height + screenTop, _traits->x + _traits->width + screenLeft}; + Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; OSStatus err = 0; WindowAttributes attr = computeWindowAttributes(_useWindowDecoration, _traits->supportsResize); @@ -425,7 +703,7 @@ bool GraphicsWindowCarbon::realizeImplementation() } else { aglSetDrawable(_context, GetWindowPort(_window)); ShowWindow(_window); - MenubarController::instance()->attachWindow( new CarbonWindowAdapter(this) ); + MenubarController::instance()->attachWindow(this); } makeCurrent(); @@ -527,8 +805,6 @@ void GraphicsWindowCarbon::resizedImplementation(int x, int y, int width, int he aglUpdateContext(_context); MenubarController::instance()->update(); - - getEventQueue()->windowResize(x,y,width, height, getEventQueue()->getTime()); } @@ -756,7 +1032,7 @@ bool GraphicsWindowCarbon::handleKeyboardEvent(EventRef theEvent) UniChar* uniChars = new UniChar[dataSize+1]; GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize, NULL, (void*)uniChars ); - unsigned int keychar = remapCarbonKey(static_cast(uniChars[0]), rawkey); + unsigned int keychar = remapOSXKey(static_cast(uniChars[0]), rawkey); switch(GetEventKind(theEvent)) { @@ -897,43 +1173,13 @@ void GraphicsWindowCarbon::checkEvents() bool GraphicsWindowCarbon::setWindowRectangleImplementation(int x, int y, int width, int height) { - int screenLeft(0), screenTop(0); - DarwinWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); - if (wsi) - { - wsi->getScreenTopLeft((*_traits), screenLeft, screenTop); - } - - Rect bounds = {y + screenTop, x + screenLeft, y + height + screenTop, x + width + screenLeft}; + Rect bounds = {y, x, y + height, x + width}; SetWindowBounds(getNativeWindowRef(), kWindowContentRgn, &bounds); aglUpdateContext(_context); MenubarController::instance()->update(); return true; } - - -void GraphicsWindowCarbon::adaptResize(int x, int y, int w, int h) -{ - DarwinWindowingSystemInterface* wsi = dynamic_cast(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); -} - - - void GraphicsWindowCarbon::grabFocus() { SelectWindow(_window); @@ -953,7 +1199,7 @@ void GraphicsWindowCarbon::useCursor(bool cursorOn) if (_traits.valid()) _traits->useCursor = cursorOn; - DarwinWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); + OSXCarbonWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); if (wsi == NULL) { osg::notify(osg::WARN) << "GraphicsWindowCarbon::useCursor :: could not get OSXCarbonWindowingSystemInterface" << std::endl; return; @@ -1028,7 +1274,7 @@ void GraphicsWindowCarbon::setWindowName (const std::string& name) void GraphicsWindowCarbon::requestWarpPointer(float x,float y) { - DarwinWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); + OSXCarbonWindowingSystemInterface* wsi = dynamic_cast(osg::GraphicsContext::getWindowingSystemInterface()); if (wsi == NULL) { osg::notify(osg::WARN) << "GraphicsWindowCarbon::useCursor :: could not get OSXCarbonWindowingSystemInterface" << std::endl; return; @@ -1055,45 +1301,36 @@ void GraphicsWindowCarbon::transformMouseXY(float& x, float& y) } } -class CarbonWindowingSystemInterface : public DarwinWindowingSystemInterface { -public: - CarbonWindowingSystemInterface() : DarwinWindowingSystemInterface() + + + + + +struct RegisterWindowingSystemInterfaceProxy +{ + RegisterWindowingSystemInterfaceProxy() { + osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::OSXCarbonWindowingSystemInterface()); } - virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) + ~RegisterWindowingSystemInterfaceProxy() { - _init(); + if (osg::Referenced::getDeleteHandler()) + { + osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0); + osg::Referenced::getDeleteHandler()->flushAll(); + } - return createGraphicsContextImplementation(traits); + osg::GraphicsContext::setWindowingSystemInterface(0); } - - virtual void _init() - { - if (_initialized) return; - - DarwinWindowingSystemInterface::_init(); - - // register application event handler and AppleEventHandler to get quit-events: - static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess}; - OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL); - status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false); - } - }; - -} - -#ifdef USE_DARWIN_CARBON_IMPLEMENTATION -RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; -#endif - +RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; // declare C entry point for static compilation. extern "C" void graphicswindow_Carbon(void) { - osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::CarbonWindowingSystemInterface()); + osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::OSXCarbonWindowingSystemInterface()); } #endif diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index 3c0da1234..f645a87ea 100755 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -1378,17 +1378,16 @@ GraphicsWindowCocoa::~GraphicsWindowCocoa() // CocoaWindowingSystemInterface // ---------------------------------------------------------------------------------------------------------- -struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface -{ - - CocoaWindowingSystemInterface() : DarwinWindowingSystemInterface() - { +struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface { + + CocoaWindowingSystemInterface() + : DarwinWindowingSystemInterface() + + { } - + void initAsStandaloneApplication() { - _init(); - static bool s_inited = false; if (s_inited) return; s_inited = true; @@ -1418,8 +1417,6 @@ struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits) { - _init(); - if (!traits->pbuffer) { GraphicsWindowCocoa::WindowData* windowData = traits->inheritedWindowData ? dynamic_cast(traits->inheritedWindowData.get()) : NULL;