From fe6238d126b672a6c8a58925a4000710bac4c9c4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 May 2016 13:45:31 +0100 Subject: [PATCH] Added osg::GraphicsContext::WindowingSystemInterfaces singleton for managing multiple WIndowinSystemInterface implementations being registered at the same time. One usage case for this functionality to support usage of Wayland and X11 in the same version of the osgViewer. As part of the new functionality there is now a osg::GraphicsContext::Traits::windowingSystemPreferrence string that default to empty, but if defined will ensure that a specific WindowingSystemInterface is utilized when you do a generic call like osg::createGraphicsContext(). Also implemented is standard proxy object for registering the new contexts and removing them automatically, and declaration of standard graphicswindow_name() C entry point to help with static build linking. --- examples/osgwindows/osgwindows.cpp | 1 + include/osg/GraphicsContext | 67 +++++++++++++++++--- include/osgQt/GraphicsWindowQt | 4 +- src/osg/GraphicsContext.cpp | 85 +++++++++++++++++++++----- src/osgQt/GraphicsWindowQt.cpp | 8 ++- src/osgViewer/DarwinUtils.h | 41 +++++++------ src/osgViewer/GraphicsWindowCarbon.cpp | 6 +- src/osgViewer/GraphicsWindowCocoa.mm | 4 ++ src/osgViewer/GraphicsWindowIOS.mm | 5 +- src/osgViewer/GraphicsWindowWin32.cpp | 25 +++++--- src/osgViewer/GraphicsWindowX11.cpp | 8 ++- src/osgViewer/IOSUtils.h | 17 +++--- 12 files changed, 204 insertions(+), 67 deletions(-) diff --git a/examples/osgwindows/osgwindows.cpp b/examples/osgwindows/osgwindows.cpp index c8fbce589..e9bf726ee 100644 --- a/examples/osgwindows/osgwindows.cpp +++ b/examples/osgwindows/osgwindows.cpp @@ -50,6 +50,7 @@ int main( int argc, char **argv ) // left window + left slave camera { osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->x = xoffset + 0; traits->y = yoffset + 0; traits->width = 600; diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index ec06b29ef..7b52e6eec 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -76,6 +76,12 @@ class OSG_EXPORT GraphicsContext : public Object int width; int height; + // provide a hint as to which WindowingSystemInterface implementation to use, i.e. "X11", "Win32", "Cocoa", "Carbon" etc. + // if the windowingSystemPreference string is empty (default) then return the first available WindowingSystemInterface that + // has been registered with the osg::GraphiccsContext::WindowingSystemInterfaces singleton + // if the windowingSystemPreference string is not empty then return the first WindowingSystemInterface that matches + std::string windowingSystemPreference; + // window decoration and behaviour std::string windowName; bool windowDecoration; @@ -168,6 +174,9 @@ class OSG_EXPORT GraphicsContext : public Object /** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/ struct WindowingSystemInterface : public osg::Referenced { + void setName(const std::string& name) { _name = name; } + const std::string& getName() const { return _name; } + virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0; virtual void getScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettings & resolution) = 0; @@ -182,9 +191,6 @@ class OSG_EXPORT GraphicsContext : public Object virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0; - virtual ~WindowingSystemInterface() {} - - /** Gets screen resolution without using the ScreenResolution structure. * \deprecated Provided only for backward compatibility. */ inline void getScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int& width, unsigned int& height) @@ -210,15 +216,38 @@ class OSG_EXPORT GraphicsContext : public Object settings.refreshRate = refreshRate; return setScreenSettings(screenIdentifier, settings); } + protected: + WindowingSystemInterface() {} + virtual ~WindowingSystemInterface() {} + std::string _name; }; + class OSG_EXPORT WindowingSystemInterfaces : public osg::Referenced + { + public: + WindowingSystemInterfaces(); - /** Set the query the windowing system for screens and create graphics context - this functor should be supplied by the windows toolkit. */ - static void setWindowingSystemInterface(WindowingSystemInterface* wsInterface); + typedef std::vector< osg::ref_ptr > Interfaces; - /** Get the WindowingSystemInterface*/ - static WindowingSystemInterface* getWindowingSystemInterface(); + Interfaces& getInterfaces() { return _interfaces; } + + void addWindowingSystemInterface(WindowingSystemInterface* wsInterface); + + void removeWindowingSystemInterface(WindowingSystemInterface* wsInterface); + + /** get named WindowingSystemInterface if one is available, otherwise return 0; */ + WindowingSystemInterface* getWindowingSystemInterface(const std::string& name = ""); + + private: + virtual ~WindowingSystemInterfaces(); + Interfaces _interfaces; + }; + + static osg::ref_ptr& getWindowingSystemInterfaces(); + + /** Get the default WindowingSystemInterface for this OS*/ + static WindowingSystemInterface* getWindowingSystemInterface(const std::string& name = ""); /** Create a graphics context for a specified set of traits.*/ static GraphicsContext* createGraphicsContext(Traits* traits); @@ -544,6 +573,30 @@ public: GLsync _previousSync; }; + +template +struct WindowingSystemInterfaceProxy +{ + WindowingSystemInterfaceProxy(const std::string& name) + { + _wsi = new T; + _wsi->setName(name); + + osg::GraphicsContext::getWindowingSystemInterfaces()->addWindowingSystemInterface(_wsi.get()); + } + + ~WindowingSystemInterfaceProxy() + { + osg::GraphicsContext::getWindowingSystemInterfaces()->removeWindowingSystemInterface(_wsi.get()); + } + + osg::ref_ptr _wsi; +}; + +#define REGISTER_WINDOWINGSYSTEMINTERFACE(ext, classname) \ + extern "C" void graphicswindow_##ext(void) {} \ + static osg::WindowingSystemInterfaceProxy s_proxy_##classname(#ext); + } #endif diff --git a/include/osgQt/GraphicsWindowQt b/include/osgQt/GraphicsWindowQt index 09bbac9f6..6f2e5a0a5 100644 --- a/include/osgQt/GraphicsWindowQt +++ b/include/osgQt/GraphicsWindowQt @@ -39,8 +39,10 @@ namespace osgQt // forward declarations class GraphicsWindowQt; +#if 0 /// The function sets the WindowingSystem to Qt. void OSGQT_EXPORT initQtWindowingSystem(); +#endif /** The function sets the viewer that will be used after entering * the Qt main loop (QCoreApplication::exec()). @@ -69,7 +71,7 @@ public: inline bool getForwardKeyEvents() const { return _forwardKeyEvents; } virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; } - + inline bool getTouchEventsEnabled() const { return _touchEventsEnabled; } void setTouchEventsEnabled( bool e ); diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 7d953e35a..35848d214 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -34,42 +34,95 @@ #include #include #include +#include using namespace osg; ///////////////////////////////////////////////////////////////////////////// +// +// WindowSystemInterfaces +// +GraphicsContext::WindowingSystemInterfaces::WindowingSystemInterfaces() +{ +} +GraphicsContext::WindowingSystemInterfaces::~WindowingSystemInterfaces() +{ +} + +void GraphicsContext::WindowingSystemInterfaces::addWindowingSystemInterface(GraphicsContext::WindowingSystemInterface* wsi) +{ + if (std::find(_interfaces.begin(), _interfaces.end(), wsi)==_interfaces.end()) + { + OSG_NOTICE<<"GraphicsContext::WindowingSystemInterfaces::addWindowingSystemInterface("<getName()==name) + { + return itr->get(); + } + + OSG_NOTICE<<" tried interface "< &windowingSystemInterfaceRef() +osg::ref_ptr& GraphicsContext::getWindowingSystemInterfaces() { - static ref_ptr s_WindowingSystemInterface; + static ref_ptr s_WindowingSystemInterface = new GraphicsContext::WindowingSystemInterfaces; return s_WindowingSystemInterface; } +OSG_INIT_SINGLETON_PROXY(ProxyInitWindowingSystemInterfaces, GraphicsContext::getWindowingSystemInterfaces()) + // GraphicsContext static method implementations - -void GraphicsContext::setWindowingSystemInterface(WindowingSystemInterface* callback) +GraphicsContext::WindowingSystemInterface* GraphicsContext::getWindowingSystemInterface(const std::string& name) { - ref_ptr &wsref = windowingSystemInterfaceRef(); - wsref = callback; - OSG_INFO<<"GraphicsContext::setWindowingSystemInterface() "< &wsref = windowingSystemInterfaceRef(); - OSG_INFO<<"GraphicsContext::getWindowingSystemInterface() "<getWindowingSystemInterface(name); } GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits) { - ref_ptr &wsref = windowingSystemInterfaceRef(); + ref_ptr wsref = getWindowingSystemInterface(traits ? traits->windowingSystemPreference : "") ; if ( wsref.valid()) { // catch any undefined values. diff --git a/src/osgQt/GraphicsWindowQt.cpp b/src/osgQt/GraphicsWindowQt.cpp index b21a2ad2e..9b551f602 100644 --- a/src/osgQt/GraphicsWindowQt.cpp +++ b/src/osgQt/GraphicsWindowQt.cpp @@ -125,7 +125,7 @@ public: osg::observer_ptr< osgViewer::ViewerBase > _viewer; virtual ~HeartBeat(); - + void init( osgViewer::ViewerBase *viewer ); void stopTimer(); void timerEvent( QTimerEvent *event ); @@ -869,7 +869,6 @@ void GraphicsWindowQt::requestWarpPointer( float x, float y ) QCursor::setPos( _widget->mapToGlobal(QPoint((int)x,(int)y)) ); } - class QtWindowingSystem : public osg::GraphicsContext::WindowingSystemInterface { public: @@ -945,6 +944,9 @@ private: QtWindowingSystem& operator=( const QtWindowingSystem& ); }; +#if 1 +REGISTER_WINDOWINGSYSTEMINTERFACE(Qt, QtWindowingSystem) +#else // declare C entry point for static compilation. extern "C" void OSGQT_EXPORT graphicswindow_Qt(void) @@ -957,7 +959,7 @@ void osgQt::initQtWindowingSystem() { graphicswindow_Qt(); } - +#endif void osgQt::setViewer( osgViewer::ViewerBase *viewer ) diff --git a/src/osgViewer/DarwinUtils.h b/src/osgViewer/DarwinUtils.h index f68798fc5..44bfd6a3e 100644 --- a/src/osgViewer/DarwinUtils.h +++ b/src/osgViewer/DarwinUtils.h @@ -8,7 +8,7 @@ */ #ifdef __APPLE__ - + #ifndef DARWIN_UTILS_HEADER_ #define DARWIN_UTILS_HEADER_ @@ -31,37 +31,37 @@ 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 +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(); - + + MenubarController(); + static MenubarController* instance(); - + void attachWindow(WindowAdapter* win); void update(); void detachWindow(osgViewer::GraphicsWindow* win); - + void setDisplaySettings(osg::DisplaySettings* display_settings); - + protected: ~MenubarController(); - - private: + + private: typedef std::list< osg::ref_ptr< WindowAdapter > > WindowList; WindowList _list; bool _menubarShown; @@ -69,7 +69,7 @@ class MenubarController : public osg::Referenced CGRect _mainScreenBounds; OpenThreads::Mutex _mutex; MenubarToggler* _toggler; - + }; @@ -91,25 +91,25 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy virtual void getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution); virtual void enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList); - + virtual bool setScreenSettings (const osg::GraphicsContext::ScreenIdentifier & si, const osg::GraphicsContext::ScreenSettings & settings); /** return the top left coord of a specific screen in global screen space */ void getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y); - + /** returns screen-ndx containing rect x,y,w,h */ unsigned int getScreenContaining(int x, int y, int w, int h); - + virtual void setDisplaySettings(osg::DisplaySettings* display_settings) { MenubarController::instance()->setDisplaySettings(display_settings); } - + protected: virtual void _init(); - + template osg::GraphicsContext* createGraphicsContextImplementation(osg::GraphicsContext::Traits* traits) { @@ -136,6 +136,7 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy }; +#if 0 template struct RegisterWindowingSystemInterfaceProxy { @@ -155,7 +156,7 @@ struct RegisterWindowingSystemInterfaceProxy osg::GraphicsContext::setWindowingSystemInterface(0); } }; - +#endif } diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index 732d5dae9..a49f451be 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -1100,15 +1100,19 @@ public: } +#if 1 +REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, osgViewer::CarbonWindowingSystemInterface) +#else + #ifdef USE_DARWIN_CARBON_IMPLEMENTATION RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; #endif - // declare C entry point for static compilation. extern "C" void graphicswindow_Carbon(void) { osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::CarbonWindowingSystemInterface()); } +#endif #endif diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index 5064143f2..c682932b3 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -1829,6 +1829,9 @@ private: } +#if 1 +REGISTER_WINDOWINGSYSTEMINTERFACE(Cocoa, osgViewer::CocoaWindowingSystemInterface) +#else #ifdef USE_DARWIN_COCOA_IMPLEMENTATION RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; #endif @@ -1838,3 +1841,4 @@ extern "C" void graphicswindow_Cocoa(void) { osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::CocoaWindowingSystemInterface()); } +#endif diff --git a/src/osgViewer/GraphicsWindowIOS.mm b/src/osgViewer/GraphicsWindowIOS.mm index 5bca620b5..6127080d0 100644 --- a/src/osgViewer/GraphicsWindowIOS.mm +++ b/src/osgViewer/GraphicsWindowIOS.mm @@ -1226,7 +1226,9 @@ public: }//end namspace - +#if 1 +REGISTER_WINDOWINGSYSTEMINTERFACE(IOS, osgViewer::ConcreteIOSWindowingSystemInterface) +#else RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; @@ -1235,3 +1237,4 @@ extern "C" void graphicswindow_IOS(void) { osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::ConcreteIOSWindowingSystemInterface()); } +#endif diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 167a9b026..9d50b7273 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -317,14 +317,16 @@ class Win32WindowingSystem : public osg::GraphicsContext::WindowingSystemInterfa static std::string osgGraphicsWindowWithCursorClass; //!< Name of Win32 window class (with cursor) used by OSG graphics window instances static std::string osgGraphicsWindowWithoutCursorClass; //!< Name of Win32 window class (without cursor) used by OSG graphics window instances - Win32WindowingSystem(); - ~Win32WindowingSystem(); + Win32WindowingSystem() + { + getInterface() = this; + } // Access the Win32 windowing system through this singleton class. - static Win32WindowingSystem* getInterface() + static osg::ref_ptr& getInterface() { - static Win32WindowingSystem* win32Interface = new Win32WindowingSystem; - return win32Interface; + static osg::ref_ptr s_win32Interface; + return s_win32Interface; } // Return the number of screens present in the system @@ -368,6 +370,8 @@ class Win32WindowingSystem : public osg::GraphicsContext::WindowingSystemInterfa protected: + virtual ~Win32WindowingSystem() {} + // Display devices present in the system typedef std::vector DisplayDevices; @@ -2273,7 +2277,7 @@ void GraphicsWindowWin32::setCursorImpl( MouseCursor mouseCursor ) _currentCursor = newCursor; _traits->useCursor = (_currentCursor != NULL) && (_mouseCursor != NoCursor); - + PostMessage(_hwnd, WM_SETCURSOR, 0, 0); } } @@ -2894,7 +2898,7 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W ////////////////////////////////////////////////////////////////////////////// // Class responsible for registering the Win32 Windowing System interface ////////////////////////////////////////////////////////////////////////////// - +#if 0 struct RegisterWindowingSystemInterfaceProxy { RegisterWindowingSystemInterfaceProxy() @@ -2915,16 +2919,19 @@ struct RegisterWindowingSystemInterfaceProxy }; static RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; +#endif } // namespace OsgViewer - +#if 1 +REGISTER_WINDOWINGSYSTEMINTERFACE(Win32, Win32WindowingSystem) +#else // declare C entry point for static compilation. extern "C" void OSGVIEWER_EXPORT graphicswindow_Win32(void) { osg::GraphicsContext::setWindowingSystemInterface(osgViewer::Win32WindowingSystem::getInterface()); } - +#endif void GraphicsWindowWin32::raiseWindow() { diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index b0d622ccd..a3d4552ca 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -2144,6 +2144,12 @@ public: }; +#if 1 + +REGISTER_WINDOWINGSYSTEMINTERFACE(X11, X11WindowingSystemInterface) + + +#else struct RegisterWindowingSystemInterfaceProxy { RegisterWindowingSystemInterfaceProxy() @@ -2166,7 +2172,6 @@ struct RegisterWindowingSystemInterfaceProxy } }; - RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; // declare C entry point for static compilation. @@ -2174,6 +2179,7 @@ extern "C" void graphicswindow_X11(void) { osg::GraphicsContext::setWindowingSystemInterface(new X11WindowingSystemInterface); } +#endif void GraphicsWindowX11::raiseWindow() { diff --git a/src/osgViewer/IOSUtils.h b/src/osgViewer/IOSUtils.h index 0bf186e8b..1c5692390 100644 --- a/src/osgViewer/IOSUtils.h +++ b/src/osgViewer/IOSUtils.h @@ -11,8 +11,8 @@ * */ -#ifdef __APPLE__ - +#ifdef __APPLE__ + #ifndef IOS_UTILS_HEADER_ #define IOS_UTILS_HEADER_ @@ -45,7 +45,7 @@ public: virtual void getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& si, osg::GraphicsContext::ScreenSettings & resolution); virtual void enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier, osg::GraphicsContext::ScreenSettingsList & resolutionList); - + virtual bool setScreenSettings (const osg::GraphicsContext::ScreenIdentifier & si, const osg::GraphicsContext::ScreenSettings & settings); /** returns screen-ndx containing rect x,y,w,h, NOT_TESTED@tom */ @@ -57,12 +57,12 @@ public: //return the UIScreen object asscoiated with the passed ScreenIdentifier //returns nil if si isn't found UIScreen* getUIScreen(const osg::GraphicsContext::ScreenIdentifier& si); - + // //Get the contents scale factor of the screen, this is the scale factor required //to convert points to pixels on this screen bool getScreenContentScaleFactor(const osg::GraphicsContext::ScreenIdentifier& si, float& scaleFactor); - + // //Get the screens size in points, docs state a point is roughly 1/160th of an inch bool getScreenSizeInPoints(const osg::GraphicsContext::ScreenIdentifier& si, osg::Vec2& pointSize); @@ -80,11 +80,12 @@ protected: private: - - + + }; +#if 0 template struct RegisterWindowingSystemInterfaceProxy { @@ -104,7 +105,7 @@ struct RegisterWindowingSystemInterfaceProxy osg::GraphicsContext::setWindowingSystemInterface(0); } }; - +#endif }