LP-500 add hottbridgestatus uavobjct to GCS
[librepilot.git] / ground / gcs / src / libs / osgearth / utils / qtwindowingsystem.cpp
blob2ae29b2202a8d6da63fae5709e86127c88e58cb5
1 /**
2 ******************************************************************************
4 * @file qtwindowingsystem.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
6 * @addtogroup
7 * @{
8 * @addtogroup
9 * @{
10 * @brief
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "qtwindowingsystem.h"
30 #include "utility.h"
32 #include <osg/DeleteHandler>
33 #include <osg/Version>
34 #include <osgViewer/GraphicsWindow>
36 #include <QOpenGLContext>
37 #include <QOffscreenSurface>
38 #include <QDebug>
40 #include <string>
42 // TODO no need to derive from GraphicsWindow (derive directly from GraphicsContext instead)
43 class GraphicsWindowQt : public osgViewer::GraphicsWindow {
44 public:
45 GraphicsWindowQt(osg::GraphicsContext::Traits *traits);
46 ~GraphicsWindowQt();
48 bool isSameKindAs(const Object *object) const
50 return dynamic_cast<const GraphicsWindowQt *>(object) != 0;
52 const char *libraryName() const
54 return "osgViewerXYZ";
56 const char *className() const
58 return "GraphicsWindowQt";
61 bool setWindowRectangleImplementation(int x, int y, int width, int height);
62 void getWindowRectangle(int & x, int & y, int & width, int & height);
63 bool setWindowDecorationImplementation(bool windowDecoration);
64 bool getWindowDecoration() const;
65 void grabFocus();
66 void grabFocusIfPointerInWindow();
67 void raiseWindow();
68 void setWindowName(const std::string & name);
69 std::string getWindowName();
70 void useCursor(bool cursorOn);
71 void setCursor(MouseCursor cursor);
72 bool valid() const;
73 bool realizeImplementation();
74 bool isRealizedImplementation() const;
75 void closeImplementation();
76 bool makeCurrentImplementation();
77 bool releaseContextImplementation();
78 void swapBuffersImplementation();
79 void runOperations();
81 void requestWarpPointer(float x, float y);
83 protected:
84 void init();
86 bool _initialized;
87 bool _valid;
88 bool _realized;
90 bool _owned;
92 QOpenGLContext *_glContext;
93 QOffscreenSurface *_surface;
96 GraphicsWindowQt::GraphicsWindowQt(osg::GraphicsContext::Traits *traits) :
97 _initialized(false),
98 _valid(false),
99 _realized(false),
100 _owned(false),
101 _glContext(NULL),
102 _surface(NULL)
104 // qDebug() << "GraphicsWindowQt::GraphicsWindowQt";
105 _traits = traits;
106 init();
109 GraphicsWindowQt::~GraphicsWindowQt()
111 // qDebug() << "GraphicsWindowQt::~GraphicsWindowQt";
112 close(true);
115 void GraphicsWindowQt::init()
117 // qDebug() << "GraphicsWindowQt::init";
118 if (_initialized) {
119 return;
122 // update by WindowData
123 // WindowData* windowData = _traits.get() ? dynamic_cast<WindowData*>(_traits->inheritedWindowData.get()) : 0;
124 // if ( !_widget )
125 // _widget = windowData ? windowData->_widget : NULL;
126 // if ( !parent )
127 // parent = windowData ? windowData->_parent : NULL;
130 setState(new osg::State);
131 getState()->setGraphicsContext(this);
133 if (_traits.valid() && _traits->sharedContext.valid()) {
134 getState()->setContextID(_traits->sharedContext->getState()->getContextID());
135 incrementContextIDUsageCount(getState()->getContextID());
136 } else {
137 getState()->setContextID(osg::GraphicsContext::createNewContextID());
140 // make sure the event queue has the correct window rectangle size and input range
141 #if OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0)
142 getEventQueue()->syncWindowRectangleWithGraphicsContext();
143 #else
144 getEventQueue()->syncWindowRectangleWithGraphcisContext();
145 #endif
147 _initialized = true;
149 _valid = _initialized;
152 bool GraphicsWindowQt::setWindowRectangleImplementation(int x, int y, int width, int height)
154 return true;
157 void GraphicsWindowQt::getWindowRectangle(int & x, int & y, int & width, int & height)
160 bool GraphicsWindowQt::setWindowDecorationImplementation(bool windowDecoration)
162 return false;
165 bool GraphicsWindowQt::getWindowDecoration() const
167 return false;
170 void GraphicsWindowQt::grabFocus()
173 void GraphicsWindowQt::grabFocusIfPointerInWindow()
176 void GraphicsWindowQt::raiseWindow()
179 void GraphicsWindowQt::setWindowName(const std::string & name)
182 std::string GraphicsWindowQt::getWindowName()
184 return "";
187 void GraphicsWindowQt::useCursor(bool cursorOn)
190 void GraphicsWindowQt::setCursor(MouseCursor cursor)
193 bool GraphicsWindowQt::valid() const
195 return _valid;
198 bool GraphicsWindowQt::realizeImplementation()
200 // qDebug() << "GraphicsWindowQt::realizeImplementation";
201 // save the current context
202 // note: this will save only Qt-based contexts
204 if (_realized) {
205 return true;
208 if (!_initialized) {
209 init();
210 if (!_initialized) {
211 return false;
215 QOpenGLContext *currentContext = QOpenGLContext::currentContext();
217 if (!currentContext) {
218 // qDebug() << "GraphicsWindowQt::realizeImplementation - creating owned context";
219 _owned = true;
220 _glContext = new QOpenGLContext();
221 _glContext->create();
222 _surface = new QOffscreenSurface();
223 _surface->setFormat(_glContext->format());
224 _surface->create();
225 #ifdef OSG_VERBOSE
226 osgQtQuick::formatInfo(_surface->format());
227 #endif
228 } else {
229 // qDebug() << "GraphicsWindowQt::realizeImplementation - using current context";
230 _glContext = currentContext;
233 //// initialize GL context for the widget
234 // if ( !valid() )
235 // _widget->glInit();
237 // make current
238 _realized = true;
239 bool current = makeCurrent();
241 // fail if we do not have current context
242 if (!current) {
243 // if ( savedContext )
244 // const_cast< QGLContext* >( savedContext )->makeCurrent();
246 qWarning() << "GraphicsWindowQt::realizeImplementation - can not make context current.";
247 _realized = false;
248 return false;
251 // make sure the event queue has the correct window rectangle size and input range
252 #if OSG_VERSION_GREATER_OR_EQUAL(3, 4, 0)
253 getEventQueue()->syncWindowRectangleWithGraphicsContext();
254 #else
255 getEventQueue()->syncWindowRectangleWithGraphcisContext();
256 #endif
258 // make this window's context not current
259 // note: this must be done as we will probably make the context current from another thread
260 // and it is not allowed to have one context current in two threads
261 if (!releaseContext()) {
262 qWarning() << "GraphicsWindowQt::realizeImplementation - can not release context.";
265 //// restore previous context
266 // if ( savedContext )
267 // const_cast< QGLContext* >( savedContext )->makeCurrent();
269 return _realized;
272 bool GraphicsWindowQt::isRealizedImplementation() const
274 return _realized;
277 void GraphicsWindowQt::runOperations()
279 // While in graphics thread this is last chance to do something useful before
280 // graphics thread will execute its operations.
281 // if (_widget->getNumDeferredEvents() > 0)
282 // _widget->processDeferredEvents();
284 // if (QGLContext::currentContext() != _widget->context())
285 // _widget->makeCurrent();
287 // qDebug() << "GraphicsWindowQt::runOperations";
288 GraphicsWindow::runOperations();
291 bool GraphicsWindowQt::makeCurrentImplementation()
293 if (!_glContext) {
294 qWarning() << "GraphicsWindowQt::makeCurrentImplementation() - no context.";
295 return false;
297 if (!_realized) {
298 qWarning() << "GraphicsWindowQt::makeCurrentImplementation() - not realized; cannot make current.";
299 return false;
301 if (_owned) {
302 if (!_glContext->makeCurrent(_surface)) {
303 qWarning() << "GraphicsWindowQt::makeCurrentImplementation : failed to make context current";
304 return false;
307 if (_glContext != QOpenGLContext::currentContext()) {
308 qWarning() << "GraphicsWindowQt::makeCurrentImplementation : context is not current";
309 // abort();
310 return false;
312 return true;
315 bool GraphicsWindowQt::releaseContextImplementation()
317 if (!_glContext) {
318 qWarning() << "GraphicsWindowQt::releaseContextImplementation() - no context.";
319 return false;
321 if (_glContext != QOpenGLContext::currentContext()) {
322 qWarning() << "GraphicsWindowQt::releaseContextImplementation : context is not current";
323 return false;
325 if (_owned) {
326 // qDebug() << "GraphicsWindowQt::releaseContextImplementation";
327 _glContext->doneCurrent();
328 if (_glContext == QOpenGLContext::currentContext()) {
329 qWarning() << "GraphicsWindowQt::releaseContextImplementation : context is still current";
332 return true;
335 void GraphicsWindowQt::closeImplementation()
337 // qDebug() << "GraphicsWindowQt::closeImplementation";
338 _initialized = false;
339 _valid = false;
340 _realized = false;
341 if (_owned) {
342 if (_glContext) {
343 // qDebug() << "GraphicsWindowQt::closeImplementation - deleting owned context";
344 delete _glContext;
346 if (_surface) {
347 _surface->destroy();
348 delete _surface;
351 _glContext = NULL;
352 _surface = NULL;
355 void GraphicsWindowQt::swapBuffersImplementation()
357 // _widget->swapBuffers();
359 //// FIXME: the processDeferredEvents should really be executed in a GUI (main) thread context but
360 //// I couln't find any reliable way to do this. For now, lets hope non of *GUI thread only operations* will
361 //// be executed in a QGLWidget::event handler. On the other hand, calling GUI only operations in the
362 //// QGLWidget event handler is an indication of a Qt bug.
363 // if (_widget->getNumDeferredEvents() > 0)
364 // _widget->processDeferredEvents();
366 //// We need to call makeCurrent here to restore our previously current context
367 //// which may be changed by the processDeferredEvents function.
368 // if (QGLContext::currentContext() != _widget->context())
369 // _widget->makeCurrent();
372 void GraphicsWindowQt::requestWarpPointer(float x, float y)
375 QtWindowingSystem::QtWindowingSystem()
378 QtWindowingSystem::~QtWindowingSystem()
380 if (osg::Referenced::getDeleteHandler()) {
381 osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
382 osg::Referenced::getDeleteHandler()->flushAll();
386 // Return the number of screens present in the system
387 unsigned int QtWindowingSystem::getNumScreens(const osg::GraphicsContext::ScreenIdentifier & /*si*/)
389 qWarning() << "osgQt: getNumScreens() not implemented yet.";
390 return 0;
393 // Return the resolution of specified screen
394 // (0,0) is returned if screen is unknown
395 void QtWindowingSystem::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier & /*si*/, osg::GraphicsContext::ScreenSettings & /*resolution*/)
397 qWarning() << "osgQt: getScreenSettings() not implemented yet.";
400 // Set the resolution for given screen
401 bool QtWindowingSystem::setScreenSettings(const osg::GraphicsContext::ScreenIdentifier & /*si*/, const osg::GraphicsContext::ScreenSettings & /*resolution*/)
403 qWarning() << "osgQt: setScreenSettings() not implemented yet.";
404 return false;
407 // Enumerates available resolutions
408 void QtWindowingSystem::enumerateScreenSettings(const osg::GraphicsContext::ScreenIdentifier & /*screenIdentifier*/, osg::GraphicsContext::ScreenSettingsList & /*resolution*/)
410 qWarning() << "osgQt: enumerateScreenSettings() not implemented yet.";
413 // Create a graphics context with given traits
414 osg::GraphicsContext *QtWindowingSystem::createGraphicsContext(osg::GraphicsContext::Traits *traits)
416 // if (traits->pbuffer)
417 // {
418 // OSG_WARN << "osgQt: createGraphicsContext - pbuffer not implemented yet.";
419 // return NULL;
420 // }
421 // else
422 // {
423 osg::ref_ptr< GraphicsWindowQt > gc = new GraphicsWindowQt(traits);
425 if (gc->valid()) {
426 return gc.release();
427 } else {
428 return NULL;
430 // }