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 "qiosintegration.h" 41#include "qioseventdispatcher.h" 42#include "qiosglobal.h" 43#include "qioswindow.h" 44#include "qiosbackingstore.h" 45#include "qiosscreen.h" 46#include "qiosplatformaccessibility.h" 47#include "qioscontext.h" 48#ifndef Q_OS_TVOS 49#include "qiosclipboard.h" 50#endif 51#include "qiosinputcontext.h" 52#include "qiostheme.h" 53#include "qiosservices.h" 54#include "qiosoptionalplugininterface.h" 55 56#include <QtGui/private/qguiapplication_p.h> 57 58#include <qoffscreensurface.h> 59#include <qpa/qplatformoffscreensurface.h> 60 61#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h> 62#include <QtClipboardSupport/private/qmacmime_p.h> 63#include <QDir> 64#include <QOperatingSystemVersion> 65 66#import <AudioToolbox/AudioServices.h> 67 68#include <QtDebug> 69 70QT_BEGIN_NAMESPACE 71 72class QCoreTextFontEngine; 73 74QIOSIntegration *QIOSIntegration::instance() 75{ 76 return static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration()); 77} 78 79QIOSIntegration::QIOSIntegration() 80 : m_fontDatabase(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>) 81#if !defined(Q_OS_TVOS) && !defined(QT_NO_CLIPBOARD) 82 , m_clipboard(new QIOSClipboard) 83#endif 84 , m_inputContext(0) 85 , m_platformServices(new QIOSServices) 86 , m_accessibility(0) 87 , m_optionalPlugins(new QFactoryLoader(QIosOptionalPluginInterface_iid, QLatin1String("/platforms/darwin"))) 88{ 89 if (Q_UNLIKELY(!qt_apple_isApplicationExtension() && !qt_apple_sharedApplication())) { 90 qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n" \ 91 "If you are writing a native iOS application, and only want to use Qt for\n" \ 92 "parts of the application, a good place to create QApplication is from within\n" \ 93 "'applicationDidFinishLaunching' inside your UIApplication delegate.\n"); 94 } 95 96 // Set current directory to app bundle folder 97 QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); 98} 99 100void QIOSIntegration::initialize() 101{ 102 UIScreen *mainScreen = [UIScreen mainScreen]; 103 NSMutableArray<UIScreen *> *screens = [[[UIScreen screens] mutableCopy] autorelease]; 104 if (![screens containsObject:mainScreen]) { 105 // Fallback for iOS 7.1 (QTBUG-42345) 106 [screens insertObject:mainScreen atIndex:0]; 107 } 108 109 for (UIScreen *screen in screens) 110 QWindowSystemInterface::handleScreenAdded(new QIOSScreen(screen)); 111 112 // Depends on a primary screen being present 113 m_inputContext = new QIOSInputContext; 114 115 m_touchDevice = new QTouchDevice; 116 m_touchDevice->setType(QTouchDevice::TouchScreen); 117 QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition; 118 if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) 119 touchCapabilities |= QTouchDevice::Pressure; 120 m_touchDevice->setCapabilities(touchCapabilities); 121 QWindowSystemInterface::registerTouchDevice(m_touchDevice); 122#if QT_CONFIG(tabletevent) 123 QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); 124#endif 125 QMacInternalPasteboardMime::initializeMimeTypes(); 126 127 for (int i = 0; i < m_optionalPlugins->metaData().size(); ++i) 128 qobject_cast<QIosOptionalPluginInterface *>(m_optionalPlugins->instance(i))->initPlugin(); 129} 130 131QIOSIntegration::~QIOSIntegration() 132{ 133 delete m_fontDatabase; 134 m_fontDatabase = 0; 135 136#if !defined(Q_OS_TVOS) && !defined(QT_NO_CLIPBOARD) 137 delete m_clipboard; 138 m_clipboard = 0; 139#endif 140 QMacInternalPasteboardMime::destroyMimeTypes(); 141 142 delete m_inputContext; 143 m_inputContext = 0; 144 145 foreach (QScreen *screen, QGuiApplication::screens()) 146 QWindowSystemInterface::handleScreenRemoved(screen->handle()); 147 148 delete m_platformServices; 149 m_platformServices = 0; 150 151 delete m_accessibility; 152 m_accessibility = 0; 153 154 delete m_optionalPlugins; 155 m_optionalPlugins = 0; 156} 157 158bool QIOSIntegration::hasCapability(Capability cap) const 159{ 160 switch (cap) { 161 case BufferQueueingOpenGL: 162 return true; 163 case OpenGL: 164 case ThreadedOpenGL: 165 return true; 166 case ThreadedPixmaps: 167 return true; 168 case MultipleWindows: 169 return true; 170 case WindowManagement: 171 return false; 172 case ApplicationState: 173 return true; 174 case RasterGLSurface: 175 return true; 176 default: 177 return QPlatformIntegration::hasCapability(cap); 178 } 179} 180 181QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const 182{ 183 return new QIOSWindow(window); 184} 185 186// Used when the QWindow's surface type is set by the client to QSurface::RasterSurface 187QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const 188{ 189 return new QIOSBackingStore(window); 190} 191 192// Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface 193QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const 194{ 195 return new QIOSContext(context); 196} 197 198class QIOSOffscreenSurface : public QPlatformOffscreenSurface 199{ 200public: 201 QIOSOffscreenSurface(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) {} 202 203 QSurfaceFormat format() const override 204 { 205 Q_ASSERT(offscreenSurface()); 206 return offscreenSurface()->requestedFormat(); 207 } 208 bool isValid() const override { return true; } 209}; 210 211QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const 212{ 213 return new QIOSOffscreenSurface(surface); 214} 215 216QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const 217{ 218 return QIOSEventDispatcher::create(); 219} 220 221QPlatformFontDatabase * QIOSIntegration::fontDatabase() const 222{ 223 return m_fontDatabase; 224} 225 226#ifndef QT_NO_CLIPBOARD 227QPlatformClipboard *QIOSIntegration::clipboard() const 228{ 229#ifndef Q_OS_TVOS 230 return m_clipboard; 231#else 232 return QPlatformIntegration::clipboard(); 233#endif 234} 235#endif 236 237QPlatformInputContext *QIOSIntegration::inputContext() const 238{ 239 return m_inputContext; 240} 241 242QPlatformServices *QIOSIntegration::services() const 243{ 244 return m_platformServices; 245} 246 247QVariant QIOSIntegration::styleHint(StyleHint hint) const 248{ 249 switch (hint) { 250 case StartDragTime: 251 return 300; 252 case PasswordMaskDelay: 253 // this number is based on timing the native delay 254 // since there is no API to get it 255 return 2000; 256 case ShowIsMaximized: 257 return true; 258 case SetFocusOnTouchRelease: 259 return true; 260 default: 261 return QPlatformIntegration::styleHint(hint); 262 } 263} 264 265QStringList QIOSIntegration::themeNames() const 266{ 267 return QStringList(QLatin1String(QIOSTheme::name)); 268} 269 270QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const 271{ 272 if (name == QLatin1String(QIOSTheme::name)) 273 return new QIOSTheme; 274 275 return QPlatformIntegration::createPlatformTheme(name); 276} 277 278QTouchDevice *QIOSIntegration::touchDevice() 279{ 280 return m_touchDevice; 281} 282 283#ifndef QT_NO_ACCESSIBILITY 284QPlatformAccessibility *QIOSIntegration::accessibility() const 285{ 286 if (!m_accessibility) 287 m_accessibility = new QIOSPlatformAccessibility; 288 return m_accessibility; 289} 290#endif 291 292QPlatformNativeInterface *QIOSIntegration::nativeInterface() const 293{ 294 return const_cast<QIOSIntegration *>(this); 295} 296 297void QIOSIntegration::beep() const 298{ 299#if !TARGET_IPHONE_SIMULATOR 300 AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); 301#endif 302} 303 304// --------------------------------------------------------- 305 306void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) 307{ 308 if (!window || !window->handle()) 309 return 0; 310 311 QByteArray lowerCaseResource = resource.toLower(); 312 313 QIOSWindow *platformWindow = static_cast<QIOSWindow *>(window->handle()); 314 315 if (lowerCaseResource == "uiview") 316 return reinterpret_cast<void *>(platformWindow->winId()); 317 318 return 0; 319} 320 321// --------------------------------------------------------- 322 323#include "moc_qiosintegration.cpp" 324 325QT_END_NAMESPACE 326