From a56d273fe360bbc6c17371105e6650f0a97a2ece Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Dec 2006 12:19:14 +0000 Subject: [PATCH] Moved the implementation of GraphicsWindowX11 from the head into the src/osgViewer directory. --- examples/osgcamera/osgcamera.cpp | 14 - include/osgViewer/GraphicsWindowX11 | 673 --------------------------- src/osgViewer/GNUmakefile | 4 + src/osgViewer/GraphicsWindowX11.cpp | 694 ++++++++++++++++++++++++++++ 4 files changed, 698 insertions(+), 687 deletions(-) create mode 100644 src/osgViewer/GraphicsWindowX11.cpp diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index 2e6b43ec8..d75bd7f1d 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -25,7 +25,6 @@ #if !defined(_WIN32) -#include #include #include @@ -35,19 +34,6 @@ void renderCamera(osg::Camera* camera) osg::GraphicsContext* gc = camera->getGraphicsContext(); if (!gc) return; -#if 0 - osgViewer::GraphicsWindowX11* gwX11 = dynamic_cast(gc); - if (gwX11) - { - gwX11->checkEvents(); - - osgGA::EventQueue::Events events; - if (gwX11->getEventQueue()->takeEvents(events)) - { - } - } -#endif - osgUtil::SceneView* sceneView = dynamic_cast(camera->getRenderingCache(0)); if (!sceneView) return; diff --git a/include/osgViewer/GraphicsWindowX11 b/include/osgViewer/GraphicsWindowX11 index 42ae4c48c..66c4adc25 100644 --- a/include/osgViewer/GraphicsWindowX11 +++ b/include/osgViewer/GraphicsWindowX11 @@ -36,54 +36,6 @@ namespace osgViewer { -class GraphicsContextX11 : public osg::GraphicsContext -{ - public: - - GraphicsContextX11(osg::GraphicsContext::Traits* traits): - _display(0), - _parent(0), - _window(0) - { - _traits = traits; - } - - /** Realise the GraphicsContext implementation, - * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ - virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."< Attributes; - Attributes attributes; - - attributes.push_back(GLX_USE_GL); - - attributes.push_back(GLX_RGBA); - - if (_traits->_doubleBuffer) attributes.push_back(GLX_DOUBLEBUFFER); - - if (_traits->_quadBufferStereo) attributes.push_back(GLX_STEREO); - - attributes.push_back(GLX_RED_SIZE); attributes.push_back(_traits->_red); - attributes.push_back(GLX_GREEN_SIZE); attributes.push_back(_traits->_green); - attributes.push_back(GLX_BLUE_SIZE); attributes.push_back(_traits->_blue); - attributes.push_back(GLX_DEPTH_SIZE); attributes.push_back(_traits->_depth); - - if (_traits->_alpha) { attributes.push_back(GLX_ALPHA_SIZE); attributes.push_back(_traits->_alpha); } - - if (_traits->_stencil) { attributes.push_back(GLX_STENCIL_SIZE); attributes.push_back(_traits->_stencil); } - - // TODO - // GLX_AUX_BUFFERS - // GLX_ACCUM_RED_SIZE - // GLX_ACCUM_GREEN_SIZE - // GLX_SAMPLE_BUFFERS - // GLX_SAMPLES - - attributes.push_back(None); - - _visualInfo = glXChooseVisual( _display, _traits->_screenNum, &(attributes.front()) ); - - return _visualInfo != 0; -} - -void GraphicsWindowX11::setWindowDecoration(bool flag) -{ - Atom atom; - if( (atom = XInternAtom( _display, "_MOTIF_WM_HINTS", 0 )) != None ) - { -// Hack for sending 64 bit atom to Xserver -#if defined( _MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64) || defined ( __ia64 ) || defined (__amd64 ) || defined(__x86_64__) - struct { - CARD32 flags0; - CARD32 flags1; - CARD32 functions0; - CARD32 functions1; - CARD32 decorations0; - CARD32 decorations1; - INT32 input_mode0; - INT32 input_mode1; - CARD32 status0; - CARD32 status1; - } wmHints; - -#if defined( __ia64 ) || defined (__amd64) || defined (__x86_64__) - wmHints.flags0 = (1L << 1); - wmHints.functions0 = 0; - wmHints.decorations0 = flag; - wmHints.input_mode0 = 0; - -#else - wmHints.flags1 = (1L << 1); - wmHints.functions1 = 0; - wmHints.decorations1 = flag; - wmHints.input_mode1 = 0; -#endif - -#else - - struct { - CARD32 flags; - CARD32 functions; - CARD32 decorations; - INT32 input_mode; - CARD32 status; - } wmHints; - - wmHints.flags = (1L << 1); - wmHints.functions = 0; - wmHints.decorations = flag; - wmHints.input_mode = 0; -#endif - - XUnmapWindow(_display, _window ); - XChangeProperty( _display, _window, atom, atom, 32, PropModeReplace, (unsigned char *)&wmHints, 5 ); - XMapWindow(_display, _window ); - - XFlush(_display); - XSync(_display,0); - -#if 0 - // now update the window dimensions to account for any size changes made by the window manager, - XGetWindowAttributes( _display, _window, &watt ); - _traits->_width = watt.width; - _traits->_height = watt.height; -#endif - - } - else - osg::notify(osg::NOTICE)<<"Error: GraphicsWindowX11::setBorder(" << flag << ") - couldn't change decorations." << std::endl; -} - -void GraphicsWindowX11::init() -{ - if (!_traits || _initialized) return; - - const char* displayString = _traits->_hostName.c_str(); - _display = XOpenDisplay(displayString); - - unsigned int screen = _traits->_screenNum; - - if (!_display) - { - osg::notify(osg::NOTICE)<<"Error: Unable to open display \"" << XDisplayName(displayString) << "\". Is the DISPLAY environmental variable set?"<_x; - sh.y = _traits->_y; - sh.width = _traits->_width; - sh.height = _traits->_height; - XSetStandardProperties( _display, _window, _traits->_windowName.c_str(), _traits->_windowName.c_str(), None, 0, 0, &sh); - -#if 0 - setWindowDecoration(_traits->_windowDecoration); -#else - setWindowDecoration(true); -#endif - // Create default Cursor - _defaultCursor = XCreateFontCursor( _display, XC_left_ptr ); - - - // Create Null Cursor - { - Pixmap pixmap; - static char buff[2] = {0,0}; - static XColor ncol = {0,0,0,0,DoRed|DoGreen|DoBlue,0}; - - pixmap = XCreateBitmapFromData( _display, _parent, buff, 1, 1); - _nullCursor = XCreatePixmapCursor( _display, pixmap, pixmap, &ncol, &ncol, 0, 0 ); - } - -#if 1 - _currentCursor = _defaultCursor; -#else - _currentCursor = _nullCursor; -#endif - - { - XDefineCursor( _display, _window, _currentCursor ); - XFlush(_display); - XSync(_display,0); - } - - XSelectInput( _display, _window, ExposureMask | StructureNotifyMask | - KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask); - - XFlush( _display ); - XSync( _display, 0 ); - - // now update the window dimensions to account for any size changes made by the window manager, - XGetWindowAttributes( _display, _window, &watt ); - _traits->_width = watt.width; - _traits->_height = watt.height; - - //osg::notify(osg::NOTICE)<<"After sync apply.x = "<getUseFixedMouseInputRange()) - { - osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); - x = eventState->getXmin() + (eventState->getXmax()-eventState->getXmin())*x/float(_traits->_width); - y = eventState->getYmin() + (eventState->getYmax()-eventState->getYmin())*y/float(_traits->_height); - } -} - -void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned int& modifierMask) -{ - // KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 ); - - static XComposeStatus state; - unsigned char keybuf[32]; - XLookupString( &keyevent, (char *)keybuf, sizeof(keybuf), NULL, &state ); - - modifierMask = 0; - if( keyevent.state & ShiftMask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; - } - if( keyevent.state & LockMask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK; - } - if( keyevent.state & ControlMask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_CTRL; - } - if( keyevent.state & Mod1Mask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_ALT; - } - if( keyevent.state & Mod2Mask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_NUM_LOCK; - } - if( keyevent.state & Mod4Mask ) - { - modifierMask |= osgGA::GUIEventAdapter::MODKEY_META; - } - - keySymbol = keybuf[0]; -} - -struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface -{ - - X11WindowingSystemInterface() - { - } - - virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) - { - const char* displayString = si._hostName.c_str(); - Display* display = XOpenDisplay(displayString); - if(display) - { - unsigned int numScreens = ScreenCount(display); - XCloseDisplay(display); - - return numScreens; - } - else - { - osg::notify(osg::NOTICE) << "Unable to open display \"" << XDisplayName(displayString) << "\". Is the DISPLAY environmental variable set?"<_pbuffer) - { - return new GraphicsContextX11(traits); - } - else - { - return new GraphicsWindowX11(traits); - } - } - -}; - -struct RegisterWindowingSystemInterfaceProxy -{ - RegisterWindowingSystemInterfaceProxy() - { - osg::GraphicsContext::setWindowingSystemInterface(new X11WindowingSystemInterface); - } - - ~RegisterWindowingSystemInterfaceProxy() - { - osg::GraphicsContext::setWindowingSystemInterface(0); - } -}; - -RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy; - } #endif diff --git a/src/osgViewer/GNUmakefile b/src/osgViewer/GNUmakefile index 301d9c0e0..58e0593a2 100644 --- a/src/osgViewer/GNUmakefile +++ b/src/osgViewer/GNUmakefile @@ -10,6 +10,10 @@ CXXFILES = \ CompositeViewer.cpp\ Version.cpp\ + +CXXFILES += GraphicsWindowX11.cpp\ + + DEF += -DOSGVIEWER_LIBRARY LIBS += -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(OTHER_LIBS) diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp new file mode 100644 index 000000000..c65abeda0 --- /dev/null +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -0,0 +1,694 @@ +/* -*-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. + */ + +#include + +using namespace osgViewer; + +class GraphicsContextX11 : public osg::GraphicsContext +{ + public: + + GraphicsContextX11(osg::GraphicsContext::Traits* traits): + _display(0), + _parent(0), + _window(0) + { + _traits = traits; + } + + /** Realise the GraphicsContext implementation, + * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ + virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."< Attributes; + Attributes attributes; + + attributes.push_back(GLX_USE_GL); + + attributes.push_back(GLX_RGBA); + + if (_traits->_doubleBuffer) attributes.push_back(GLX_DOUBLEBUFFER); + + if (_traits->_quadBufferStereo) attributes.push_back(GLX_STEREO); + + attributes.push_back(GLX_RED_SIZE); attributes.push_back(_traits->_red); + attributes.push_back(GLX_GREEN_SIZE); attributes.push_back(_traits->_green); + attributes.push_back(GLX_BLUE_SIZE); attributes.push_back(_traits->_blue); + attributes.push_back(GLX_DEPTH_SIZE); attributes.push_back(_traits->_depth); + + if (_traits->_alpha) { attributes.push_back(GLX_ALPHA_SIZE); attributes.push_back(_traits->_alpha); } + + if (_traits->_stencil) { attributes.push_back(GLX_STENCIL_SIZE); attributes.push_back(_traits->_stencil); } + + // TODO + // GLX_AUX_BUFFERS + // GLX_ACCUM_RED_SIZE + // GLX_ACCUM_GREEN_SIZE + // GLX_SAMPLE_BUFFERS + // GLX_SAMPLES + + attributes.push_back(None); + + _visualInfo = glXChooseVisual( _display, _traits->_screenNum, &(attributes.front()) ); + + return _visualInfo != 0; +} + +void GraphicsWindowX11::setWindowDecoration(bool flag) +{ + Atom atom; + if( (atom = XInternAtom( _display, "_MOTIF_WM_HINTS", 0 )) != None ) + { +// Hack for sending 64 bit atom to Xserver +#if defined( _MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64) || defined ( __ia64 ) || defined (__amd64 ) || defined(__x86_64__) + struct { + CARD32 flags0; + CARD32 flags1; + CARD32 functions0; + CARD32 functions1; + CARD32 decorations0; + CARD32 decorations1; + INT32 input_mode0; + INT32 input_mode1; + CARD32 status0; + CARD32 status1; + } wmHints; + +#if defined( __ia64 ) || defined (__amd64) || defined (__x86_64__) + wmHints.flags0 = (1L << 1); + wmHints.functions0 = 0; + wmHints.decorations0 = flag; + wmHints.input_mode0 = 0; + +#else + wmHints.flags1 = (1L << 1); + wmHints.functions1 = 0; + wmHints.decorations1 = flag; + wmHints.input_mode1 = 0; +#endif + +#else + + struct { + CARD32 flags; + CARD32 functions; + CARD32 decorations; + INT32 input_mode; + CARD32 status; + } wmHints; + + wmHints.flags = (1L << 1); + wmHints.functions = 0; + wmHints.decorations = flag; + wmHints.input_mode = 0; +#endif + + XUnmapWindow(_display, _window ); + XChangeProperty( _display, _window, atom, atom, 32, PropModeReplace, (unsigned char *)&wmHints, 5 ); + XMapWindow(_display, _window ); + + XFlush(_display); + XSync(_display,0); + +#if 0 + // now update the window dimensions to account for any size changes made by the window manager, + XGetWindowAttributes( _display, _window, &watt ); + _traits->_width = watt.width; + _traits->_height = watt.height; +#endif + + } + else + osg::notify(osg::NOTICE)<<"Error: GraphicsWindowX11::setBorder(" << flag << ") - couldn't change decorations." << std::endl; +} + +void GraphicsWindowX11::init() +{ + if (!_traits || _initialized) return; + + const char* displayString = _traits->_hostName.c_str(); + _display = XOpenDisplay(displayString); + + unsigned int screen = _traits->_screenNum; + + if (!_display) + { + osg::notify(osg::NOTICE)<<"Error: Unable to open display \"" << XDisplayName(displayString) << "\". Is the DISPLAY environmental variable set?"<_x; + sh.y = _traits->_y; + sh.width = _traits->_width; + sh.height = _traits->_height; + XSetStandardProperties( _display, _window, _traits->_windowName.c_str(), _traits->_windowName.c_str(), None, 0, 0, &sh); + +#if 1 + setWindowDecoration(_traits->_windowDecoration); +#else + setWindowDecoration(true); +#endif + // Create default Cursor + _defaultCursor = XCreateFontCursor( _display, XC_left_ptr ); + + + // Create Null Cursor + { + Pixmap pixmap; + static char buff[2] = {0,0}; + static XColor ncol = {0,0,0,0,DoRed|DoGreen|DoBlue,0}; + + pixmap = XCreateBitmapFromData( _display, _parent, buff, 1, 1); + _nullCursor = XCreatePixmapCursor( _display, pixmap, pixmap, &ncol, &ncol, 0, 0 ); + } + +#if 1 + _currentCursor = _defaultCursor; +#else + _currentCursor = _nullCursor; +#endif + + { + XDefineCursor( _display, _window, _currentCursor ); + XFlush(_display); + XSync(_display,0); + } + + XSelectInput( _display, _window, ExposureMask | StructureNotifyMask | + KeyPressMask | KeyReleaseMask | + PointerMotionMask | ButtonPressMask | ButtonReleaseMask); + + XFlush( _display ); + XSync( _display, 0 ); + + // now update the window dimensions to account for any size changes made by the window manager, + XGetWindowAttributes( _display, _window, &watt ); + _traits->_width = watt.width; + _traits->_height = watt.height; + + //osg::notify(osg::NOTICE)<<"After sync apply.x = "<getUseFixedMouseInputRange()) + { + osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); + x = eventState->getXmin() + (eventState->getXmax()-eventState->getXmin())*x/float(_traits->_width); + y = eventState->getYmin() + (eventState->getYmax()-eventState->getYmin())*y/float(_traits->_height); + } +} + +void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned int& modifierMask) +{ + // KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 ); + + static XComposeStatus state; + unsigned char keybuf[32]; + XLookupString( &keyevent, (char *)keybuf, sizeof(keybuf), NULL, &state ); + + modifierMask = 0; + if( keyevent.state & ShiftMask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; + } + if( keyevent.state & LockMask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK; + } + if( keyevent.state & ControlMask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_CTRL; + } + if( keyevent.state & Mod1Mask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_ALT; + } + if( keyevent.state & Mod2Mask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_NUM_LOCK; + } + if( keyevent.state & Mod4Mask ) + { + modifierMask |= osgGA::GUIEventAdapter::MODKEY_META; + } + + keySymbol = keybuf[0]; +} + +struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface +{ + + X11WindowingSystemInterface() + { + } + + virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si) + { + const char* displayString = si._hostName.c_str(); + Display* display = XOpenDisplay(displayString); + if(display) + { + unsigned int numScreens = ScreenCount(display); + XCloseDisplay(display); + + return numScreens; + } + else + { + osg::notify(osg::NOTICE) << "Unable to open display \"" << XDisplayName(displayString) << "\". Is the DISPLAY environmental variable set?"<_pbuffer) + { + return new GraphicsContextX11(traits); + } + else + { + return new GraphicsWindowX11(traits); + } + } + +}; + +struct RegisterWindowingSystemInterfaceProxy +{ + RegisterWindowingSystemInterfaceProxy() + { + osg::GraphicsContext::setWindowingSystemInterface(new X11WindowingSystemInterface); + } + + ~RegisterWindowingSystemInterfaceProxy() + { + osg::GraphicsContext::setWindowingSystemInterface(0); + } +}; + +RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy;