From 37272b14ac8fb8287a4e832061b58d0fa9f3450e Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 8 Mar 2021 17:00:58 +0000 Subject: [PATCH] Remove the custom graphics window impl Probably not worth the compat hassle :) --- src/Viewer/GraphicsWindowQt5.cpp | 898 ------------------------------- src/Viewer/GraphicsWindowQt5.hxx | 193 ------- 2 files changed, 1091 deletions(-) delete mode 100644 src/Viewer/GraphicsWindowQt5.cpp delete mode 100644 src/Viewer/GraphicsWindowQt5.hxx diff --git a/src/Viewer/GraphicsWindowQt5.cpp b/src/Viewer/GraphicsWindowQt5.cpp deleted file mode 100644 index 52f514745..000000000 --- a/src/Viewer/GraphicsWindowQt5.cpp +++ /dev/null @@ -1,898 +0,0 @@ -// Copyright (C) 2017 James Turner -// derived from OSG GraphicsWindowQt by Wang Rui -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program 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 GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#include -#include -#include "GraphicsWindowQt5.hxx" -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include
- -using namespace flightgear; - -class QtKeyboardMap -{ - -public: - QtKeyboardMap() - { - mKeyMap[Qt::Key_Escape ] = osgGA::GUIEventAdapter::KEY_Escape; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Home ] = osgGA::GUIEventAdapter::KEY_Home; - mKeyMap[Qt::Key_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter; - mKeyMap[Qt::Key_End ] = osgGA::GUIEventAdapter::KEY_End; - mKeyMap[Qt::Key_Return ] = osgGA::GUIEventAdapter::KEY_Return; - mKeyMap[Qt::Key_PageUp ] = osgGA::GUIEventAdapter::KEY_Page_Up; - mKeyMap[Qt::Key_PageDown ] = osgGA::GUIEventAdapter::KEY_Page_Down; - mKeyMap[Qt::Key_Left ] = osgGA::GUIEventAdapter::KEY_Left; - mKeyMap[Qt::Key_Right ] = osgGA::GUIEventAdapter::KEY_Right; - mKeyMap[Qt::Key_Up ] = osgGA::GUIEventAdapter::KEY_Up; - mKeyMap[Qt::Key_Down ] = osgGA::GUIEventAdapter::KEY_Down; - mKeyMap[Qt::Key_Backspace ] = osgGA::GUIEventAdapter::KEY_BackSpace; - mKeyMap[Qt::Key_Tab ] = osgGA::GUIEventAdapter::KEY_Tab; - mKeyMap[Qt::Key_Space ] = osgGA::GUIEventAdapter::KEY_Space; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Alt ] = osgGA::GUIEventAdapter::KEY_Alt_L; - mKeyMap[Qt::Key_Shift ] = osgGA::GUIEventAdapter::KEY_Shift_L; - -#if defined(Q_OS_MACOS) - // undo the Qt-mac remapping - mKeyMap[Qt::Key_Meta ] = osgGA::GUIEventAdapter::KEY_Control_L; - mKeyMap[Qt::Key_Control ] = osgGA::GUIEventAdapter::KEY_Meta_L; -#else - mKeyMap[Qt::Key_Control ] = osgGA::GUIEventAdapter::KEY_Control_L; - mKeyMap[Qt::Key_Meta ] = osgGA::GUIEventAdapter::KEY_Meta_L; -#endif - mKeyMap[Qt::Key_Super_L ] = osgGA::GUIEventAdapter::KEY_Super_L; - mKeyMap[Qt::Key_Super_R ] = osgGA::GUIEventAdapter::KEY_Super_R; - mKeyMap[Qt::Key_Hyper_L ] = osgGA::GUIEventAdapter::KEY_Hyper_L; - mKeyMap[Qt::Key_Hyper_R ] = osgGA::GUIEventAdapter::KEY_Hyper_R; - - - mKeyMap[Qt::Key_F1 ] = osgGA::GUIEventAdapter::KEY_F1; - mKeyMap[Qt::Key_F2 ] = osgGA::GUIEventAdapter::KEY_F2; - mKeyMap[Qt::Key_F3 ] = osgGA::GUIEventAdapter::KEY_F3; - mKeyMap[Qt::Key_F4 ] = osgGA::GUIEventAdapter::KEY_F4; - mKeyMap[Qt::Key_F5 ] = osgGA::GUIEventAdapter::KEY_F5; - mKeyMap[Qt::Key_F6 ] = osgGA::GUIEventAdapter::KEY_F6; - mKeyMap[Qt::Key_F7 ] = osgGA::GUIEventAdapter::KEY_F7; - mKeyMap[Qt::Key_F8 ] = osgGA::GUIEventAdapter::KEY_F8; - mKeyMap[Qt::Key_F9 ] = osgGA::GUIEventAdapter::KEY_F9; - mKeyMap[Qt::Key_F10 ] = osgGA::GUIEventAdapter::KEY_F10; - mKeyMap[Qt::Key_F11 ] = osgGA::GUIEventAdapter::KEY_F11; - mKeyMap[Qt::Key_F12 ] = osgGA::GUIEventAdapter::KEY_F12; - mKeyMap[Qt::Key_F13 ] = osgGA::GUIEventAdapter::KEY_F13; - mKeyMap[Qt::Key_F14 ] = osgGA::GUIEventAdapter::KEY_F14; - mKeyMap[Qt::Key_F15 ] = osgGA::GUIEventAdapter::KEY_F15; - mKeyMap[Qt::Key_F16 ] = osgGA::GUIEventAdapter::KEY_F16; - mKeyMap[Qt::Key_F17 ] = osgGA::GUIEventAdapter::KEY_F17; - mKeyMap[Qt::Key_F18 ] = osgGA::GUIEventAdapter::KEY_F18; - mKeyMap[Qt::Key_F19 ] = osgGA::GUIEventAdapter::KEY_F19; - mKeyMap[Qt::Key_F20 ] = osgGA::GUIEventAdapter::KEY_F20; - - - mKeyMap[Qt::Key_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; - //mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete; - } - - ~QtKeyboardMap() - { - } - - int remapKey(QKeyEvent* event) - { - const QChar unicodePoint = event->text().isEmpty() ? QChar() : event->text().at(0); - KeyMap::iterator itr = mKeyMap.find(event->key()); - if (itr == mKeyMap.end()) { - if (unicodePoint.isNull()) { - // this happens for Ctrl modifiers on A-Z (at least). Keyboard.xml relies on the - // old ASCII mappings of these values, so we need to synthesise those here - // since Qt won't do it. - - const auto k = event->key(); - if ((k >= Qt::Key_A) && (k <= Qt::Key_Z)) { - return 1 + (k - Qt::Key_A); // offset into the ASCII control code range - } else { - qWarning() << Q_FUNC_INFO << "misssing mapping for key"; - } - } -#if 0 - qDebug() << "key" << event->key() << ", mods" << event->modifiers() << "Unicode:" << unicodePoint << ", ASCII:" - << unicodePoint.toLatin1() << "(" << (int)unicodePoint.toLatin1() << "), raw text:" << event->text(); -#endif - return int(unicodePoint.toLatin1()); - } - - return itr->second; - } - -private: - typedef std::map KeyMap; - KeyMap mKeyMap; -}; - -static QtKeyboardMap s_QtKeyboardMap; - - - -GLWindow::GLWindow() - : QWindow() -{ - _devicePixelRatio = 1.0; - connect(this, &QWindow::screenChanged, this, &GLWindow::onScreenChanged); - onScreenChanged(); -} - -void GLWindow::onScreenChanged() -{ - qWarning() << Q_FUNC_INFO << "screen changed"; - _devicePixelRatio = screen()->devicePixelRatio(); - - if (_isPrimaryWindow) { - // allow PUI and Canvas to be scaled - fgSetDouble("/sim/rendering/gui-pixel-ratio", _devicePixelRatio); - } - - syncGeometryWithOSG(); -} - -void GLWindow::syncGeometryWithOSG() -{ - const int w = width(); - const int h = height(); - - int scaled_width = static_cast(w *_devicePixelRatio); - int scaled_height = static_cast(h*_devicePixelRatio); - - if (_gw) { - _gw->resized( x(), y(), scaled_width, scaled_height); - _gw->getEventQueue()->windowResize( x(), y(), scaled_width, scaled_height ); - _gw->requestRedraw(); - _gw->_updateContextNeeded = true; - } -} - -GLWindow::~GLWindow() -{ - if (_gw) { - _gw->_window = nullptr; - _gw = nullptr; - } -} - -bool GLWindow::event( QEvent* event ) -{ - if (event->type() == QEvent::WindowStateChange) { - // keep full-screen state in sync - const bool isFullscreen = (windowState() == Qt::WindowFullScreen); - - if (_isPrimaryWindow) { - fgSetBool("/sim/startup/fullscreen", isFullscreen); - } - } - else if (event->type() == QEvent::UpdateRequest) - { - processUpdateEvent(); - } - else if (event->type() == QEvent::Close) { - // spin an 'are you sure'? dialog here - // need to decide immediately unfortunately. - _gw->getEventQueue()->closeWindow(); - } - - // perform regular event handling - return QWindow::event( event ); -} - -void GLWindow::processUpdateEvent() -{ - osg::ref_ptr v; - if (_gw->_viewer.lock(v)) { - v->frame(); - } - - // see discussion of QWindow::requestUpdate to see - // why this is good behaviour - if (_gw->_continousUpdate) { - requestUpdate(); - } - -} - -static void setOSGModifier(int& modifiers, unsigned int bits, bool set) -{ - if (set) { - modifiers |= bits; - } else { - modifiers &= ~bits; - } -} - -void GLWindow::setKeyboardModifiers(const Qt::KeyboardModifiers qtMods) -{ - auto es = _gw->getEventQueue()->getCurrentEventState(); - auto modifiers = es->getModKeyMask(); - -#if defined(Q_OS_MACOS) - setOSGModifier(modifiers, osgGA::GUIEventAdapter::MODKEY_CTRL, qtMods & Qt::MetaModifier); -#else - setOSGModifier(modifiers, osgGA::GUIEventAdapter::MODKEY_CTRL, qtMods & Qt::ControlModifier); -#endif - setOSGModifier(modifiers, osgGA::GUIEventAdapter::MODKEY_ALT, qtMods & Qt::AltModifier); - setOSGModifier(modifiers, osgGA::GUIEventAdapter::MODKEY_SHIFT, qtMods & Qt::ShiftModifier); - - _gw->getEventQueue()->getCurrentEventState()->setModKeyMask(modifiers); -} - -void GLWindow::resizeEvent( QResizeEvent* event ) -{ - QWindow::resizeEvent(event); - syncGeometryWithOSG(); -} - -void GLWindow::moveEvent( QMoveEvent* event ) -{ - QWindow::moveEvent(event); - syncGeometryWithOSG(); -} - -void GLWindow::keyPressEvent( QKeyEvent* event ) -{ - setKeyboardModifiers( event->modifiers() ); - int value = s_QtKeyboardMap.remapKey( event ); - _gw->getEventQueue()->keyPress( value ); - - // this passes the event to the regular Qt key event processing, - // among others, it closes popup windows on ESC and forwards the event to the parent widgets - if( _forwardKeyEvents ) - inherited::keyPressEvent( event ); -} - -void GLWindow::keyReleaseEvent( QKeyEvent* event ) -{ - if (event->isAutoRepeat()) { - event->ignore(); - } else { - setKeyboardModifiers(event->modifiers() ); - int value = s_QtKeyboardMap.remapKey( event ); - _gw->getEventQueue()->keyRelease( value ); - } - - // this passes the event to the regular Qt key event processing, - // among others, it closes popup windows on ESC and forwards the event to the parent widgets - if( _forwardKeyEvents ) - inherited::keyReleaseEvent( event ); -} - -void GLWindow::mousePressEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers(event->modifiers()); - _gw->getEventQueue()->mouseButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWindow::mouseReleaseEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers(event->modifiers()); - _gw->getEventQueue()->mouseButtonRelease( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWindow::mouseDoubleClickEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers(event->modifiers()); - _gw->getEventQueue()->mouseDoubleButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWindow::mouseMoveEvent( QMouseEvent* event ) -{ - setKeyboardModifiers(event->modifiers()); - _gw->getEventQueue()->mouseMotion( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio ); -} - -void GLWindow::wheelEvent( QWheelEvent* event ) -{ - setKeyboardModifiers(event->modifiers()); - _gw->getEventQueue()->mouseScroll( - event->orientation() == Qt::Vertical ? - (event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) : - (event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT) ); -} - -GraphicsWindowQt5::GraphicsWindowQt5(osg::GraphicsContext::Traits* traits) -{ - _traits = traits; - init(0); -} - -GraphicsWindowQt5::~GraphicsWindowQt5() -{ - OSG_INFO << "destroying GraphicsWindowQt5" << std::endl; - close(); -} - -bool GraphicsWindowQt5::init( Qt::WindowFlags f ) -{ - // update _widget and parent by WindowData - WindowData* windowData = _traits.get() ? dynamic_cast(_traits->inheritedWindowData.get()) : 0; - assert(!_window); - _ownsWidget = true; - - // WindowFlags - Qt::WindowFlags flags = f | Qt::Window | Qt::CustomizeWindowHint; - if ( _traits->windowDecoration ) { - flags |= Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint; - flags |= Qt::WindowFullscreenButtonHint; - - // TODO - check if this is desirable or not on Windows+Linux - //flags |= Qt::MaximizeUsingFullscreenGeometryHint; - } - - // create window - _window.reset(new GLWindow); - _window->setFlags(flags); - _window->setSurfaceType(QSurface::OpenGLSurface); - _window->setFormat(traits2qSurfaceFormat(_traits.get())); - _window->create(); - _window->setTitle( _traits->windowName.c_str() ); - - // to get OS-dependant default positioning of the window (which is desirable), - // we must take care to only set the position if explicitly requested. - // hence we set X & Y to these marker values by default. - // And hence only set position if both are valid. - if ((_traits->x != std::numeric_limits::max()) && (_traits->y != std::numeric_limits::max())) { - _window->setPosition( _traits->x, _traits->y ); - } - - QSize sz(_traits->width, _traits->height); - if ( !_traits->supportsResize ) { - _window->setMinimumSize( sz ); - _window->setMaximumSize( sz ); - } else { - _window->resize( sz ); - } - - if (windowData->createFullscreen) { - // this doesn't seem to actually work, so we - // check the flag again in realizeImplementation() - _window->setWindowState(Qt::WindowFullScreen); - } - - _window->_isPrimaryWindow = windowData->isPrimaryWindow; - if (_window->_isPrimaryWindow) { - fgSetDouble("/sim/rendering/gui-pixel-ratio", _window->_devicePixelRatio); - } - - _window->setGraphicsWindow( this ); - useCursor( _traits->useCursor ); - - // initialize State - setState( new osg::State ); - getState()->setGraphicsContext(this); - getState()->setContextID( osg::GraphicsContext::createNewContextID() ); - - // make sure the event queue has the correct window rectangle size and input range - getEventQueue()->syncWindowRectangleWithGraphicsContext(); - - return true; -} - -QSurfaceFormat GraphicsWindowQt5::traits2qSurfaceFormat( const osg::GraphicsContext::Traits* traits ) -{ - QSurfaceFormat format; - format.setRenderableType(QSurfaceFormat::OpenGL); - - format.setAlphaBufferSize( traits->alpha ); - format.setRedBufferSize( traits->red ); - format.setGreenBufferSize( traits->green ); - format.setBlueBufferSize( traits->blue ); - format.setDepthBufferSize( traits->depth ); - format.setStencilBufferSize( traits->stencil ); - // format.setSampleBuffers( traits->sampleBuffers ); - format.setSamples( traits->samples ); - - format.setAlphaBufferSize( traits->alpha>0 ); - format.setDepthBufferSize( traits->depth ); - - format.setSwapBehavior( traits->doubleBuffer ? - QSurfaceFormat::DoubleBuffer : - QSurfaceFormat::DefaultSwapBehavior); - format.setSwapInterval( traits->vsync ? 1 : 0 ); - format.setStereo( traits->quadBufferStereo ? 1 : 0 ); - - return format; -} - -void GraphicsWindowQt5::qSurfaceFormat2traits( const QSurfaceFormat& format, osg::GraphicsContext::Traits* traits ) -{ - traits->red = format.redBufferSize(); - traits->green = format.greenBufferSize(); - traits->blue = format.blueBufferSize(); - traits->alpha = format.alphaBufferSize(); - traits->depth = format.depthBufferSize(); - traits->stencil = format.stencilBufferSize(); - traits->samples = format.samples(); - - traits->quadBufferStereo = format.stereo(); - traits->doubleBuffer = (format.swapBehavior() == QSurfaceFormat::DoubleBuffer); - traits->vsync = format.swapInterval() >= 1; -} - -osg::GraphicsContext::Traits* GraphicsWindowQt5::createTraits( const QWindow* window ) -{ - osg::GraphicsContext::Traits *traits = new osg::GraphicsContext::Traits; - - qSurfaceFormat2traits( window->format(), traits ); - - QRect r = window->geometry(); - traits->x = r.x(); - traits->y = r.y(); - traits->width = r.width(); - traits->height = r.height(); - - traits->windowName = window->title().toLocal8Bit().data(); - Qt::WindowFlags f = window->flags(); - traits->windowDecoration = ( f & Qt::WindowTitleHint ) && - ( f & Qt::WindowMinMaxButtonsHint ) && - ( f & Qt::WindowSystemMenuHint ); - - traits->supportsResize = true; - - /* - QSizePolicy sp = window->sizePolicy(); - traits->supportsResize = sp.horizontalPolicy() != QSizePolicy::Fixed || - sp.verticalPolicy() != QSizePolicy::Fixed; -*/ - return traits; -} - -bool GraphicsWindowQt5::setWindowRectangleImplementation( int x, int y, int width, int height ) -{ - if (!_window) - return false; - - qDebug() << "setWRI window geometry to " << x << "," << y << - " w=" << width << " h=" << height; - _window->setGeometry( x, y, width, height ); - return true; -} - -void GraphicsWindowQt5::getWindowRectangle( int& x, int& y, int& width, int& height ) -{ - if ( _window ) - { - const QRect& geom = _window->geometry(); - x = geom.x(); - y = geom.y(); - width = geom.width(); - height = geom.height(); - } -} - -bool GraphicsWindowQt5::setWindowDecorationImplementation( bool windowDecoration ) -{ - Qt::WindowFlags flags = Qt::Window|Qt::CustomizeWindowHint;//|Qt::WindowStaysOnTopHint; - if ( windowDecoration ) - flags |= Qt::WindowTitleHint|Qt::WindowMinMaxButtonsHint|Qt::WindowSystemMenuHint; - _traits->windowDecoration = windowDecoration; - - if ( _window ) - { - _window->setFlags( flags ); - return true; - } - - return false; -} - -bool GraphicsWindowQt5::getWindowDecoration() const -{ - return _traits->windowDecoration; -} - -void GraphicsWindowQt5::grabFocus() -{ - if ( _window ) - _window->requestActivate(); -} - -void GraphicsWindowQt5::grabFocusIfPointerInWindow() -{ - #if 0 - if ( _widget->underMouse() ) - _widget->setFocus( Qt::ActiveWindowFocusReason ); - #endif -} - -void GraphicsWindowQt5::raiseWindow() -{ - if ( _window ) - _window->raise(); -} - -void GraphicsWindowQt5::setWindowName( const std::string& name ) -{ - if ( _window ) - _window->setTitle( QString::fromUtf8(name.c_str()) ); -} - -std::string GraphicsWindowQt5::getWindowName() -{ - return _window ? _window->title().toStdString() : ""; -} - -void GraphicsWindowQt5::useCursor( bool cursorOn ) -{ - if ( _window ) - { - _traits->useCursor = cursorOn; - if ( !cursorOn ) _window->setCursor( Qt::BlankCursor ); - else _window->setCursor( _currentCursor ); - } -} - -void GraphicsWindowQt5::setCursor( MouseCursor cursor ) -{ - if ( cursor==InheritCursor && _window ) - { - _window->unsetCursor(); - } - - switch ( cursor ) - { - case NoCursor: _currentCursor = Qt::BlankCursor; break; - case RightArrowCursor: case LeftArrowCursor: _currentCursor = Qt::ArrowCursor; break; - case InfoCursor: _currentCursor = Qt::SizeAllCursor; break; - case DestroyCursor: _currentCursor = Qt::ForbiddenCursor; break; - case HelpCursor: _currentCursor = Qt::WhatsThisCursor; break; - case CycleCursor: _currentCursor = Qt::ForbiddenCursor; break; - case SprayCursor: _currentCursor = Qt::SizeAllCursor; break; - case WaitCursor: _currentCursor = Qt::WaitCursor; break; - case TextCursor: _currentCursor = Qt::IBeamCursor; break; - case CrosshairCursor: _currentCursor = Qt::CrossCursor; break; - case HandCursor: _currentCursor = Qt::OpenHandCursor; break; - case UpDownCursor: _currentCursor = Qt::SizeVerCursor; break; - case LeftRightCursor: _currentCursor = Qt::SizeHorCursor; break; - case TopSideCursor: case BottomSideCursor: _currentCursor = Qt::UpArrowCursor; break; - case LeftSideCursor: case RightSideCursor: _currentCursor = Qt::SizeHorCursor; break; - case TopLeftCorner: _currentCursor = Qt::SizeBDiagCursor; break; - case TopRightCorner: _currentCursor = Qt::SizeFDiagCursor; break; - case BottomRightCorner: _currentCursor = Qt::SizeBDiagCursor; break; - case BottomLeftCorner: _currentCursor = Qt::SizeFDiagCursor; break; - default: break; - }; - if ( _window ) _window->setCursor( _currentCursor ); -} - -bool GraphicsWindowQt5::valid() const -{ - return _window.get() != nullptr; -} - -bool GraphicsWindowQt5::realizeImplementation() -{ - WindowData* windowData = _traits.get() ? dynamic_cast(_traits->inheritedWindowData.get()) : nullptr; - if (windowData->createFullscreen) { - _window->showFullScreen(); - // work-around for resize events being discarded by EventQueue::setStartTick - _sendResizeOnEventCheck = true; - } else { - _window->show(); - } - - // make sure the event queue has the correct window rectangle size and input range - getEventQueue()->syncWindowRectangleWithGraphicsContext(); - - getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS); - - _realized = true; - return true; -} - -bool GraphicsWindowQt5::isRealizedImplementation() const -{ - return _realized; -} - -void GraphicsWindowQt5::closeImplementation() -{ - if ( _window ) { - _window->close(); - _window.reset(); - } - - _context.reset(); - _realized = false; -} - -void GraphicsWindowQt5::runOperations() -{ - // While in graphics thread this is last chance to do something useful before - // graphics thread will execute its operations. - if (_updateContextNeeded || (QOpenGLContext::currentContext() != _context.get())) { - makeCurrent(); - _updateContextNeeded = false; - } - - _window->beforeRendering(); - - GraphicsWindow::runOperations(); - - _window->afterRendering(); -} - -bool GraphicsWindowQt5::makeCurrentImplementation() -{ - if (!_context) { - if ( _traits->sharedContext.valid() ) { - qWarning() << Q_FUNC_INFO << "share contexts not supported"; - } - - _context.reset(new QOpenGLContext()); - _context->setFormat(_window->format()); - bool result = _context->create(); - if (!result) - { - OSG_WARN << "GraphicsWindowQt5: Can't create QOpenGLContext'" << std::endl; - return false; - } - - _context->makeCurrent(_window.get()); - // allow derived classes to do work now the context is initalised - contextInitalised(); - } - - if (_context && (QThread::currentThread() != _context->thread())) { - qWarning() << "attempt to make context current on wrong thread"; - return false; - } - - _context->makeCurrent(_window.get()); - return true; -} - -bool GraphicsWindowQt5::releaseContextImplementation() -{ - _context->doneCurrent(); - return true; -} - -void GraphicsWindowQt5::swapBuffersImplementation() -{ - _context->swapBuffers(_window.get()); -} - -void GraphicsWindowQt5::requestWarpPointer( float x, float y ) -{ - if ( _window ) - QCursor::setPos( _window->mapToGlobal(QPoint((int)x,(int)y)) ); - - getEventQueue()->mouseWarped(x,y); -} - -bool GraphicsWindowQt5::checkEvents() -{ - if (_sendResizeOnEventCheck) { - _sendResizeOnEventCheck = false; - _window->syncGeometryWithOSG(); - } - -// todo - only if not running inside QApplication::exec; can we check this? - QCoreApplication::processEvents(QEventLoop::AllEvents); - - return true; -} - -void GraphicsWindowQt5::setViewer(osgViewer::ViewerBase* viewer) -{ - osg::ref_ptr previous(_viewer); - _viewer = viewer; - viewerChanged(previous.get()); -} - -void GraphicsWindowQt5::viewerChanged(osgViewer::ViewerBase*) -{ - // nothing -} - -void GraphicsWindowQt5::requestRedraw() -{ - _window->requestUpdate(); -} - -void GraphicsWindowQt5::requestContinuousUpdate(bool needed) -{ - _continousUpdate = needed; - GraphicsWindow::requestContinuousUpdate(needed); - if (_continousUpdate) { - _window->requestUpdate(); - } -} - -void GraphicsWindowQt5::setFullscreen(bool isFullscreen) -{ - if (isFullscreen) { - _window->showFullScreen(); - } else { - // FIXME should restore previous state? - _window->showNormal(); - } -} - - -class Qt5WindowingSystem : public osg::GraphicsContext::WindowingSystemInterface -{ -public: - - Qt5WindowingSystem() - { -#if OSG_VERSION_GREATER_THAN(3,5,9) - setName("FlightGearQt5"); -#endif - } - - ~Qt5WindowingSystem() - { - if (osg::Referenced::getDeleteHandler()) - { - osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0); - osg::Referenced::getDeleteHandler()->flushAll(); - } - } - - // Access the Qt windowing system through this singleton class. - static Qt5WindowingSystem* getInterface() - { - static Qt5WindowingSystem* qtInterface = new Qt5WindowingSystem; - return qtInterface; - } - - // Return the number of screens present in the system - virtual unsigned int getNumScreens( const osg::GraphicsContext::ScreenIdentifier& /*si*/ ) - { - return QGuiApplication::screens().size(); - } - - // Return the resolution of specified screen - // (0,0) is returned if screen is unknown - virtual void getScreenSettings( const osg::GraphicsContext::ScreenIdentifier& si, - osg::GraphicsContext::ScreenSettings& resolution ) - { - QScreen* screen = qScreenFromSI(si); - if (!screen) { - qWarning() << Q_FUNC_INFO << "no screen for identifier" << QString::fromStdString(si.displayName()); - return; - } - - resolution.width = screen->size().width(); - resolution.height = screen->size().height(); - resolution.colorDepth = screen->depth(); - resolution.refreshRate = screen->refreshRate(); - } - - // Set the resolution for given screen - virtual bool setScreenSettings( const osg::GraphicsContext::ScreenIdentifier& /*si*/, const osg::GraphicsContext::ScreenSettings & /*resolution*/ ) - { - OSG_WARN << "osgQt: setScreenSettings() not implemented yet." << std::endl; - return false; - } - - // Enumerates available resolutions - virtual void enumerateScreenSettings( const osg::GraphicsContext::ScreenIdentifier& si, - osg::GraphicsContext::ScreenSettingsList & resolutions ) - { - QScreen* screen = qScreenFromSI(si); - if (!screen) { - qWarning() << Q_FUNC_INFO << "no screen for identifier" << QString::fromStdString(si.displayName()); - return; - } - - resolutions.clear(); - osg::GraphicsContext::ScreenSettings ss; - ss.width = screen->size().width(); - ss.height = screen->size().height(); - ss.colorDepth = screen->depth(); - ss.refreshRate = screen->refreshRate(); - resolutions.push_back(ss); - } - - // Create a graphics context with given traits - virtual osg::GraphicsContext* createGraphicsContext( osg::GraphicsContext::Traits* traits ) - { - if (traits->pbuffer) - { - OSG_WARN << "osgQt: createGraphicsContext - pbuffer not implemented yet." << std::endl; - return NULL; - } - else - { - osg::ref_ptr< GraphicsWindowQt5 > window = new GraphicsWindowQt5( traits ); - if (window->valid()) { - return window.release(); - } - else { - qWarning() << "window is not valid"; - return NULL; - } - } - } - -private: - QScreen* qScreenFromSI(const osg::GraphicsContext::ScreenIdentifier& si) - { - QList screens = QGuiApplication::screens(); - if (screens.size() < si.screenNum) { - return screens.at(si.screenNum); - } - - return QGuiApplication::primaryScreen(); - } - - // No implementation for these - Qt5WindowingSystem( const Qt5WindowingSystem& ); - Qt5WindowingSystem& operator=( const Qt5WindowingSystem& ); -}; - -namespace flightgear -{ - -void initQtWindowingSystem() -{ -#if OSG_VERSION_LESS_THAN(3,5,2) - osg::GraphicsContext::setWindowingSystemInterface(Qt5WindowingSystem::getInterface()); -#else - osg::GraphicsContext::getWindowingSystemInterfaces()->addWindowingSystemInterface(Qt5WindowingSystem::getInterface()); -#endif -} - -} // of namespace flightgear diff --git a/src/Viewer/GraphicsWindowQt5.hxx b/src/Viewer/GraphicsWindowQt5.hxx deleted file mode 100644 index 042b3dcac..000000000 --- a/src/Viewer/GraphicsWindowQt5.hxx +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (C) 2017 James Turner -// derived from OSG GraphicsWindowQt by Wang Rui -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program 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 GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#ifndef FGFS_GRAPHICSWINDOWQT -#define FGFS_GRAPHICSWINDOWQT - -#include - -#include -#include - -#include -#include -#include -#include - -class QInputEvent; -class QGestureEvent; -class QOpenGLContext; - -namespace osgViewer { - class ViewerBase; -} - -namespace flightgear -{ - -// forward declarations -class GraphicsWindowQt5; - -/// The function sets the WindowingSystem to Qt. -void initQtWindowingSystem(); - -class GLWindow : public QWindow -{ - Q_OBJECT - typedef QWindow inherited; - -public: - GLWindow(); - - virtual ~GLWindow(); - - virtual void setGraphicsWindow( GraphicsWindowQt5* gw ) { _gw = gw; } - virtual GraphicsWindowQt5* getGraphicsWindow() { return _gw; } - virtual const GraphicsWindowQt5* getGraphicsWindow() const { return _gw; } - - inline bool getForwardKeyEvents() const { return _forwardKeyEvents; } - virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; } - - void setKeyboardModifiers(const Qt::KeyboardModifiers qtMods); - - virtual void keyPressEvent( QKeyEvent* event ); - virtual void keyReleaseEvent( QKeyEvent* event ); - virtual void mousePressEvent( QMouseEvent* event ); - virtual void mouseReleaseEvent( QMouseEvent* event ); - virtual void mouseDoubleClickEvent( QMouseEvent* event ); - virtual void mouseMoveEvent( QMouseEvent* event ); - virtual void wheelEvent( QWheelEvent* event ); - -signals: - void beforeRendering(); - void afterRendering(); - -private slots: - void onScreenChanged(); - - void processUpdateEvent(); - -protected: - void syncGeometryWithOSG(); - - void updateEventQueueModifiers(QKeyEvent* event); - - - friend class GraphicsWindowQt5; - GraphicsWindowQt5* _gw = nullptr; // back-pointer - - bool _forwardKeyEvents = false; - qreal _devicePixelRatio = 1.0; - - // is this the primary (GUI) window - bool _isPrimaryWindow = false; - - virtual void resizeEvent( QResizeEvent* event ); - virtual void moveEvent( QMoveEvent* event ); - virtual bool event( QEvent* event ); -}; - -class GraphicsWindowQt5 : public osgViewer::GraphicsWindow -{ -public: - GraphicsWindowQt5( osg::GraphicsContext::Traits* traits = 0); - virtual ~GraphicsWindowQt5(); - - inline GLWindow* getGLWindow() { return _window.get(); } - inline const GLWindow* getGLWindow() const { return _window.get(); } - - struct WindowData : public osg::Referenced - { - WindowData( GLWindow* win = NULL ): _window(win) {} - GLWindow* _window; - - bool createFullscreen = false; - - // is this the main window, corresponding to the /sim/startup - // properties? If so we will drive them in some cases. - bool isPrimaryWindow = false; - }; - - bool init( Qt::WindowFlags f ); - - static QSurfaceFormat traits2qSurfaceFormat( const osg::GraphicsContext::Traits* traits ); - static void qSurfaceFormat2traits( const QSurfaceFormat& format, osg::GraphicsContext::Traits* traits ); - static osg::GraphicsContext::Traits* createTraits( const QWindow* window ); - - virtual bool setWindowRectangleImplementation( int x, int y, int width, int height ); - virtual void getWindowRectangle( int& x, int& y, int& width, int& height ); - virtual bool setWindowDecorationImplementation( bool windowDecoration ); - virtual bool getWindowDecoration() const; - virtual void grabFocus(); - virtual void grabFocusIfPointerInWindow(); - virtual void raiseWindow(); - virtual void setWindowName( const std::string& name ); - virtual std::string getWindowName(); - virtual void useCursor( bool cursorOn ); - virtual void setCursor( MouseCursor cursor ); - // inline bool getTouchEventsEnabled() const { return _widget->getTouchEventsEnabled(); } - // virtual void setTouchEventsEnabled( bool e ) { _widget->setTouchEventsEnabled(e); } - - - virtual bool valid() const; - virtual bool realizeImplementation(); - virtual bool isRealizedImplementation() const; - virtual void closeImplementation(); - virtual bool makeCurrentImplementation(); - virtual bool releaseContextImplementation(); - virtual void swapBuffersImplementation(); - virtual void runOperations(); - virtual bool checkEvents(); - - virtual void requestRedraw(); - virtual void requestContinuousUpdate(bool needed=true); - - virtual void requestWarpPointer( float x, float y ); - - /** - * set the viewer for this window. This will be refreshed when then - * QGuiApplication event loop runs (via exec), or when the window - * needs to be updated. - */ - void setViewer( osgViewer::ViewerBase *viewer ); - - virtual void contextInitalised() { ; } - - void setFullscreen(bool isFullscreen); -protected: - virtual void viewerChanged(osgViewer::ViewerBase*); - - friend class GLWindow; - std::unique_ptr _window; - std::unique_ptr _context; - QOpenGLContext* _shareContext = nullptr; - bool _ownsWidget; - QCursor _currentCursor; - bool _realized = false; - bool _updateContextNeeded = false; - bool _continousUpdate = false; - osg::observer_ptr< osgViewer::ViewerBase > _viewer; - - // if true, we will generate a resize event on the next - // call to check events. Ths works around OSG clearing the - // event queue on us. - bool _sendResizeOnEventCheck = false; -}; - -} // of namespace flightgear - -#endif