1 /***************************************************************************
3 ** Copyright (C) 2011 - 2012 Research In Motion
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qqnxintegration.h"
43 #include "qqnxeventthread.h"
44 #include "qqnxglbackingstore.h"
45 #include "qqnxglcontext.h"
46 #include "qqnxnativeinterface.h"
47 #include "qqnxnavigatoreventhandler.h"
48 #include "qqnxnavigatoreventnotifier.h"
49 #include "qqnxrasterbackingstore.h"
50 #include "qqnxscreen.h"
51 #include "qqnxscreeneventhandler.h"
52 #include "qqnxwindow.h"
53 #include "qqnxvirtualkeyboard.h"
54 #include "qqnxclipboard.h"
55 #include "qqnxglcontext.h"
56 #include "qqnxservices.h"
59 #include "qqnxinputcontext_imf.h"
61 #include "qqnxinputcontext_noimf.h"
64 #include "private/qgenericunixfontdatabase_p.h"
65 #include "private/qgenericunixeventdispatcher_p.h"
67 #include <QtGui/QPlatformWindow>
68 #include <QtGui/QWindowSystemInterface>
69 #include <QtGui/QOpenGLContext>
71 #include <QtCore/QDebug>
72 #include <QtCore/QHash>
78 QQnxWindowMapper QQnxIntegration::ms_windowMapper;
79 QMutex QQnxIntegration::ms_windowMapperMutex;
81 QQnxIntegration::QQnxIntegration()
82 : QPlatformIntegration()
84 , m_navigatorEventHandler(new QQnxNavigatorEventHandler())
85 , m_navigatorEventNotifier(0)
86 , m_virtualKeyboard(0)
88 , m_fontDatabase(new QGenericUnixFontDatabase())
89 , m_paintUsingOpenGL(false)
90 , m_eventDispatcher(createUnixEventDispatcher())
91 , m_nativeInterface(new QQnxNativeInterface())
93 , m_screenEventHandler(new QQnxScreenEventHandler())
94 #ifndef QT_NO_CLIPBOARD
98 #if defined(QQNXINTEGRATION_DEBUG)
99 qDebug() << Q_FUNC_INFO;
101 // Open connection to QNX composition manager
103 int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT);
105 qFatal("QQnx: failed to connect to composition manager, errno=%d", errno);
108 // Create/start navigator event notifier
109 m_navigatorEventNotifier = new QQnxNavigatorEventNotifier(m_navigatorEventHandler);
111 // delay invocation of start() to the time the event loop is up and running
112 // needed to have the QThread internals of the main thread properly initialized
113 QMetaObject::invokeMethod(m_navigatorEventNotifier, "start", Qt::QueuedConnection);
115 // Create displays for all possible screens (which may not be attached)
118 // Initialize global OpenGL resources
119 QQnxGLContext::initialize();
121 // Create/start event thread
122 m_eventThread = new QQnxEventThread(m_screenContext, m_screenEventHandler);
123 m_eventThread->start();
125 // Create/start the keyboard class.
126 m_virtualKeyboard = new QQnxVirtualKeyboard();
128 // delay invocation of start() to the time the event loop is up and running
129 // needed to have the QThread internals of the main thread properly initialized
130 QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection);
132 // TODO check if we need to do this for all screens or only the primary one
133 QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)),
134 primaryDisplay(), SLOT(keyboardHeightChanged(int)));
136 // Set up the input context
137 m_inputContext = new QQnxInputContext(*m_virtualKeyboard);
139 // Create services handling class
140 #ifdef Q_OS_BLACKBERRY
141 m_services = new QQnxServices;
145 QQnxIntegration::~QQnxIntegration()
147 #if defined(QQNXINTEGRATION_DEBUG)
148 qDebug() << "QQnx: platform plugin shutdown begin";
152 delete m_nativeInterface;
154 // Destroy input context
155 delete m_inputContext;
157 // Destroy the keyboard class.
158 delete m_virtualKeyboard;
160 #ifndef QT_NO_CLIPBOARD
161 // Delete the clipboard
165 // Stop/destroy navigator event notifier
166 delete m_navigatorEventNotifier;
167 delete m_navigatorEventHandler;
169 // Stop/destroy event thread
170 delete m_eventThread;
171 delete m_screenEventHandler;
173 // Destroy all displays
176 // Close connection to QNX composition manager
177 screen_destroy_context(m_screenContext);
179 // Cleanup global OpenGL resources
180 QQnxGLContext::shutdown();
182 // Destroy services class
183 #ifdef Q_OS_BLACKBERRY
187 #if defined(QQNXINTEGRATION_DEBUG)
188 qDebug() << "QQnx: platform plugin shutdown end";
192 bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const
194 #if defined(QQNXINTEGRATION_DEBUG)
195 qDebug() << Q_FUNC_INFO;
198 case ThreadedPixmaps: return true;
199 #if defined(QT_OPENGL_ES)
203 default: return QPlatformIntegration::hasCapability(cap);
207 QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
209 #if defined(QQNXINTEGRATION_DEBUG)
210 qDebug() << Q_FUNC_INFO;
212 return new QQnxWindow(window, m_screenContext);
215 QPlatformBackingStore *QQnxIntegration::createPlatformBackingStore(QWindow *window) const
217 #if defined(QQNXINTEGRATION_DEBUG)
218 qDebug() << Q_FUNC_INFO;
220 if (paintUsingOpenGL())
221 return new QQnxGLBackingStore(window);
223 return new QQnxRasterBackingStore(window);
226 QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
228 #if defined(QQNXINTEGRATION_DEBUG)
229 qDebug() << Q_FUNC_INFO;
231 return new QQnxGLContext(context);
234 QPlatformInputContext *QQnxIntegration::inputContext() const
236 #if defined(QQNXINTEGRATION_DEBUG)
237 qDebug() << Q_FUNC_INFO;
239 return m_inputContext;
242 void QQnxIntegration::moveToScreen(QWindow *window, int screen)
244 #if defined(QQNXINTEGRATION_DEBUG)
245 qDebug() << "QQnxIntegration::moveToScreen - w=" << window << ", s=" << screen;
248 // get platform window used by widget
249 QQnxWindow *platformWindow = static_cast<QQnxWindow *>(window->handle());
251 // lookup platform screen by index
252 QQnxScreen *platformScreen = m_screens.at(screen);
254 // move the platform window to the platform screen
255 platformWindow->setScreen(platformScreen);
258 QAbstractEventDispatcher *QQnxIntegration::guiThreadEventDispatcher() const
260 #if defined(QQNXINTEGRATION_DEBUG)
261 qDebug() << Q_FUNC_INFO;
263 return m_eventDispatcher;
266 QPlatformNativeInterface *QQnxIntegration::nativeInterface() const
268 return m_nativeInterface;
271 #ifndef QT_NO_CLIPBOARD
272 QPlatformClipboard *QQnxIntegration::clipboard() const
274 #if defined(QQNXINTEGRATION_DEBUG)
275 qDebug() << Q_FUNC_INFO;
278 m_clipboard = new QQnxClipboard;
284 QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
286 #if defined(QQNXINTEGRATION_DEBUG)
287 qDebug() << Q_FUNC_INFO;
289 if (hint == ShowIsFullScreen)
292 return QPlatformIntegration::styleHint(hint);
295 QPlatformServices * QQnxIntegration::services() const
300 QWindow *QQnxIntegration::window(screen_window_t qnxWindow)
302 #if defined(QQNXINTEGRATION_DEBUG)
303 qDebug() << Q_FUNC_INFO;
305 QMutexLocker locker(&ms_windowMapperMutex);
307 return ms_windowMapper.value(qnxWindow, 0);
310 void QQnxIntegration::addWindow(screen_window_t qnxWindow, QWindow *window)
312 #if defined(QQNXINTEGRATION_DEBUG)
313 qDebug() << Q_FUNC_INFO;
315 QMutexLocker locker(&ms_windowMapperMutex);
317 ms_windowMapper.insert(qnxWindow, window);
320 void QQnxIntegration::removeWindow(screen_window_t qnxWindow)
322 #if defined(QQNXINTEGRATION_DEBUG)
323 qDebug() << Q_FUNC_INFO;
325 QMutexLocker locker(&ms_windowMapperMutex);
327 ms_windowMapper.remove(qnxWindow);
330 void QQnxIntegration::createDisplays()
332 #if defined(QQNXINTEGRATION_DEBUG)
333 qDebug() << Q_FUNC_INFO;
335 // Query number of displays
338 int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount);
340 qFatal("QQnxIntegration: failed to query display count, errno=%d", errno);
345 screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
346 result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays);
348 qFatal("QQnxIntegration: failed to query displays, errno=%d", errno);
351 for (int i=0; i<displayCount; i++) {
352 #if defined(QQNXINTEGRATION_DEBUG)
353 qDebug() << "QQnxIntegration::Creating screen for display " << i;
355 QQnxScreen *screen = new QQnxScreen(m_screenContext, displays[i], i==0);
356 m_screens.append(screen);
359 QObject::connect(m_screenEventHandler, SIGNAL(newWindowCreated(void *)),
360 screen, SLOT(newWindowCreated(void *)));
361 QObject::connect(m_screenEventHandler, SIGNAL(windowClosed(void *)),
362 screen, SLOT(windowClosed(void *)));
364 QObject::connect(m_navigatorEventHandler, SIGNAL(rotationChanged(int)), screen, SLOT(setRotation(int)));
368 void QQnxIntegration::destroyDisplays()
370 #if defined(QQNXINTEGRATION_DEBUG)
371 qDebug() << Q_FUNC_INFO;
373 qDeleteAll(m_screens);
377 QQnxScreen *QQnxIntegration::primaryDisplay() const
379 return m_screens.first();