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 74 QT_BEGIN_NAMESPACE 75 76 class QCoreTextFontEngine; 77 78 template <typename BaseEventDispatcher> 79 class QOffscreenEventDispatcher : public BaseEventDispatcher 80 { 81 public: QOffscreenEventDispatcher(QObject * parent=nullptr)82 explicit QOffscreenEventDispatcher(QObject *parent = nullptr) 83 : BaseEventDispatcher(parent) 84 { 85 } 86 processEvents(QEventLoop::ProcessEventsFlags flags)87 bool processEvents(QEventLoop::ProcessEventsFlags flags) 88 { 89 bool didSendEvents = BaseEventDispatcher::processEvents(flags); 90 91 return QWindowSystemInterface::sendWindowSystemEvents(flags) || didSendEvents; 92 } 93 hasPendingEvents()94 bool hasPendingEvents() 95 { 96 return BaseEventDispatcher::hasPendingEvents() 97 || QWindowSystemInterface::windowSystemEventsQueued(); 98 } 99 flush()100 void flush() 101 { 102 if (qApp) 103 qApp->sendPostedEvents(); 104 BaseEventDispatcher::flush(); 105 } 106 }; 107 QOffscreenIntegration()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(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(new QOffscreenDrag); 122 #endif 123 m_services.reset(new QPlatformServices); 124 125 m_screen = new QOffscreenScreen; 126 QWindowSystemInterface::handleScreenAdded(m_screen); 127 } 128 ~QOffscreenIntegration()129QOffscreenIntegration::~QOffscreenIntegration() 130 { 131 QWindowSystemInterface::handleScreenRemoved(m_screen); 132 } 133 initialize()134void QOffscreenIntegration::initialize() 135 { 136 m_inputContext.reset(QPlatformInputContextFactory::create()); 137 } 138 inputContext() const139QPlatformInputContext *QOffscreenIntegration::inputContext() const 140 { 141 return m_inputContext.data(); 142 } 143 hasCapability(QPlatformIntegration::Capability cap) const144bool QOffscreenIntegration::hasCapability(QPlatformIntegration::Capability cap) const 145 { 146 switch (cap) { 147 case ThreadedPixmaps: return true; 148 case MultipleWindows: return true; 149 default: return QPlatformIntegration::hasCapability(cap); 150 } 151 } 152 createPlatformWindow(QWindow * window) const153QPlatformWindow *QOffscreenIntegration::createPlatformWindow(QWindow *window) const 154 { 155 Q_UNUSED(window); 156 QPlatformWindow *w = new QOffscreenWindow(window); 157 w->requestActivateWindow(); 158 return w; 159 } 160 createPlatformBackingStore(QWindow * window) const161QPlatformBackingStore *QOffscreenIntegration::createPlatformBackingStore(QWindow *window) const 162 { 163 return new QOffscreenBackingStore(window); 164 } 165 createEventDispatcher() const166QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const 167 { 168 #if defined(Q_OS_UNIX) 169 return createUnixEventDispatcher(); 170 #elif defined(Q_OS_WIN) 171 #ifndef Q_OS_WINRT 172 return new QOffscreenEventDispatcher<QEventDispatcherWin32>(); 173 #else // !Q_OS_WINRT 174 return new QOffscreenEventDispatcher<QEventDispatcherWinRT>(); 175 #endif // Q_OS_WINRT 176 #else 177 return 0; 178 #endif 179 } 180 nativeInterface() const181QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const 182 { 183 if (!m_nativeInterface) 184 m_nativeInterface.reset(new QOffscreenPlatformNativeInterface); 185 return m_nativeInterface.get(); 186 } 187 themeName()188static QString themeName() { return QStringLiteral("offscreen"); } 189 themeNames() const190QStringList QOffscreenIntegration::themeNames() const 191 { 192 return QStringList(themeName()); 193 } 194 195 // Restrict the styles to "fusion" to prevent native styles requiring native 196 // window handles (eg Windows Vista style) from being used. 197 class OffscreenTheme : public QPlatformTheme 198 { 199 public: OffscreenTheme()200 OffscreenTheme() {} 201 themeHint(ThemeHint h) const202 QVariant themeHint(ThemeHint h) const override 203 { 204 switch (h) { 205 case StyleNames: 206 return QVariant(QStringList(QStringLiteral("fusion"))); 207 default: 208 break; 209 } 210 return QPlatformTheme::themeHint(h); 211 } 212 }; 213 createPlatformTheme(const QString & name) const214QPlatformTheme *QOffscreenIntegration::createPlatformTheme(const QString &name) const 215 { 216 return name == themeName() ? new OffscreenTheme() : nullptr; 217 } 218 fontDatabase() const219QPlatformFontDatabase *QOffscreenIntegration::fontDatabase() const 220 { 221 return m_fontDatabase.data(); 222 } 223 224 #if QT_CONFIG(draganddrop) drag() const225QPlatformDrag *QOffscreenIntegration::drag() const 226 { 227 return m_drag.data(); 228 } 229 #endif 230 services() const231QPlatformServices *QOffscreenIntegration::services() const 232 { 233 return m_services.data(); 234 } 235 createOffscreenIntegration()236QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() 237 { 238 #if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) 239 QByteArray glx = qgetenv("QT_QPA_OFFSCREEN_NO_GLX"); 240 if (glx.isEmpty()) 241 return new QOffscreenX11Integration; 242 #endif 243 return new QOffscreenIntegration; 244 } 245 246 QT_END_NAMESPACE 247