Qt 4.8
qbbintegration.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 - 2012 Research In Motion <blackberry-qt@qnx.com>
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 //#define QBBINTEGRATION_DEBUG
43 
44 #include "qbbintegration.h"
45 #include "qbbinputcontext.h"
46 #include "qbbscreeneventthread.h"
47 #include "qbbglcontext.h"
48 #include "qbbglwindowsurface.h"
51 #include "qbbrasterwindowsurface.h"
52 #include "qbbscreen.h"
53 #include "qbbscreeneventhandler.h"
54 #include "qbbwindow.h"
55 #include "qbbvirtualkeyboardpps.h"
57 #include "qbbclipboard.h"
58 #include "qbbglcontext.h"
59 #include "qbblocalethread.h"
60 #include "qbbnativeinterface.h"
61 #include "qbbbuttoneventnotifier.h"
62 #if defined(Q_OS_BLACKBERRY)
63 #include "qbbbpseventfilter.h"
64 #include "qbbvirtualkeyboardbps.h"
65 #endif
66 
67 #include <QtCore/QAbstractEventDispatcher>
68 #include <QtGui/QApplication>
69 #include <QtGui/private/qpixmap_raster_p.h>
70 #include <QtGui/QPlatformWindow>
71 #include <QtGui/QWindowSystemInterface>
72 #include <QtOpenGL/private/qpixmapdata_gl_p.h>
73 #include <QDebug>
74 
75 #include <errno.h>
76 
77 #if defined(Q_OS_BLACKBERRY)
78 #include <bps/navigator.h>
79 #endif
80 
82 
83 Q_DECLARE_METATYPE(screen_window_t);
84 
86  mScreenEventThread(0),
87  mNavigatorEventHandler(new QBBNavigatorEventHandler()),
88  mButtonsNotifier(new QBBButtonEventNotifier()),
89  mFontDb(new QGenericUnixFontDatabase()),
90  mScreenEventHandler(new QBBScreenEventHandler(this)),
91  mPaintUsingOpenGL(getenv("QBB_USE_OPENGL") != NULL),
92  mVirtualKeyboard(0),
93  mNativeInterface(new QBBNativeInterface(this)),
94  mBpsEventFilter(0)
95 {
96  qRegisterMetaType<screen_window_t>();
97 
98  if (mPaintUsingOpenGL) {
99  // Set default window API to OpenGL
103  }
104 
105  // initialize global OpenGL resources
107 
108  // open connection to QNX composition manager
109  errno = 0;
110  int result = screen_create_context(&mContext, SCREEN_APPLICATION_CONTEXT);
111  if (result != 0) {
112  qFatal("QBB: failed to connect to composition manager, errno=%d", errno);
113  }
114 
115  // Create/start navigator event notifier
116  // Not on BlackBerry, it has specialised event dispatcher which also handles navigator events
117 #if !defined(Q_OS_BLACKBERRY)
119 
120  // delay invocation of start() to the time the event loop is up and running
121  // needed to have the QThread internals of the main thread properly initialized
123 #endif
124 
125  // Create displays for all possible screens (which may not be attached)
126  createDisplays();
127 
128  // create/start event thread
129 #if defined(QBB_SCREENEVENTTHREAD)
132 #endif
133 
134 #ifdef QBBLOCALETHREAD_ENABLED
135  // Start the locale change monitoring thread.
136  mLocaleThread = new QBBLocaleThread();
137  mLocaleThread->start();
138 #endif
139 
140 #if defined(Q_OS_BLACKBERRY)
141  bps_initialize();
142 
143  QBBVirtualKeyboardBps *virtualKeyboardBps = new QBBVirtualKeyboardBps;
144 
146  (mScreenEventThread ? 0 : mScreenEventHandler), virtualKeyboardBps);
147 
148  if (!mScreenEventThread) {
149  Q_FOREACH (QPlatformScreen *platformScreen, mScreens) {
150  QBBScreen *screen = static_cast<QBBScreen*>(platformScreen);
152  }
153  }
154 
156 
157  mVirtualKeyboard = virtualKeyboardBps;
158 #else
159  // create/start the keyboard class.
161 
162  // delay invocation of start() to the time the event loop is up and running
163  // needed to have the QThread internals of the main thread properly initialized
165 #endif
166 
167  // TODO check if we need to do this for all screens or only the primary one
168  QObject::connect(mVirtualKeyboard, SIGNAL(heightChanged(int)),
169  primaryDisplay(), SLOT(keyboardHeightChanged(int)));
170 
171  // Set up the input context
172  qApp->setInputContext(new QBBInputContext(*mVirtualKeyboard, qApp));
173 
174  // delay invocation of start() to the time the event loop is up and running
175  // needed to have the QThread internals of the main thread properly initialized
177 }
178 
180 {
181 #if defined(QBBINTEGRATION_DEBUG)
182  qDebug() << "QBB: platform plugin shutdown begin";
183 #endif
184  delete mNativeInterface;
185 
186  // Destroy the hardware button notifier
187  delete mButtonsNotifier;
188 
189 #ifdef QBBLOCALETHREAD_ENABLED
190  // stop/destroy the locale thread.
191  delete mLocaleThread;
192 #endif
193 
194 #if defined(QBB_SCREENEVENTTHREAD)
195  // stop/destroy event thread
196  delete mScreenEventThread;
197 #elif defined(Q_OS_BLACKBERRY)
198  Q_FOREACH (QPlatformScreen *platformScreen, mScreens) {
199  QBBScreen *screen = static_cast<QBBScreen*>(platformScreen);
201  }
202 #endif
203 
204 #if defined(Q_OS_BLACKBERRY)
205  delete mBpsEventFilter;
206 #else
207  // stop/destroy navigator event handling classes
209 #endif
210 
211  // destroy the keyboard class.
212  delete mVirtualKeyboard;
213 
214  delete mNavigatorEventHandler;
215  delete mScreenEventHandler;
216 
217  // destroy all displays
218  destroyDisplays();
219 
220  // close connection to QNX composition manager
221  screen_destroy_context(mContext);
222 
223  // cleanup global OpenGL resources
225 
226 #if defined(Q_OS_BLACKBERRY)
227  bps_shutdown();
228 #endif
229 
230 #if defined(QBBINTEGRATION_DEBUG)
231  qDebug() << "QBB: platform plugin shutdown end";
232 #endif
233 }
234 
236 {
237  switch (cap) {
238  case ThreadedPixmaps: return true;
239 #if defined(QT_OPENGL_ES)
240  case OpenGL: return true;
241 #endif
242  default: return QPlatformIntegration::hasCapability(cap);
243  }
244 }
245 
247 {
248  if (paintUsingOpenGL())
249  return new QGLPixmapData(type);
250  else
251  return new QRasterPixmapData(type);
252 }
253 
255 {
256  Q_UNUSED(winId);
257 
258  return new QBBWindow(widget, mContext, primaryDisplay());
259 }
260 
262 {
263  Q_UNUSED(winId);
264  if (paintUsingOpenGL())
265  return new QBBGLWindowSurface(widget);
266  else
267  return new QBBRasterWindowSurface(widget);
268 }
269 
271 {
272  return mNativeInterface;
273 }
274 
276 {
277 #if defined(QBBINTEGRATION_DEBUG)
278  qDebug() << "QBBIntegration::moveToScreen - w=" << window << ", s=" << screen;
279 #endif
280 
281  // get platform window used by widget
282  QBBWindow* platformWindow = static_cast<QBBWindow*>(window->platformWindow());
283 
284  // lookup platform screen by index
285  QBBScreen* platformScreen = static_cast<QBBScreen*>(mScreens.at(screen));
286 
287  // move the platform window to the platform screen (this can fail when move to screen
288  // is called before the window is actually created).
289  if (platformWindow && platformScreen)
290  platformWindow->setScreen(platformScreen);
291 }
292 
294 {
295  return mScreens;
296 }
297 
298 #ifndef QT_NO_CLIPBOARD
300 {
301  static QPlatformClipboard *clipboard = 0;
302  if (!clipboard) {
303  clipboard = static_cast<QPlatformClipboard *>(new QBBClipboard);
304  }
305  return clipboard;
306 }
307 #endif
308 
309 
311 {
312  screen_display_t display = 0;
313  if (screen_get_window_property_pv(window, SCREEN_PROPERTY_DISPLAY, (void**)&display) != 0) {
314  qWarning("QBBIntegration: Failed to get screen for window, errno=%d", errno);
315  return 0;
316  }
317 
318  Q_FOREACH (QPlatformScreen *screen, mScreens) {
319  QBBScreen * const bbScreen = static_cast<QBBScreen*>(screen);
320  if (bbScreen->nativeDisplay() == display)
321  return bbScreen;
322  }
323 
324  return 0;
325 }
326 
328 {
329  return static_cast<QBBScreen*>(mScreens.first());
330 }
331 
333 {
335 }
336 
338 {
339  // get number of displays
340  errno = 0;
341  int displayCount;
342  int result = screen_get_context_property_iv(mContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount);
343  if (result != 0)
344  qFatal("QBBIntegration: failed to query display count, errno=%d", errno);
345 
346  // get all displays
347  errno = 0;
348  screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
349  result = screen_get_context_property_pv(mContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays);
350  if (result != 0)
351  qFatal("QBBIntegration: failed to query displays, errno=%d", errno);
352 
353  for (int i=0; i<displayCount; i++) {
354  int isAttached = 0;
355  result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED, &isAttached);
356  if (result != 0) {
357  qWarning("QBBIntegration: failed to query display attachment, errno=%d", errno);
358  isAttached = 1; // assume attached
359  }
360 
361  if (!isAttached)
362  continue;
363 
364  createDisplay(displays[i], i);
365  } // of displays iteration
366 }
367 
368 void QBBIntegration::createDisplay(screen_display_t display, int screenIndex)
369 {
370  QBBScreen *screen = new QBBScreen(mContext, display, screenIndex);
371  mScreens.append(screen);
372  screen->adjustOrientation();
373 
374  QObject::connect(mScreenEventHandler, SIGNAL(newWindowCreated(screen_window_t)),
375  screen, SLOT(newWindowCreated(screen_window_t)));
376  QObject::connect(mScreenEventHandler, SIGNAL(windowClosed(screen_window_t)),
377  screen, SLOT(windowClosed(screen_window_t)));
378 
379  QObject::connect(mNavigatorEventHandler, SIGNAL(rotationChanged(int)), screen, SLOT(setRotation(int)));
380  QObject::connect(mNavigatorEventHandler, SIGNAL(windowGroupActivated(QByteArray)), screen, SLOT(activateWindowGroup(QByteArray)));
381  QObject::connect(mNavigatorEventHandler, SIGNAL(windowGroupDeactivated(QByteArray)), screen, SLOT(deactivateWindowGroup(QByteArray)));
383  screen, SLOT(windowGroupStateChanged(QByteArray,Qt::WindowState)));
384 }
385 
387 {
388  Q_CHECK_PTR(screen);
389  Q_ASSERT(mScreens.contains(screen));
390  mScreens.removeAll(screen);
391  screen->deleteLater();
392 }
393 
395 {
397  mScreens.clear();
398 }
399 
400 QBBScreen *QBBIntegration::screenForNative(screen_display_t nativeScreen) const
401 {
402  Q_FOREACH (QPlatformScreen *screen, mScreens) {
403  QBBScreen *bbScreen = static_cast<QBBScreen*>(screen);
404  if (bbScreen->nativeDisplay() == nativeScreen)
405  return bbScreen;
406  }
407 
408  return 0;
409 }
410 
QBBLocaleThread * mLocaleThread
unsigned long WId
Definition: qwindowdefs.h:119
int type
Definition: qmetatype.cpp:239
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
void unregisterForScreenEvents(QBBScreen *screen)
The QPlatformScreen class provides an abstraction for visual displays.
QBBNativeInterface * mNativeInterface
void setScreen(QBBScreen *platformScreen)
Definition: qbbwindow.cpp:474
void createDisplay(screen_display_t display, int screenIndex)
static QAbstractEventDispatcher * instance(QThread *thread=0)
Returns a pointer to the event dispatcher object for the specified thread.
virtual QList< QPlatformScreen * > screens() const
Accessor function to a list of all the screens on the current system.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
Q_DECLARE_METATYPE(screen_window_t)
static QPlatformWindowFormat defaultFormat()
Returns the default QPlatformWindowFormat for the application.
#define SLOT(a)
Definition: qobjectdefs.h:226
virtual bool hasCapability(Capability cap) const
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
virtual void moveToScreen(QWidget *window, int screen)
This function is called when a QWidget is displayed on screen, or the QWidget is to be displayed on a...
The QPlatformWindowFormat class specifies the display format of an OpenGL rendering context and if po...
The QPlatformWindow class provides an abstraction for top-level windows.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QBBAbstractVirtualKeyboard * mVirtualKeyboard
QBBButtonEventNotifier * mButtonsNotifier
virtual bool hasCapability(QPlatformIntegration::Capability cap) const
virtual ~QBBIntegration()
QList< QPlatformScreen * > mScreens
Q_CORE_EXPORT void qDebug(const char *,...)
#define SIGNAL(a)
Definition: qobjectdefs.h:227
virtual QPixmapData * createPixmapData(QPixmapData::PixelType type) const
Factory function for QPixmapData.
NSWindow * window
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
Q_GUI_EXPORT EGLDisplay display()
Definition: qegl.cpp:589
static void initialize()
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
#define qApp
void injectPointerMoveEvent(int x, int y)
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QBBScreenEventThread * mScreenEventThread
Q_CORE_EXPORT void qWarning(const char *,...)
void clear()
Removes all items from the list.
Definition: qlist.h:764
QBBScreen * screenForNative(screen_display_t screen) const
The QWindowSurface class provides the drawing area for top-level windows.
virtual QPlatformNativeInterface * nativeInterface() const
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
screen_display_t nativeDisplay() const
Definition: qbbscreen.h:72
QBBScreen * primaryDisplay() const
virtual QWindowSurface * createWindowSurface(QWidget *widget, WId winId) const
Factory function for QWindowSurface.
Q_CORE_EXPORT void qFatal(const char *,...)
#define Q_CHECK_PTR(p)
Definition: qglobal.h:1853
void adjustOrientation()
Definition: qbbscreen.cpp:496
virtual void setCursorPos(int x, int y)
void start(Priority=InheritPriority)
Begins execution of the thread by calling run().
QBBBpsEventFilter * mBpsEventFilter
QBBScreenEventHandler * mScreenEventHandler
void setWindowApi(QPlatformWindowFormat::WindowApi api)
void installOnEventDispatcher(QAbstractEventDispatcher *dispatcher)
void removeDisplay(QBBScreen *screen)
void registerForScreenEvents(QBBScreen *screen)
static void shutdown()
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
QBBScreen * screenForWindow(screen_window_t window) const
#define Q_FOREACH(variable, container)
Same as foreach(variable, container).
Definition: qglobal.h:2435
QBBNavigatorEventHandler * mNavigatorEventHandler
QBBNavigatorEventNotifier * mNavigatorEventNotifier
screen_context_t mContext
virtual QPlatformClipboard * clipboard() const
Accessor for the platform integrations clipboard.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
WindowState
Definition: qnamespace.h:366
void deleteLater()
Schedules this object for deletion.
Definition: qobject.cpp:2145
bool paintUsingOpenGL() const
virtual QPlatformWindow * createPlatformWindow(QWidget *widget, WId winId) const
Factory function for QPlatformWindow.
int errno
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static void setDefaultFormat(const QPlatformWindowFormat &f)
Sets a new default QPlatformWindowFormat for the application to f.
int removeAll(const T &t)
Removes all occurrences of value in the list and returns the number of entries removed.
Definition: qlist.h:770