1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qoffscreenintegration.h"
41#include "qoffscreenwindow.h"
42#include "qoffscreencommon.h"
43
44#if defined(Q_OS_UNIX)
45#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
46#if defined(Q_OS_MAC)
47#include <qpa/qplatformfontdatabase.h>
48#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
49#else
50#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
51#endif
52#elif defined(Q_OS_WIN)
53#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
54#ifndef Q_OS_WINRT
55#include <QtCore/private/qeventdispatcher_win_p.h>
56#else
57#include <QtCore/private/qeventdispatcher_winrt_p.h>
58#endif
59#endif
60
61#include <QtGui/private/qpixmap_raster_p.h>
62#include <QtGui/private/qguiapplication_p.h>
63#include <qpa/qplatforminputcontextfactory_p.h>
64#include <qpa/qplatforminputcontext.h>
65#include <qpa/qplatformtheme.h>
66#include <qpa/qwindowsysteminterface.h>
67
68#include <qpa/qplatformservices.h>
69
70#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2)
71#include "qoffscreenintegration_x11.h"
72#endif
73
74QT_BEGIN_NAMESPACE
75
76class QCoreTextFontEngine;
77
78template <typename BaseEventDispatcher>
79class QOffscreenEventDispatcher : public BaseEventDispatcher
80{
81public:
82 explicit QOffscreenEventDispatcher(QObject *parent = nullptr)
83 : BaseEventDispatcher(parent)
84 {
85 }
86
87 bool processEvents(QEventLoop::ProcessEventsFlags flags)
88 {
89 bool didSendEvents = BaseEventDispatcher::processEvents(flags);
90
91 return QWindowSystemInterface::sendWindowSystemEvents(flags) || didSendEvents;
92 }
93
94 bool hasPendingEvents()
95 {
96 return BaseEventDispatcher::hasPendingEvents()
97 || QWindowSystemInterface::windowSystemEventsQueued();
98 }
99
100 void flush()
101 {
102 if (qApp)
103 qApp->sendPostedEvents();
104 BaseEventDispatcher::flush();
105 }
106};
107
108QOffscreenIntegration::QOffscreenIntegration()
109{
110#if defined(Q_OS_UNIX)
111#if defined(Q_OS_MAC)
112 m_fontDatabase.reset(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>);
113#else
114 m_fontDatabase.reset(other: new QGenericUnixFontDatabase());
115#endif
116#elif defined(Q_OS_WIN)
117 m_fontDatabase.reset(new QFreeTypeFontDatabase());
118#endif
119
120#if QT_CONFIG(draganddrop)
121 m_drag.reset(other: new QOffscreenDrag);
122#endif
123 m_services.reset(other: new QPlatformServices);
124
125 QWindowSystemInterface::handleScreenAdded(screen: new QOffscreenScreen);
126}
127
128QOffscreenIntegration::~QOffscreenIntegration()
129{
130}
131
132void QOffscreenIntegration::initialize()
133{
134 m_inputContext.reset(other: QPlatformInputContextFactory::create());
135}
136
137QPlatformInputContext *QOffscreenIntegration::inputContext() const
138{
139 return m_inputContext.data();
140}
141
142bool QOffscreenIntegration::hasCapability(QPlatformIntegration::Capability cap) const
143{
144 switch (cap) {
145 case ThreadedPixmaps: return true;
146 case MultipleWindows: return true;
147 default: return QPlatformIntegration::hasCapability(cap);
148 }
149}
150
151QPlatformWindow *QOffscreenIntegration::createPlatformWindow(QWindow *window) const
152{
153 Q_UNUSED(window);
154 QPlatformWindow *w = new QOffscreenWindow(window);
155 w->requestActivateWindow();
156 return w;
157}
158
159QPlatformBackingStore *QOffscreenIntegration::createPlatformBackingStore(QWindow *window) const
160{
161 return new QOffscreenBackingStore(window);
162}
163
164QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const
165{
166#if defined(Q_OS_UNIX)
167 return createUnixEventDispatcher();
168#elif defined(Q_OS_WIN)
169#ifndef Q_OS_WINRT
170 return new QOffscreenEventDispatcher<QEventDispatcherWin32>();
171#else // !Q_OS_WINRT
172 return new QOffscreenEventDispatcher<QEventDispatcherWinRT>();
173#endif // Q_OS_WINRT
174#else
175 return 0;
176#endif
177}
178
179QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const
180{
181 if (!m_nativeInterface)
182 m_nativeInterface.reset(other: new QOffscreenPlatformNativeInterface);
183 return m_nativeInterface.get();
184}
185
186static QString themeName() { return QStringLiteral("offscreen"); }
187
188QStringList QOffscreenIntegration::themeNames() const
189{
190 return QStringList(themeName());
191}
192
193// Restrict the styles to "fusion" to prevent native styles requiring native
194// window handles (eg Windows Vista style) from being used.
195class OffscreenTheme : public QPlatformTheme
196{
197public:
198 OffscreenTheme() {}
199
200 QVariant themeHint(ThemeHint h) const override
201 {
202 switch (h) {
203 case StyleNames:
204 return QVariant(QStringList(QStringLiteral("fusion")));
205 default:
206 break;
207 }
208 return QPlatformTheme::themeHint(hint: h);
209 }
210};
211
212QPlatformTheme *QOffscreenIntegration::createPlatformTheme(const QString &name) const
213{
214 return name == themeName() ? new OffscreenTheme() : nullptr;
215}
216
217QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const
218{
219 return m_fontDatabase.data();
220}
221
222#if QT_CONFIG(draganddrop)
223QPlatformDrag *QOffscreenIntegration::drag() const
224{
225 return m_drag.data();
226}
227#endif
228
229QPlatformServices *QOffscreenIntegration::services() const
230{
231 return m_services.data();
232}
233
234QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration()
235{
236#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2)
237 QByteArray glx = qgetenv(varName: "QT_QPA_OFFSCREEN_NO_GLX");
238 if (glx.isEmpty())
239 return new QOffscreenX11Integration;
240#endif
241 return new QOffscreenIntegration;
242}
243
244QT_END_NAMESPACE
245

source code of qtbase/src/plugins/platforms/offscreen/qoffscreenintegration.cpp