a46d51127fb996bcd66dbe0e0115cd5b9b10ad61
[profile/ivi/qtbase.git] / src / plugins / platforms / xcb / qxcbintegration.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins 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 #include "qxcbintegration.h"
43 #include "qxcbconnection.h"
44 #include "qxcbscreen.h"
45 #include "qxcbwindow.h"
46 #include "qxcbcursor.h"
47 #include "qxcbkeyboard.h"
48 #include "qxcbbackingstore.h"
49 #include "qxcbnativeinterface.h"
50 #include "qxcbclipboard.h"
51 #include "qxcbdrag.h"
52
53 #include <xcb/xcb.h>
54
55 #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
56 #include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
57 #include <QtPlatformSupport/private/qgenericunixservices_p.h>
58
59 #include <stdio.h>
60
61 //this has to be included before egl, since egl pulls in X headers
62 #include <QtGui/private/qguiapplication_p.h>
63
64 #ifdef XCB_USE_EGL
65 #include <EGL/egl.h>
66 #endif
67
68 #ifdef XCB_USE_XLIB
69 #include <X11/Xlib.h>
70 #endif
71
72 #include <qpa/qplatforminputcontextfactory_p.h>
73 #include <private/qgenericunixthemes_p.h>
74 #include <qpa/qplatforminputcontext.h>
75
76 #if defined(XCB_USE_GLX)
77 #include "qglxintegration.h"
78 #elif defined(XCB_USE_EGL)
79 #include "qxcbeglsurface.h"
80 #include <QtPlatformSupport/private/qeglplatformcontext_p.h>
81 #endif
82
83 #include <QtGui/QOpenGLContext>
84 #include <QtGui/QScreen>
85 #ifndef QT_NO_ACCESSIBILITY
86 #include <qpa/qplatformaccessibility.h>
87 #include "../../../platformsupport/linuxaccessibility/bridge_p.h"
88 #endif
89
90 QT_BEGIN_NAMESPACE
91
92 QXcbIntegration::QXcbIntegration(const QStringList &parameters)
93     : m_eventDispatcher(createUnixEventDispatcher())
94     ,  m_services(new QGenericUnixServices)
95 {
96     QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
97
98 #ifdef XCB_USE_XLIB
99     XInitThreads();
100 #endif
101     m_nativeInterface.reset(new QXcbNativeInterface);
102
103     m_connections << new QXcbConnection(m_nativeInterface.data());
104
105     for (int i = 0; i < parameters.size() - 1; i += 2) {
106 #ifdef Q_XCB_DEBUG
107         qDebug() << "QXcbIntegration: Connecting to additional display: " << parameters.at(i) << parameters.at(i+1);
108 #endif
109         QString display = parameters.at(i) + ':' + parameters.at(i+1);
110         m_connections << new QXcbConnection(m_nativeInterface.data(), display.toLatin1().constData());
111     }
112
113     m_fontDatabase.reset(new QGenericUnixFontDatabase());
114     m_inputContext.reset(QPlatformInputContextFactory::create());
115 #ifndef QT_NO_ACCESSIBILITY
116     m_accessibility.reset(new QSpiAccessibleBridge());
117 #endif
118 }
119
120 QXcbIntegration::~QXcbIntegration()
121 {
122 #if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX)
123     qDeleteAll(m_defaultContextInfos);
124 #endif
125     qDeleteAll(m_connections);
126 }
127
128 QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
129 {
130     return new QXcbWindow(window);
131 }
132
133 #if defined(XCB_USE_EGL)
134 class QEGLXcbPlatformContext : public QEGLPlatformContext
135 {
136 public:
137     QEGLXcbPlatformContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
138                            EGLDisplay display, QXcbConnection *c)
139         : QEGLPlatformContext(glFormat, share, display)
140         , m_connection(c)
141     {
142         Q_XCB_NOOP(m_connection);
143     }
144
145     void swapBuffers(QPlatformSurface *surface)
146     {
147         Q_XCB_NOOP(m_connection);
148         QEGLPlatformContext::swapBuffers(surface);
149         Q_XCB_NOOP(m_connection);
150     }
151
152     bool makeCurrent(QPlatformSurface *surface)
153     {
154         Q_XCB_NOOP(m_connection);
155         bool ret = QEGLPlatformContext::makeCurrent(surface);
156         Q_XCB_NOOP(m_connection);
157         return ret;
158     }
159
160     void doneCurrent()
161     {
162         Q_XCB_NOOP(m_connection);
163         QEGLPlatformContext::doneCurrent();
164         Q_XCB_NOOP(m_connection);
165     }
166
167     EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface)
168     {
169         return static_cast<QXcbWindow *>(surface)->eglSurface()->surface();
170     }
171
172 private:
173     QXcbConnection *m_connection;
174 };
175 #endif
176
177 #ifndef QT_NO_OPENGL
178 QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
179 {
180     QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
181 #if defined(XCB_USE_GLX)
182     QOpenGLDefaultContextInfo *defaultContextInfo;
183     if (m_defaultContextInfos.contains(screen)) {
184         defaultContextInfo = m_defaultContextInfos.value(screen);
185     } else {
186         defaultContextInfo = QOpenGLDefaultContextInfo::create(screen);
187         m_defaultContextInfos.insert(screen, defaultContextInfo);
188     }
189     return new QGLXContext(screen, context->format(), context->shareHandle(), defaultContextInfo);
190 #elif defined(XCB_USE_EGL)
191     return new QEGLXcbPlatformContext(context->format(), context->shareHandle(),
192         screen->connection()->egl_display(), screen->connection());
193 #else
194     Q_UNUSED(screen);
195     qWarning("QXcbIntegration: Cannot create platform OpenGL context, neither GLX nor EGL are enabled");
196     return 0;
197 #endif
198 }
199 #endif
200
201 QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
202 {
203     return new QXcbBackingStore(window);
204 }
205
206 bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
207 {
208     switch (cap) {
209     case ThreadedPixmaps: return true;
210 #if defined(XCB_USE_GLX)
211     case OpenGL: return m_connections.at(0)->hasGLX();
212 #elif defined(XCB_USE_EGL)
213     case OpenGL: return true;
214 #else
215     case OpenGL: return false;
216 #endif
217     case ThreadedOpenGL: return false;
218     case WindowMasks: return true;
219     default: return QPlatformIntegration::hasCapability(cap);
220     }
221 }
222
223 QAbstractEventDispatcher *QXcbIntegration::guiThreadEventDispatcher() const
224 {
225     return m_eventDispatcher;
226 }
227
228 void QXcbIntegration::moveToScreen(QWindow *window, int screen)
229 {
230     Q_UNUSED(window);
231     Q_UNUSED(screen);
232 }
233
234 QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
235 {
236     return m_fontDatabase.data();
237 }
238
239 QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
240 {
241     return m_nativeInterface.data();
242 }
243
244 #ifndef QT_NO_CLIPBOARD
245 QPlatformClipboard *QXcbIntegration::clipboard() const
246 {
247     return m_connections.at(0)->clipboard();
248 }
249 #endif
250
251 #ifndef QT_NO_DRAGANDDROP
252 QPlatformDrag *QXcbIntegration::drag() const
253 {
254     return m_connections.at(0)->drag();
255 }
256 #endif
257
258 QPlatformInputContext *QXcbIntegration::inputContext() const
259 {
260     return m_inputContext.data();
261 }
262
263 #ifndef QT_NO_ACCESSIBILITY
264 QPlatformAccessibility *QXcbIntegration::accessibility() const
265 {
266     return m_accessibility.data();
267 }
268 #endif
269
270 QPlatformServices *QXcbIntegration::services() const
271 {
272     return m_services.data();
273 }
274
275 Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const
276 {
277     int keybMask = 0;
278     QXcbConnection *conn = m_connections.at(0);
279     QXcbCursor::queryPointer(conn, 0, 0, &keybMask);
280     return conn->keyboard()->translateModifiers(keybMask);
281 }
282
283 QStringList QXcbIntegration::themeNames() const
284 {
285     return QGenericUnixTheme::themeNames();
286 }
287
288 QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const
289 {
290     return QGenericUnixTheme::createUnixTheme(name);
291 }
292
293 /*!
294   Called by QXcbConnection prior to a QQnxScreen being deleted.
295
296   Destroys and cleans up any default OpenGL context info for this screen.
297 */
298 void QXcbIntegration::removeDefaultOpenGLContextInfo(QXcbScreen *screen)
299 {
300 #if !defined(QT_NO_OPENGL) && defined(XCB_USE_GLX)
301     if (!m_defaultContextInfos.contains(screen))
302         return;
303     QOpenGLDefaultContextInfo* info = m_defaultContextInfos.take(screen);
304     delete info;
305 #else
306     Q_UNUSED(screen);
307 #endif
308 }
309
310 QT_END_NAMESPACE