From 0575baac5e21cbe38a6ceabaa6b17862cbfee7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:22:56 +0100 Subject: Don't link QtPlatformSupport to CoreFoundation or Carbon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the Carbon dependency to the Cocoa platform plugin instead, where it's actually used. CoreFoundation was not used by any plugins and could be removed completely. Change-Id: I1c825cdf94e2cc348ea13519b894fd868be0d14a Reviewed-by: Morten Johan Sørvig --- src/platformsupport/platformsupport.pro | 2 +- src/plugins/platforms/cocoa/cocoa.pro | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 57d9b422f4..469c76ffae 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -2,7 +2,7 @@ TARGET = QtPlatformSupport QT = core-private gui-private CONFIG += static internal_module -mac:LIBS += -lz -framework CoreFoundation -framework Carbon +mac:LIBS += -lz load(qt_module) diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 83e2a88e6a..6ed26f9e6c 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -78,7 +78,7 @@ HEADERS += qcocoaintegration.h \ RESOURCES += qcocoaresources.qrc -LIBS += -framework Cocoa -framework IOKit +LIBS += -framework Cocoa -framework Carbon -framework IOKit QT += core-private gui-private platformsupport-private -- cgit v1.2.3 From a36eaae89338ce5a17a8c831a3fad2b746322f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 Nov 2012 15:48:36 +0100 Subject: Xcode: Merge various sources and extra-compilers into more managable groups Instead of letting each qmake variable have its own auto-generated name we try to group common variables into similar groups as used by the Xcode templates provided by Apple. We also prevent the same files from ending up multiple times in a group. Change-Id: I73b13d6071bb7b3cd1501c422a99c60743221485 Reviewed-by: Andy Shaw --- qmake/generators/mac/pbuilder_pbx.cpp | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 9893a7a7a4..0bf4b601b2 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -451,18 +451,17 @@ public: ProjectBuilderSources::ProjectBuilderSources(const QString &k, bool b, const QString &g, const QString &c, bool o) : buildable(b), object_output(o), key(k), group(g), compiler(c) { - if(group.isNull()) { - if(k == "SOURCES") - group = "Sources"; - else if(k == "HEADERS") - group = "Headers"; - else if(k == "QMAKE_INTERNAL_INCLUDED_FILES") - group = "Sources [qmake]"; - else if(k == "GENERATED_SOURCES" || k == "GENERATED_FILES") - group = "Temporary Sources"; - else - fprintf(stderr, "No group available for %s!\n", k.toLatin1().constData()); - } + // Override group name for a few common keys + if (k == "SOURCES" || k == "OBJECTIVE_SOURCES" || k == "HEADERS") + group = "Sources"; + else if (k == "QMAKE_INTERNAL_INCLUDED_FILES") + group = "Supporting Files"; + else if (k == "GENERATED_SOURCES" || k == "GENERATED_FILES") + group = "Generated Sources"; + else if (k == "RESOURCES") + group = "Resources"; + else if (group.isNull()) + group = QString("Sources [") + c + "]"; } QStringList @@ -545,10 +544,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { if (project->isEmpty(ProKey(*it + ".output"))) continue; - ProString name = *it; - const ProKey nkey(*it + ".name"); - if (!project->isEmpty(nkey)) - name = project->first(nkey); const ProStringList &inputs = project->values(ProKey(*it + ".input")); for(int input = 0; input < inputs.size(); ++input) { if (project->isEmpty(inputs.at(input).toKey())) @@ -572,7 +567,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } sources.append(ProjectBuilderSources(inputs.at(input).toQString(), true, - QString("Sources [") + name + "]", (*it).toQString(), isObj)); + QString(), (*it).toQString(), isObj)); } } } @@ -618,12 +613,17 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } last_grp = new_grp; } + if (groups[last_grp].contains(src_key)) + continue; groups[last_grp] += src_key; in_root = false; } } - if(in_root) + if (in_root) { + if (src_list.contains(src_key)) + continue; src_list.append(src_key); + } //source reference t << "\t\t" << src_key << " = {" << "\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" -- cgit v1.2.3 From e70e81d554f0e3ff459a8cae4646ea4b003d9412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 Nov 2012 13:50:40 +0100 Subject: Xcode: Change groups/build phase wording to match Apple's templates Change-Id: I286965a05750bc77b94ca4d3b76364b0130e32ed Reviewed-by: Andy Shaw --- qmake/generators/mac/pbuilder_pbx.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 0bf4b601b2..2c7715ecf2 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -786,7 +786,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //SOURCE BUILDPHASE if(!project->isEmpty("QMAKE_PBX_OBJ")) { - QString grp = "Build Sources", key = keyFor(grp); + QString grp = "Compile Sources", key = keyFor(grp); project->values("QMAKE_PBX_BUILDPHASES").append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" @@ -967,7 +967,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) { tmp = project->values("QMAKE_PBX_LIBRARIES"); if(!tmp.isEmpty()) { - QString grp("External Frameworks and Libraries"), key = keyFor(grp); + QString grp("Frameworks"), key = keyFor(grp); project->values("QMAKE_PBX_GROUPS").append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";" << "\n" @@ -980,7 +980,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } { - QString grp("Frameworks & Libraries"), key = keyFor(grp); + QString grp("Link Binary With Libraries"), key = keyFor(grp); project->values("QMAKE_PBX_BUILDPHASES").append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" -- cgit v1.2.3 From 66f6e5b1621fba4d7a8d6d63c5d5e33ad938c04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Nov 2012 15:26:17 +0100 Subject: qmake: Update Xcode generator to produce project files similar to Xcode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There was quite a bit of cruft left over from older Xcode version. We now produce Xcode 3.2 compatible files, similar to what Xcode would do when asked to upgrade one of our generated files. In particular: - Removed refType - Set more lastKnownFileTypes - Renamed defaultConfigurationIsName to defaultConfigurationName - Add runOnlyForDeploymentPostprocessing = 0 to build phases - Don't put buildSettings directly into PBXNativeTarget - Don't write productSettingsXML - Don't write startupPath - Don't write name when path is the exact same - Write empty buildSetting lists as empty string - Don't write empty PBXBuildFile settings - Don't write generated/neede filenames for PBXShellScriptBuildPhase - Use PBXFileReference instad of PBXFrameworkReference - Prune deprecated buildSetting variables - Remove deprecated PBXBuildStyle sections - Resolve correct CC/CPLUSPLUS/LDPLUSPLUS - Write IPHONEOS_DEPLOYMENT_TARGET Change-Id: Ia2365c2623fe898878bd10636c3b85145c1cff04 Reviewed-by: Andy Shaw Reviewed-by: Morten Johan Sørvig --- mkspecs/common/clang-mac.conf | 2 + mkspecs/macx-llvm/qmake.conf | 2 + qmake/generators/mac/pbuilder_pbx.cpp | 435 ++++++++++++++-------------------- 3 files changed, 184 insertions(+), 255 deletions(-) diff --git a/mkspecs/common/clang-mac.conf b/mkspecs/common/clang-mac.conf index f7fe50a50b..efe771d24d 100644 --- a/mkspecs/common/clang-mac.conf +++ b/mkspecs/common/clang-mac.conf @@ -3,3 +3,5 @@ QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} - QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvm.clang.1_0 diff --git a/mkspecs/macx-llvm/qmake.conf b/mkspecs/macx-llvm/qmake.conf index 43db8d850c..96e02dc913 100644 --- a/mkspecs/macx-llvm/qmake.conf +++ b/mkspecs/macx-llvm/qmake.conf @@ -16,6 +16,8 @@ include(../common/llvm.conf) QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42 + QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 2c7715ecf2..c68b3d4f83 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #ifdef Q_OS_UNIX @@ -222,7 +223,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) << "\t\t\t" << writeSettings("lastKnownFileType", "wrapper.pb-project") << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(tmp_proj.first("TARGET") + projectSuffix())) << ";" << "\n" << "\t\t\t" << writeSettings("path", pbxproj) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; //WRAPPER @@ -235,8 +235,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t\t" << writeSettings("fileType", "compiled.mach-o.dylib") << ";" << "\n" << "\t\t\t" << writeSettings("path", tmp_proj.first("TARGET") + ".dylib") << ";" << "\n"; } - t << "\t\t\t" << writeSettings("refType", "3", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("remoteRef", keyFor(pbxproj + "_WRAPPERREF")) << ";" << "\n" + t << "\t\t\t" << writeSettings("remoteRef", keyFor(pbxproj + "_WRAPPERREF")) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" << "\t\t" << "};" << "\n"; t << "\t\t" << keyFor(pbxproj + "_WRAPPERREF") << " = {" << "\n" @@ -252,7 +251,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) << "\t\t\t" << writeSettings("children", project->values(ProKey(pbxproj + "_WRAPPER")), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Products") << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -291,14 +289,13 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER - //BUILDSTYLE - QString active_buildstyle; + //BUILDCONFIGURATIONS + QString defaultConfig; for(int as_release = 0; as_release < 2; as_release++) { QMap settings; @@ -320,6 +317,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) } QString name = (as_release ? "Release" : "Debug"); + if (project->isActiveConfig("debug") != (bool)as_release) + defaultConfig = name; QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + name); project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS").append(key); t << "\t\t" << key << " = {" << "\n" @@ -330,26 +329,12 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t\t" << "};" << "\n" << "\t\t\t" << writeSettings("name", name) << ";" << "\n" << "\t\t" << "};" << "\n"; - - key = keyFor("QMAKE_SUBDIR_PBX_BUILDSTYLE_" + name); - project->values("QMAKE_SUBDIR_PBX_BUILDSTYLES").append(key); - if (project->isActiveConfig("debug") != (bool)as_release) - active_buildstyle = name; - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << writeSettings("buildRules", ProStringList(), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << "buildSettings = {" << "\n"; - for(QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) - t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n"; - t << "\t\t\t" << "};" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXBuildStyle", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", name) << ";" << "\n" - << "\t\t" << "};" << "\n"; } t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {" << "\n" << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n" + << "\t\t\t" << writeSettings("defaultConfigurationName", defaultConfig, SettingsNoQuote) << ";" << "\n" << "\t\t" << "};" << "\n"; #ifdef GENERATE_AGGREGRATE_SUBDIR @@ -376,7 +361,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t) t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_ROOT_GROUP") << " = {" << "\n" << "\t\t\t" << writeSettings("children", project->values("QMAKE_SUBDIR_PBX_GROUPS"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; @@ -482,6 +466,36 @@ ProjectBuilderSources::files(QMakeProject *project) const return ret; } +static QString xcodeFiletypeForFilename(const QString &filename) +{ + foreach (const QString &ext, Option::cpp_ext) { + if (filename.endsWith(ext)) + return QStringLiteral("sourcecode.cpp.cpp"); + } + + foreach (const QString &ext, Option::c_ext) { + if (filename.endsWith(ext)) + return QStringLiteral("sourcecode.c.c"); + } + + foreach (const QString &ext, Option::h_ext) { + if (filename.endsWith(ext)) + return "sourcecode.c.h"; + } + + if (filename.endsWith(QStringLiteral(".mm"))) + return QStringLiteral("sourcecode.cpp.objcpp"); + if (filename.endsWith(QStringLiteral(".m"))) + return QStringLiteral("sourcecode.c.objc"); + if (filename.endsWith(QStringLiteral(".framework"))) + return QStringLiteral("wrapper.framework"); + if (filename.endsWith(QStringLiteral(".a"))) + return QStringLiteral("archive.ar"); + if (filename.endsWith(QStringLiteral(".pro")) || filename.endsWith(QStringLiteral(".qrc"))) + return QStringLiteral("text"); + + return QString(); +} bool ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) @@ -522,10 +536,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << phase_key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("generatedFileNames", ProStringList(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Qt Qmake") << ";" << "\n" - << "\t\t\t" << writeSettings("neededFileNames", ProStringList(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";" << "\n" << "\t\t" << "};" << "\n"; @@ -627,21 +640,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //source reference t << "\t\t" << src_key << " = {" << "\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" - << "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(file)), SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(file)) << ";" << "\n"; - QString filetype; - for (QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { - if (file.endsWith((*cppit))) { - filetype = "sourcecode.cpp.cpp"; - break; - } - } + << "\t\t\t" << writeSettings("path", escapeFilePath(file)) << ";" << "\n"; + if (name != file) + t << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n"; + t << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(file)) << ";" << "\n"; + QString filetype = xcodeFiletypeForFilename(file); if (!filetype.isNull()) t << "\t\t\t" << writeSettings("lastKnownFileType", filetype) << ";" << "\n"; t << "\t\t" << "};" << "\n"; - if(sources.at(source).isBuildable()) { //build reference + if (sources.at(source).isBuildable() && sources.at(source).isObjectOutput(file)) { //build reference QString build_key = keyFor(file + ".BUILDABLE"); t << "\t\t" << build_key << " = {" << "\n" << "\t\t\t" << writeSettings("fileRef", src_key) << ";" << "\n" @@ -650,8 +657,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t\t" << writeSettings("ATTRIBUTES", ProStringList(), SettingsAsList, 5) << ";" << "\n" << "\t\t\t" << "};" << "\n" << "\t\t" << "};" << "\n"; - if(sources.at(source).isObjectOutput(file)) - project->values("QMAKE_PBX_OBJ").append(build_key); + project->values("QMAKE_PBX_OBJ").append(build_key); } } if(!src_list.isEmpty()) { @@ -671,7 +677,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("children", grp_it.value(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(grp_it.key().section(Option::dir_sep, -1))) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -775,10 +780,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << phase_key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("generatedFileNames", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Qt Preprocessors") << ";" << "\n" - << "\t\t\t" << writeSettings("neededFileNames", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";" << "\n" << "\t\t" << "};" << "\n"; @@ -792,6 +796,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("files", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXSourcesBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", grp) << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -899,22 +904,21 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) libdirs += path; } library = fileFixify(library); + QString filetype = xcodeFiletypeForFilename(library); QString key = keyFor(library); - bool is_frmwrk = (library.endsWith(".framework")); t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << writeSettings("isa", (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference"), SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" << "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(library)), SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(library)) << ";" << "\n" - << "\t\t" << "};" << "\n"; + << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(library)) << ";" << "\n"; + if (!filetype.isNull()) + t << "\t\t\t" << writeSettings("lastKnownFileType", filetype) << ";" << "\n"; + t << "\t\t" << "};" << "\n"; project->values("QMAKE_PBX_LIBRARIES").append(key); QString build_key = keyFor(library + ".BUILDABLE"); t << "\t\t" << build_key << " = {" << "\n" << "\t\t\t" << writeSettings("fileRef", key) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << "settings = {" << "\n" - << "\t\t\t" << "};" << "\n" << "\t\t" << "};" << "\n"; project->values("QMAKE_PBX_BUILD_LIBRARIES").append(build_key); } @@ -955,10 +959,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << phase_key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("generatedFileNames", ProStringList(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Qt Sublibs") << ";" << "\n" - << "\t\t\t" << writeSettings("neededFileNames", ProStringList(), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n" << "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";" << "\n" << "\t\t" << "};" << "\n"; @@ -973,8 +976,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_LIBRARIES"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" - << "\t\t\t" << writeSettings("path", ProStringList()) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -986,6 +987,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("files", project->values("QMAKE_PBX_BUILD_LIBRARIES"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXFrameworksBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -1003,6 +1005,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } t << "\t\t\t" << ");" << "\n" << "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" << "\t\t" << "};" << "\n"; } @@ -1040,7 +1043,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << file_ref_key << " = {" << "\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("path", escapeFilePath(fn)) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", QString::number(reftypeForFile(fn)), SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(fn)) << ";" << "\n" << "\t\t" << "};" << "\n"; QString copy_file_key = keyFor("QMAKE_PBX_BUNDLE_COPY_FILE." + bundle_data[i] + "-" + fn); @@ -1048,8 +1050,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << copy_file_key << " = {\n" << "\t\t\t" << writeSettings("fileRef", file_ref_key) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << "settings = {\n" - << "\t\t\t" << "}" << ";" << "\n" << "\t\t" << "}" << ";" << "\n"; } //the phase @@ -1076,26 +1076,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("children", bundle_file_refs, SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Source [bundle data]") << ";" << "\n" - << "\t\t\t" << writeSettings("path", ProStringList()) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } - //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER - //ROOT_GROUP - t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" - << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n" - << "\t\t\t" << writeSettings("path", ProStringList()) << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" - << "\t\t" << "};" << "\n"; //REFERENCE project->values("QMAKE_PBX_PRODUCTS").append(keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")); t << "\t\t" << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << " = {" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n"; + << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("includeInIndex", "0", SettingsNoQuote) << ";" << "\n"; if(project->first("TEMPLATE") == "app") { ProString targ = project->first("QMAKE_ORIG_TARGET"); if(project->isActiveConfig("bundle") && !project->isEmpty("QMAKE_BUNDLE_EXTENSION")) { @@ -1110,7 +1099,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) targ += ".app"; t << "\t\t\t" << writeSettings("explicitFileType", "wrapper.application") << ";" << "\n"; } else { - t << "\t\t\t" << writeSettings("explicitFileType", "wrapper.executable") << ";" << "\n"; + t << "\t\t\t" << writeSettings("explicitFileType", "compiled.mach-o.executable") << ";" << "\n"; } QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") : qmake_getpwd()) + Option::dir_sep + targ; @@ -1144,8 +1133,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } t << "\t\t\t" << writeSettings("path", escapeFilePath(lib)) << ";" << "\n"; } - t << "\t\t\t" << writeSettings("refType", "3", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" + t << "\t\t\t" << writeSettings("sourceTree", "BUILT_PRODUCTS_DIR", SettingsNoQuote) << ";" << "\n" << "\t\t" << "};" << "\n"; { //Products group QString grp("Products"), key = keyFor(grp); @@ -1154,177 +1142,38 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_PRODUCTS"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("name", "Products") << ";" << "\n" - << "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER + //ROOT_GROUP + t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" + << "\t\t\t" << writeSettings("children", project->values("QMAKE_PBX_GROUPS"), SettingsAsList, 4) << ";" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n" + << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" + << "\t\t" << "};" << "\n"; + //TARGET QString target_key = keyFor(pbx_dir + "QMAKE_PBX_TARGET"); project->values("QMAKE_PBX_TARGETS").append(target_key); t << "\t\t" << target_key << " = {" << "\n" << "\t\t\t" << writeSettings("buildPhases", project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES") + project->values("QMAKE_PBX_BUILDPHASES"), - SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << "buildSettings = {" << "\n"; - ProString cCompiler = project->first("QMAKE_CC"); - if (!cCompiler.isEmpty()) { - t << "\t\t\t\t" << writeSettings("CC", fixForOutput(findProgram(cCompiler))) << ";" << "\n"; - } - cCompiler = project->first("QMAKE_CXX"); - if (!cCompiler.isEmpty()) { - t << "\t\t\t\t" << writeSettings("CPLUSPLUS", fixForOutput(findProgram(cCompiler))) << ";" << "\n"; - } - - t << "\t\t\t\t" << writeSettings("LEXFLAGS", fixListForOutput("QMAKE_LEXFLAGS")) << ";" << "\n" - << "\t\t\t\t" << writeSettings("YACCFLAGS", fixListForOutput("QMAKE_YACCFLAGS")) << ";" << "\n" - << "\t\t\t\t" << writeSettings("OTHER_REZFLAGS", ProStringList()) << ";" << "\n" - << "\t\t\t\t" << writeSettings("SECTORDER_FLAGS", ProStringList()) << ";" << "\n" - << "\t\t\t\t" << writeSettings("WARNING_CFLAGS", ProStringList()) << ";" << "\n" - << "\t\t\t\t" << writeSettings("PREBINDING", ProStringList((project->isEmpty("QMAKE_DO_PREBINDING") ? "NO" : "YES")), SettingsNoQuote) << ";" << "\n"; - if((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) || - (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && - project->isActiveConfig("lib_bundle"))) { - QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString()); - if(plist.isEmpty()) - plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); - if(exists(plist)) { - QFile plist_in_file(plist); - if(plist_in_file.open(QIODevice::ReadOnly)) { - QTextStream plist_in(&plist_in_file); - QString plist_in_text = plist_in.readAll(); - plist_in_text = plist_in_text.replace("@ICON@", - (project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1))); - if(project->first("TEMPLATE") == "app") { - plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString()); - } else { - plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); - } - if (!project->values("VERSION").isEmpty()) { - plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + - project->first("VER_MIN")); - } - plist_in_text = plist_in_text.replace("@TYPEINFO@", - (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : - project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString())); - QFile plist_out_file("Info.plist"); - if(plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QTextStream plist_out(&plist_out_file); - plist_out << plist_in_text; - t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n"; - } - } - } - } -#if 1 - t << "\t\t\t\t" << writeSettings("BUILD_ROOT", escapeFilePath(qmake_getpwd())) << ";" << "\n"; -#endif - if(!project->isActiveConfig("staticlib")) { - t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS", - fixListForOutput("SUBLIBS") - + fixListForOutput("QMAKE_LFLAGS") - + fixListForOutput("QMAKE_LIBS") - + fixListForOutput("QMAKE_LIBS_PRIVATE"), - SettingsAsList, 6) << ";" << "\n"; - } - if(!project->isEmpty("DESTDIR")) { - ProString dir = project->first("DESTDIR"); - if (QDir::isRelativePath(dir.toQString())) - dir.prepend(qmake_getpwd() + Option::dir_sep); - t << "\t\t\t\t" << writeSettings("INSTALL_DIR", dir) << ";" << "\n"; - } - if (project->first("TEMPLATE") == "lib") { - t << "\t\t\t\t" << writeSettings("INSTALL_PATH", ProStringList()) << ";" << "\n"; - } - if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { - t << "\t\t\t\t" << writeSettings("DYLIB_CURRENT_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")+"."+project->first("VER_PAT")) << ";" << "\n"; - if(project->isEmpty("COMPAT_VERSION")) - t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")) << ";" << "\n"; - if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && - project->isActiveConfig("lib_bundle")) - t << "\t\t\t\t" << writeSettings("FRAMEWORK_VERSION", project->first("QMAKE_FRAMEWORK_VERSION")) << ";" << "\n"; - } - if(!project->isEmpty("COMPAT_VERSION")) - t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("COMPAT_VERSION")) << ";" << "\n"; - if(!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET")) - t << "\t\t\t\t" << writeSettings("MACOSX_DEPLOYMENT_TARGET", project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET")) << ";" << "\n"; - if(project->first("TEMPLATE") == "app") { - t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET").toQString())) << ";" << "\n"; - } else { - if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { - t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "STATIC") << ";" << "\n"; - } else { - t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "DYNAMIC") << ";" << "\n"; - } - ProString lib = project->first("QMAKE_ORIG_TARGET"); - if(!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib")) - lib.prepend("lib"); - t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";" << "\n"; - } - tmp = project->values("QMAKE_PBX_VARS"); - for(int i = 0; i < tmp.count(); i++) { - QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())); - if(val.isEmpty() && var == "TB") - val = "/usr/bin/"; - t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";" << "\n"; - } - t << "\t\t\t" << "};" << "\n" - << "\t\t\t" << "conditionalBuildSettings = {" << "\n" - << "\t\t\t" << "};" << "\n" - << "\t\t\t" << writeSettings("dependencies", project->values("QMAKE_PBX_TARGET_DEPENDS"), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("productReference", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n" - << "\t\t\t" << writeSettings("shouldUseHeadermap", "1", SettingsNoQuote) << ";" << "\n"; + SettingsAsList, 4) << ";" << "\n"; + t << "\t\t\t" << writeSettings("dependencies", project->values("QMAKE_PBX_TARGET_DEPENDS"), SettingsAsList, 4) << ";" << "\n" + << "\t\t\t" << writeSettings("productReference", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n"; t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_TARGET"), SettingsNoQuote) << ";" << "\n"; t << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";" << "\n"; + t << "\t\t\t" << writeSettings("buildRules", ProStringList(), SettingsAsList) << ";" << "\n"; if(project->first("TEMPLATE") == "app") { - if(!project->isActiveConfig("app_bundle")) { - if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) - t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; - else - t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";" << "\n"; + if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) { + t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; } else { - if (!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE")) - t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n"; - else + if (project->isActiveConfig("app_bundle")) t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.application") << ";" << "\n"; - t << "\t\t\t" << "productSettingsXML = \""; - bool read_plist = false; - if(exists("Info.plist")) { - QFile plist("Info.plist"); - if (plist.open(QIODevice::ReadOnly)) { - read_plist = true; - QTextStream stream(&plist); - while(!stream.atEnd()) - t << stream.readLine().replace('"', "\\\"") << endl; - } - } - if(!read_plist) { - t << "" << "\n" - << "\t\t\t\t" << "" << "\n" - << "\t\t\t\t" << "" << "\n" - << "\t\t\t\t" << "" << "\n" - << "\t\t\t\t\t" << "CFBundleDevelopmentRegion" << "\n" - << "\t\t\t\t\t" << "English" << "\n" - << "\t\t\t\t\t" << "CFBundleExecutable" << "\n" - << "\t\t\t\t\t" << "" << project->first("QMAKE_ORIG_TARGET") << "" << "\n" - << "\t\t\t\t\t" << "CFBundleIconFile" << "\n" - << "\t\t\t\t\t" << "" << var("ICON").section(Option::dir_sep, -1) << "" << "\n" - << "\t\t\t\t\t" << "CFBundleInfoDictionaryVersion" << "\n" - << "\t\t\t\t\t" << "6.0" << "\n" - << "\t\t\t\t\t" << "CFBundlePackageType" << "\n" - << "\t\t\t\t\t" << "APPL" << "\n" - << "\t\t\t\t\t" << "CFBundleSignature" << "\n" - << "\t\t\t\t\t" << "" - << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : - project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << "" << "\n" - << "\t\t\t\t\t" << "CFBundleVersion" << "\n" - << "\t\t\t\t\t" << "0.1" << "\n" - << "\t\t\t\t\t" << "CSResourcesFileMapped" << "\n" - << "\t\t\t\t\t" << "" << "\n" - << "\t\t\t\t" << "" << "\n" - << "\t\t\t\t" << ""; - } - t << "\";" << "\n"; + else + t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";" << "\n"; } t << "\t\t\t" << writeSettings("name", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n" << "\t\t\t" << writeSettings("productName", escapeFilePath(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n"; @@ -1343,12 +1192,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) else t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.library.dynamic") << ";" << "\n"; } - t << "\t\t\t" << writeSettings("startupPath", "<>") << ";" << "\n"; if(!project->isEmpty("DESTDIR")) t << "\t\t\t" << writeSettings("productInstallPath", escapeFilePath(project->first("DESTDIR"))) << ";" << "\n"; t << "\t\t" << "};" << "\n"; //DEBUG/RELEASE - QString active_buildstyle; + QString defaultConfig; for(int as_release = 0; as_release < 2; as_release++) { QMap settings; @@ -1379,6 +1227,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } QString name = (as_release ? "Release" : "Debug"); + if (project->isActiveConfig("debug") != (bool)as_release) + defaultConfig = name; for (int i = 0; i < buildConfigGroups.size(); i++) { QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i)); project->values(ProKey("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i))).append(key); @@ -1387,15 +1237,100 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << "buildSettings = {" << "\n"; for (QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n"; - if (!project->isEmpty("PRECOMPILED_HEADER")) { - t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";" << "\n" - << "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";" << "\n"; - } if (buildConfigGroups.at(i) == QLatin1String("PROJECT")) { + if (!project->isEmpty("QMAKE_XCODE_GCC_VERSION")) + t << "\t\t\t\t" << writeSettings("GCC_VERSION", project->first("QMAKE_XCODE_GCC_VERSION"), SettingsNoQuote) << ";" << "\n"; + ProString program = project->first("QMAKE_CC"); + if (!program.isEmpty()) + t << "\t\t\t\t" << writeSettings("CC", fixForOutput(findProgram(program))) << ";" << "\n"; + program = project->first("QMAKE_CXX"); + // Xcode will automatically take care of using CC with the right -x option, + // and will actually break if we pass CPLUSPLUS, by adding an additional set of "++" + if (!program.isEmpty() && !program.contains("clang++")) + t << "\t\t\t\t" << writeSettings("CPLUSPLUS", fixForOutput(findProgram(program))) << ";" << "\n"; + program = project->first("QMAKE_LINK"); + if (!program.isEmpty()) + t << "\t\t\t\t" << writeSettings("LDPLUSPLUS", fixForOutput(findProgram(program))) << ";" << "\n"; + + if ((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) || + (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && + project->isActiveConfig("lib_bundle"))) { + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString()); + if (plist.isEmpty()) + plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); + if (exists(plist)) { + QFile plist_in_file(plist); + if (plist_in_file.open(QIODevice::ReadOnly)) { + QTextStream plist_in(&plist_in_file); + QString plist_in_text = plist_in.readAll(); + plist_in_text = plist_in_text.replace("@ICON@", + (project->isEmpty("ICON") ? QString("") : project->first("ICON").toQString().section(Option::dir_sep, -1))); + if (project->first("TEMPLATE") == "app") { + plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET").toQString()); + } else { + plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); + } + if (!project->values("VERSION").isEmpty()) { + plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + + project->first("VER_MIN")); + } + plist_in_text = plist_in_text.replace("@TYPEINFO@", + (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") + ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4).toQString())); + QFile plist_out_file("Info.plist"); + if (plist_out_file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream plist_out(&plist_out_file); + plist_out << plist_in_text; + t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n"; + } + } + } + } + + t << "\t\t\t\t" << writeSettings("SYMROOT", escapeFilePath(qmake_getpwd())) << ";" << "\n"; + + if (!project->isEmpty("DESTDIR")) { + ProString dir = project->first("DESTDIR"); + if (QDir::isRelativePath(dir.toQString())) + dir.prepend(qmake_getpwd() + Option::dir_sep); + t << "\t\t\t\t" << writeSettings("TARGET_BUILD_DIR", dir) << ";" << "\n"; + } + + if (project->first("TEMPLATE") == "lib") + t << "\t\t\t\t" << writeSettings("INSTALL_PATH", ProStringList()) << ";" << "\n"; + + if (!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { + t << "\t\t\t\t" << writeSettings("DYLIB_CURRENT_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")+"."+project->first("VER_PAT")) << ";" << "\n"; + if (project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("VER_MAJ")+"."+project->first("VER_MIN")) << ";" << "\n"; + if (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && + project->isActiveConfig("lib_bundle")) + t << "\t\t\t\t" << writeSettings("FRAMEWORK_VERSION", project->first("QMAKE_FRAMEWORK_VERSION")) << ";" << "\n"; + } + if (!project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("COMPAT_VERSION")) << ";" << "\n"; + + if (!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET")) + t << "\t\t\t\t" << writeSettings("MACOSX_DEPLOYMENT_TARGET", project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET")) << ";" << "\n"; + if (!project->isEmpty("QMAKE_IOS_DEPLOYMENT_TARGET")) + t << "\t\t\t\t" << writeSettings("IPHONEOS_DEPLOYMENT_TARGET", project->first("QMAKE_IOS_DEPLOYMENT_TARGET")) << ";" << "\n"; + + tmp = project->values("QMAKE_PBX_VARS"); + for (int i = 0; i < tmp.count(); i++) { + QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())); + if (val.isEmpty() && var == "TB") + val = "/usr/bin/"; + t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";" << "\n"; + } + if (!project->isEmpty("PRECOMPILED_HEADER")) { + t << "\t\t\t\t" << writeSettings("GCC_PRECOMPILE_PREFIX_HEADER", "YES") << ";" << "\n" + << "\t\t\t\t" << writeSettings("GCC_PREFIX_HEADER", escapeFilePath(project->first("PRECOMPILED_HEADER"))) << ";" << "\n"; + } t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + ProStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n" << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n" - << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n" - << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n"; + << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), + !project->values("QMAKE_FRAMEWORKPATH").isEmpty() ? SettingsAsList : 0, 5) << ";" << "\n"; + { ProStringList cflags = fixListForOutput("QMAKE_CFLAGS"); const ProStringList &prl_defines = project->values("PRL_EXPORT_DEFINES"); @@ -1446,20 +1381,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t" << "};" << "\n" << "\t\t\t" << writeSettings("name", name) << ";" << "\n" << "\t\t" << "};" << "\n"; - - key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name); - project->values("QMAKE_PBX_BUILDSTYLES").append(key); - if (project->isActiveConfig("debug") != (bool)as_release) - active_buildstyle = name; - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << writeSettings("buildRules", ProStringList(), SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << "buildSettings = {" << "\n"; - for(QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) - t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n"; - t << "\t\t\t" << "};" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n" - << "\t\t\t" << writeSettings("name", name) << ";" << "\n" - << "\t\t" << "};" << "\n"; } } for (int i = 0; i < buildConfigGroups.size(); i++) { @@ -1467,20 +1388,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("buildConfigurations", project->values(ProKey("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i))), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n" + << "\t\t\t" << writeSettings("defaultConfigurationName", defaultConfig) << ";" << "\n" << "\t\t" << "};" << "\n"; } //ROOT t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n" - << "\t\t\t" << writeSettings("buildStyles", project->values("QMAKE_PBX_BUILDSTYLES"), SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("hasScannedForEncodings", "1", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("compatibilityVersion", "Xcode 3.2") << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXProject", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_PBX_ROOT_GROUP")) << ";" << "\n"; + << "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_PBX_ROOT_GROUP")) << ";" << "\n" + << "\t\t\t" << writeSettings("productRefGroup", keyFor("Products")) << ";" << "\n"; t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_PROJECT")) << ";" << "\n"; t << "\t\t\t" << writeSettings("projectDirPath", ProStringList()) << ";" << "\n" + << "\t\t\t" << writeSettings("projectRoot", "") << ";" << "\n" << "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";" << "\n" << "\t\t" << "};" << "\n"; + // FIXME: Deal with developmentRegion and knownRegions for QMAKE_PBX_ROOT + //FOOTER t << "\t" << "};" << "\n" << "\t" << writeSettings("rootObject", keyFor("QMAKE_PBX_ROOT")) << ";" << "\n" -- cgit v1.2.3 From c6eae1acf8939e512d742578ef3c0c710d3c1653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 3 Dec 2012 14:55:19 +0100 Subject: qmake: Don't generate Xcode project bundle identifiers with spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace them with dashes, like Xcode itself does. Change-Id: I302425363a2eef13394025cd4a9e414048ce55ce Reviewed-by: Morten Johan Sørvig --- mkspecs/unsupported/macx-ios-clang/Info.plist.app | 20 ++++++++++++++++++++ mkspecs/unsupported/macx-ios-clang/Info.plist.lib | 18 ++++++++++++++++++ qmake/generators/mac/pbuilder_pbx.cpp | 1 + 3 files changed, 39 insertions(+) create mode 100755 mkspecs/unsupported/macx-ios-clang/Info.plist.app create mode 100644 mkspecs/unsupported/macx-ios-clang/Info.plist.lib diff --git a/mkspecs/unsupported/macx-ios-clang/Info.plist.app b/mkspecs/unsupported/macx-ios-clang/Info.plist.app new file mode 100755 index 0000000000..bcf7f41f27 --- /dev/null +++ b/mkspecs/unsupported/macx-ios-clang/Info.plist.app @@ -0,0 +1,20 @@ + + + + + CFBundleIconFile + @ICON@ + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @EXECUTABLE@ + CFBundleIdentifier + com.yourcompany.@BUNDLEIDENTIFIER@ + NOTE + This file was generated by Qt/QMake. + + diff --git a/mkspecs/unsupported/macx-ios-clang/Info.plist.lib b/mkspecs/unsupported/macx-ios-clang/Info.plist.lib new file mode 100644 index 0000000000..97609ed0ce --- /dev/null +++ b/mkspecs/unsupported/macx-ios-clang/Info.plist.lib @@ -0,0 +1,18 @@ + + + + + CFBundlePackageType + FMWK + CFBundleShortVersionString + @SHORT_VERSION@ + CFBundleGetInfoString + Created by Qt/QMake + CFBundleSignature + @TYPEINFO@ + CFBundleExecutable + @LIBRARY@ + NOTE + Please, do NOT change this file -- It was generated by Qt/QMake. + + diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index c68b3d4f83..c5bf7bb7c9 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1270,6 +1270,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } else { plist_in_text = plist_in_text.replace("@LIBRARY@", project->first("QMAKE_ORIG_TARGET").toQString()); } + plist_in_text = plist_in_text.replace("@BUNDLEIDENTIFIER@", QLatin1String("${PRODUCT_NAME:rfc1034identifier}")); if (!project->values("VERSION").isEmpty()) { plist_in_text = plist_in_text.replace("@SHORT_VERSION@", project->first("VER_MAJ") + "." + project->first("VER_MIN")); -- cgit v1.2.3 From 883efa10cdfd81cc4ccbcca55d42a454877d146e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Feb 2013 13:12:25 +0100 Subject: qmake: Prevent duplicate libaries from being added to the link phase Change-Id: I5ec7acb8f060e9d9bbd8cdb95d40ace03cffe9c7 Reviewed-by: Richard Moe Gustavsen --- qmake/generators/mac/pbuilder_pbx.cpp | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index c5bf7bb7c9..87085318bc 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -906,21 +906,23 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) library = fileFixify(library); QString filetype = xcodeFiletypeForFilename(library); QString key = keyFor(library); - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" - << "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";" << "\n" - << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(library)) << ";" << "\n"; - if (!filetype.isNull()) - t << "\t\t\t" << writeSettings("lastKnownFileType", filetype) << ";" << "\n"; - t << "\t\t" << "};" << "\n"; - project->values("QMAKE_PBX_LIBRARIES").append(key); - QString build_key = keyFor(library + ".BUILDABLE"); - t << "\t\t" << build_key << " = {" << "\n" - << "\t\t\t" << writeSettings("fileRef", key) << ";" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" - << "\t\t" << "};" << "\n"; - project->values("QMAKE_PBX_BUILD_LIBRARIES").append(build_key); + if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) { + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("name", escapeFilePath(name)) << ";" << "\n" + << "\t\t\t" << writeSettings("path", escapeFilePath(library)) << ";" << "\n" + << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(library)) << ";" << "\n"; + if (!filetype.isNull()) + t << "\t\t\t" << writeSettings("lastKnownFileType", filetype) << ";" << "\n"; + t << "\t\t" << "};" << "\n"; + project->values("QMAKE_PBX_LIBRARIES").append(key); + QString build_key = keyFor(library + ".BUILDABLE"); + t << "\t\t" << build_key << " = {" << "\n" + << "\t\t\t" << writeSettings("fileRef", key) << ";" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" + << "\t\t" << "};" << "\n"; + project->values("QMAKE_PBX_BUILD_LIBRARIES").append(build_key); + } } if(remove) tmp.removeAt(x); -- cgit v1.2.3 From 3cc738dfc79cca0cf415184ab1db0cc7a1c069d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Dec 2012 13:33:59 +0100 Subject: qmake: Don't treat .xcodeproj directories as OUT_PWD when passed with -o The Xcode generator creates a makefile for running 'make qmake', and the makefile passes -o to ensure it writes to the same Xcode project. This fails when qmake then treats -o foo.xcodeproj/project.xcproj as not only setting the output filename, but also the output directory to foo.xcodeproj, which results in the Xcode project trying to reference files relative to this directory, such as '../main.cpp'. Unfortunatly the output filename parsing happens too early for us to know whether or not the generator is Xcode, so we just have to assume that a certain combination of output filename and directories means we are generating an Xcode project. Change-Id: I0901d4db995f287c35cbbbd015683d5abda6d0f5 Reviewed-by: Richard Moe Gustavsen --- qmake/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qmake/main.cpp b/qmake/main.cpp index 5f9fb05449..6ef0707da9 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -116,6 +116,11 @@ int runQMake(int argc, char **argv) if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir)) dir = tmp_dir; } +#ifdef Q_OS_MAC + if (fi.fileName().endsWith(QStringLiteral(".pbxproj")) + && dir.endsWith(QStringLiteral(".xcodeproj"))) + dir += QStringLiteral("/.."); +#endif if(!dir.isNull() && dir != ".") Option::output_dir = dir; if(QDir::isRelativePath(Option::output_dir)) -- cgit v1.2.3 From 0e548b585695f4bcfaaccf289da8124c851d6d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 7 Jan 2013 16:05:21 +0100 Subject: qmake: Use PBXResourcesBuildPhase for QMAKE_BUNDLE_DATA without a path The PBXResourcesBuildPhase will optimize resources, such as turning XIB files into NIB files, running pngcrush on images, turning string files into binary plists, etc, so we prefer that if possible. Unfortunatly this phase does not support custom paths, so whenever we encounter bundle data with a custom path we fall back to the regular PBXCopyFilesBuildPhase. Change-Id: I539db03dd7982fd37293123b6428cdb695f64d2b Reviewed-by: Richard Moe Gustavsen --- qmake/generators/mac/pbuilder_pbx.cpp | 100 +++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 87085318bc..d0b7efaca6 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -993,24 +993,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" << "\t\t" << "};" << "\n"; } - if(project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES - QString grp("Bundle Resources"), key = keyFor(grp); - project->values("QMAKE_PBX_BUILDPHASES").append(key); - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << "files = (" << "\n"; - if(!project->isEmpty("ICON")) { - ProString icon = project->first("ICON"); - if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0))) - icon = icon.mid(1, icon.length()-2); - t << "\t\t\t\t" << keyFor(icon + ".BUILDABLE") << ",\n"; - } - t << "\t\t\t" << ");" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" - << "\t\t" << "};" << "\n"; - } if (!project->isEmpty("DESTDIR")) { QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE"); QString destDir = project->first("DESTDIR").toQString(); @@ -1029,55 +1011,87 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";" << "\n" << "\t\t" << "};\n"; } - //BUNDLE_DATA BUILDPHASE (copy) - if(!project->isEmpty("QMAKE_BUNDLE_DATA")) { + // Copy Bundle Resources + if (!project->isEmpty("QMAKE_BUNDLE_DATA")) { ProStringList bundle_file_refs; + ProStringList bundle_resources_files; + + bool useCopyResourcesPhase = project->isActiveConfig("app_bundle") && project->first("TEMPLATE") == "app"; + //all bundle data const ProStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA"); for(int i = 0; i < bundle_data.count(); i++) { - ProStringList pbx_files; + ProStringList bundle_files; + ProString path = project->first(ProKey(bundle_data[i] + ".path")); //all files const ProStringList &files = project->values(ProKey(bundle_data[i] + ".files")); for(int file = 0; file < files.count(); file++) { QString fn = files[file].toQString(); - QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_COPY_FILE_REF." + bundle_data[i] + "-" + fn); + QString file_ref_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE_REF." + bundle_data[i] + "-" + fn); bundle_file_refs += file_ref_key; t << "\t\t" << file_ref_key << " = {" << "\n" << "\t\t\t" << writeSettings("isa", "PBXFileReference", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("path", escapeFilePath(fn)) << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", sourceTreeForFile(fn)) << ";" << "\n" << "\t\t" << "};" << "\n"; - QString copy_file_key = keyFor("QMAKE_PBX_BUNDLE_COPY_FILE." + bundle_data[i] + "-" + fn); - pbx_files += copy_file_key; - t << "\t\t" << copy_file_key << " = {\n" + QString file_key = keyFor("QMAKE_PBX_BUNDLE_DATA_FILE." + bundle_data[i] + "-" + fn); + bundle_files += file_key; + t << "\t\t" << file_key << " = {\n" << "\t\t\t" << writeSettings("fileRef", file_ref_key) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n" << "\t\t" << "}" << ";" << "\n"; } - //the phase - QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]); - QString path; - if (!project->isEmpty(ProKey(bundle_data[i] + ".version"))) { - //### + + if (!useCopyResourcesPhase || !path.isEmpty()) { + // The resource copy phase doesn't support paths, so we have to use + // a regular file copy phase (which doesn't optimize the resources). + QString phase_key = keyFor("QMAKE_PBX_BUNDLE_COPY." + bundle_data[i]); + if (!project->isEmpty(ProKey(bundle_data[i] + ".version"))) { + //### + } + + project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); + t << "\t\t" << phase_key << " = {\n" + << "\t\t\t" << writeSettings("name", "Copy '" + bundle_data[i] + "' Files to Bundle") << ";" << "\n" + << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";" << "\n" + << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("files", bundle_files, SettingsAsList, 4) << ";" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" + << "\t\t" << "}" << ";" << "\n"; + } else { + // Otherwise we leave it to the resource copy phase below + bundle_resources_files += bundle_files; + } + } + + if (useCopyResourcesPhase) { + if (!project->isEmpty("ICON")) { + ProString icon = project->first("ICON"); + if (icon.length() >= 2 && (icon.at(0) == '"' || icon.at(0) == '\'') && icon.endsWith(icon.at(0))) { + icon = icon.mid(1, icon.length() - 2); + bundle_resources_files += keyFor(icon + ".BUILDABLE"); + } } - path += project->first(ProKey(bundle_data[i] + ".path")); - project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key); - t << "\t\t" << phase_key << " = {\n" - << "\t\t\t" << writeSettings("name", "Bundle Copy [" + bundle_data[i] + "]") << ";" << "\n" + + QString grp("Copy Bundle Resources"), key = keyFor(grp); + project->values("QMAKE_PBX_BUILDPHASES").append(key); + t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("dstPath", escapeFilePath(path)) << ";" << "\n" - << "\t\t\t" << writeSettings("dstSubfolderSpec", "1", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("files", pbx_files, SettingsAsList, 4) << ";" << "\n" - << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n" + << "\t\t\t" << writeSettings("files", bundle_resources_files, SettingsAsList, 4) << ";" << "\n" + << "\t\t\t" << writeSettings("isa", "PBXResourcesBuildPhase", SettingsNoQuote) << ";" << "\n" << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n" - << "\t\t" << "}" << ";" << "\n"; + << "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n" + << "\t\t" << "};" << "\n"; } - QString bundle_copy_key = keyFor("QMAKE_PBX_BUNDLE_COPY"); - project->values("QMAKE_PBX_GROUPS").append(bundle_copy_key); - t << "\t\t" << bundle_copy_key << " = {" << "\n" + + QString bundle_data_key = keyFor("QMAKE_PBX_BUNDLE_DATA"); + project->values("QMAKE_PBX_GROUPS").append(bundle_data_key); + t << "\t\t" << bundle_data_key << " = {" << "\n" << "\t\t\t" << writeSettings("children", bundle_file_refs, SettingsAsList, 4) << ";" << "\n" << "\t\t\t" << writeSettings("isa", "PBXGroup", SettingsNoQuote) << ";" << "\n" - << "\t\t\t" << writeSettings("name", "Source [bundle data]") << ";" << "\n" + << "\t\t\t" << writeSettings("name", "Bundle Resources") << ";" << "\n" << "\t\t\t" << writeSettings("sourceTree", "") << ";" << "\n" << "\t\t" << "};" << "\n"; } -- cgit v1.2.3 From f6d13a45c88d94a7b616450efe1adb0a231a92c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 22 Dec 2012 19:57:10 +0100 Subject: qmake: Prevent Obj-C sources from building both as extra compiler and in Xcode We already assume that if a source is buildable and should end up in OBJECTS we can let Xcode build it, so we skip this input for the extra compiler. Change-Id: I17b2408925b8e6513f0fa0d2459ec539bf7381d3 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Oswald Buddenhagen --- qmake/generators/mac/pbuilder_pbx.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index d0b7efaca6..4710f7e939 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -557,10 +557,13 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { if (project->isEmpty(ProKey(*it + ".output"))) continue; - const ProStringList &inputs = project->values(ProKey(*it + ".input")); - for(int input = 0; input < inputs.size(); ++input) { - if (project->isEmpty(inputs.at(input).toKey())) + ProStringList &inputs = project->values(ProKey(*it + ".input")); + int input = 0; + while (input < inputs.size()) { + if (project->isEmpty(inputs.at(input).toKey())) { + ++input; continue; + } bool duplicate = false; bool isObj = project->values(ProKey(*it + ".CONFIG")).indexOf("no_link") == -1; if (!isObj) { @@ -581,7 +584,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } sources.append(ProjectBuilderSources(inputs.at(input).toQString(), true, QString(), (*it).toQString(), isObj)); + + if (isObj) { + inputs.removeAt(input); + continue; + } } + + ++input; } } } -- cgit v1.2.3 From dd5b437d6a9b509466021c9484cc396bbdf0f1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 11 Dec 2012 16:46:55 +0100 Subject: qmake: Fix file paths in Xcode projects when shadow-building The Xcode generator seems to have been written with the assumption that writeMakeParts() would be called with the output directory as the current directory, but that's not the case when shadow-building. Perhaps this was changed in qmake at some point, and the Xcode generator was not updated to reflect that. Instead of replacing every occurance of fileFixify and other logic to deal with paths, we just chdir into the output_dir for the duration of the function (except when writing the 'make qmake' makefile, as the regular makefile generator works as expected with the current directory set to the input directory). Change-Id: I6ba492036d73f29f4adbd7cd554db9504050629e Reviewed-by: Richard Moe Gustavsen --- qmake/generators/mac/pbuilder_pbx.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 4710f7e939..41af3d2a53 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -453,7 +453,6 @@ ProjectBuilderSources::files(QMakeProject *project) const { QStringList ret = project->values(ProKey(key)).toQStringList(); if(key == "QMAKE_INTERNAL_INCLUDED_FILES") { - ret.prepend(project->projectFile()); for(int i = 0; i < ret.size(); ++i) { QStringList newret; if(!ret.at(i).endsWith(Option::prf_ext)) @@ -500,6 +499,14 @@ static QString xcodeFiletypeForFilename(const QString &filename) bool ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) { + // The code in this function assumes that the current directory matches + // the output directory, which is not actually the case when we are called + // from the generic generator code. Instead of changing every single + // assumption and fileFixify we cheat by moving into the output directory + // for the duration of this function. + QString input_dir = qmake_getpwd(); + qmake_setpwd(Option::output_dir); + ProStringList tmp; bool did_preprocess = false; @@ -521,6 +528,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QFile mkf(mkfile); if(mkf.open(QIODevice::WriteOnly | QIODevice::Text)) { writingUnixMakefileGenerator = true; + qmake_setpwd(input_dir); // Makefile generation assumes input_dir as pwd debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); QTextStream mkt(&mkf); writeHeader(mkt); @@ -529,6 +537,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt.flush(); mkf.close(); writingUnixMakefileGenerator = false; + qmake_setpwd(Option::output_dir); } QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE"); mkfile = fileFixify(mkfile, qmake_getpwd()); @@ -544,6 +553,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t" << "};" << "\n"; } + // FIXME: Move all file resolving logic out of ProjectBuilderSources::files(), as it + // doesn't have access to any of the information it needs to resolve relative paths. + project->values("QMAKE_INTERNAL_INCLUDED_FILES").prepend(fileFixify(project->projectFile(), qmake_getpwd(), input_dir)); + //DUMP SOURCES QMap groups; QList sources; @@ -1463,6 +1476,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) writingUnixMakefileGenerator = false; } } + + qmake_setpwd(input_dir); + return true; } @@ -1676,10 +1692,9 @@ ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where) QString ProjectBuilderMakefileGenerator::sourceTreeForFile(const QString &where) { - QString ret = ""; - if (QDir::isRelativePath(unescapeFilePath(where))) - ret = "SOURCE_ROOT"; //relative - return ret; + // We always use absolute paths, instead of maintaining the SRCROOT + // build variable and making files relative to that. + return QLatin1String(""); } QString -- cgit v1.2.3 From de5553aad52f8a8343d53bac5e9d29bcd67fbf2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 19 Nov 2012 14:58:10 +0100 Subject: qmake: Resolve QMAKE_INFO_PLIST against current working dir We're not in the output directory yet, so resolving using vanilla fileFixify will end up failing when we check if the file exists, since QFileInfo resolves relative paths against the current directory. Change-Id: I414c6a2e83b49e3fb30e6153a49f7a90a8e528a0 Reviewed-by: Oswald Buddenhagen --- qmake/generators/unix/unixmake2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 41e40e0bb6..8ad603580c 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1218,7 +1218,7 @@ void UnixMakefileGenerator::init2() } if(!project->isEmpty("QMAKE_BUNDLE")) { - QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString()); + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST").toQString(), qmake_getpwd()); if(plist.isEmpty()) plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); if(exists(Option::fixPathToLocalOS(plist))) { -- cgit v1.2.3 From 20cfe045356aa573570936028511a35b121c20ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Oct 2012 16:17:19 +0200 Subject: iOS: Remove hard-coding of Xcode /Developer path in common/ios mkspecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can use xcode-select -print-path to get the /Developer directory. This also removes the need for the "legacy" makespecs, which only differ from their non-legacy counterparts in the location of the Xcode developer directory. Change-Id: Ia9245033a4b82cc3933226bf998f07177b60871f Reviewed-by: Morten Johan Sørvig Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios/qmake.conf | 9 +--- mkspecs/common/ios/versions.conf | 60 ++++++++-------------- .../macx-iosdevice-clang-legacy/qmake.conf | 35 ------------- .../macx-iosdevice-clang-legacy/qplatformdefs.h | 42 --------------- .../unsupported/macx-iosdevice-clang/qmake.conf | 10 ++-- .../macx-iosdevice-g++-legacy/qmake.conf | 35 ------------- .../macx-iosdevice-g++-legacy/qplatformdefs.h | 42 --------------- .../macx-iosdevice-llvm-legacy/qmake.conf | 35 ------------- .../macx-iosdevice-llvm-legacy/qplatformdefs.h | 42 --------------- .../macx-iossimulator-clang-legacy/qmake.conf | 6 --- .../macx-iossimulator-clang-legacy/qplatformdefs.h | 42 --------------- .../macx-iossimulator-g++-legacy/qmake.conf | 33 ------------ .../macx-iossimulator-g++-legacy/qplatformdefs.h | 42 --------------- .../macx-iossimulator-llvm-legacy/qmake.conf | 33 ------------ .../macx-iossimulator-llvm-legacy/qplatformdefs.h | 42 --------------- 15 files changed, 27 insertions(+), 481 deletions(-) delete mode 100644 mkspecs/unsupported/macx-iosdevice-clang-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-clang-legacy/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iosdevice-g++-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-g++-legacy/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iosdevice-llvm-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-llvm-legacy/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-clang-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-clang-legacy/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-g++-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-g++-legacy/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-llvm-legacy/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-llvm-legacy/qplatformdefs.h diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 6d38e16581..dcc674556b 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -3,6 +3,7 @@ # # Depends on: # +# QMAKE_XCODE_DEVELOPER_PATH - set in mkspecs/common/ios/versions.conf # QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf # QMAKE_IOS_SDK_VERSION - set in mkspecs/common/ios/versions.conf # QMAKE_IOSSIMULATOR_SDK_VERSION - set in mkspecs/common/ios/versions.conf @@ -18,14 +19,8 @@ else { QMAKE_IOS_SIMULATOR_SDK_VERSION = } -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - # Xcode 4.3+ is stored in /Applications - QMAKE_IOS_XCODE_PATH = /Applications/Xcode.app/Contents -} else: QMAKE_IOS_XCODE_PATH = - # iOS platform /Developer path -QMAKE_IOS_DEV_PATH = $$QMAKE_IOS_XCODE_PATH/Developer/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer -QMAKE_IOS_XCODE_PATH = +QMAKE_IOS_DEV_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer # iOS platform SDK path QMAKE_IOS_SDK = $$QMAKE_IOS_DEV_PATH/SDKs/$${QMAKE_IOS_DEVICE_TYPE}$${QMAKE_IOS_SDK_VERSION}.sdk diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index b755068769..319144627a 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -25,9 +25,6 @@ # # IMPORTANT: # -# Xcode versions <= 4.2.x must be installed in /Developer. -# Xcode versions >= 4.3.x must be installed in /Applications -# # Xcode versions >= 4.10 & < 5.0 and versions >= 10.0 are not supported due to # the way the version checks are done here. As Apple (so far) has not used # minor version numbers greater than 3 for Xcode, and the Xcode major version @@ -62,59 +59,48 @@ QMAKE_IPHONEOS_DEPLOYMENT_TARGET = 4.0 ########################################################################### +# Get path of Xcode's Developer directory +QMAKE_XCODE_DEVELOPER_PATH = $$system(xcode-select --print-path) + +# Make sure Xcode path is valid +!exists($$QMAKE_XCODE_DEVELOPER_PATH): \ + error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}! Please use xcode-select to choose Xcode installation path") + # No Xcode version specified? isEmpty(QMAKE_IOS_XCODE_VERSION) { # Get version string from installed Xcode - exists(/Applications/Xcode.app/Contents/Developer) { - QMAKE_IOS_XCODE_INFO = $$system(/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -version) - } else: QMAKE_IOS_XCODE_INFO = $$system(/Developer/usr/bin/xcodebuild -version) + QMAKE_IOS_XCODE_INFO = $$system($${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -version) # Extract Xcode version number from output QMAKE_IOS_XCODE_VERSION = $$member(QMAKE_IOS_XCODE_INFO, 1) QMAKE_IOS_XCODE_INFO = } -# Make sure Xcode version is valid -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - # Xcode 4.3+ is stored in /Applications - QMAKE_IOS_PLATFORM_PATH = /Applications/Xcode.app/Contents/Developer/Platforms - - # Make sure Xcode path is valid - !exists($$QMAKE_IOS_PLATFORM_PATH): error("Xcode is not installed in /Applications/Xcode.app! Edit mkspecs/common/ios/versions.conf to specify version installed.") -} else { - # Older Xcode versions are stored in /Developer - QMAKE_IOS_PLATFORM_PATH = /Developer/Platforms - - # Make sure Xcode path is valid - !exists($$QMAKE_IOS_PLATFORM_PATH): error("Xcode is not installed in /Developer! Edit mkspecs/common/ios/versions.conf to specify version installed.") -} +QMAKE_XCODE_PLATFORM_PATH = $${QMAKE_XCODE_DEVELOPER_PATH}/Platforms # iOS 4.3 is the preferred version as it is the earliest version that is armv7/gles2 only QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 +# Get lists of installed SDKs from Xcode +QMAKE_XCODE_SDKS = $$system($${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -showsdks) + # Building for iOS device? !*simulator* { # No iOS SDK version specified? isEmpty(QMAKE_IOS_SDK_VERSION) { - # Get version string from installed Xcode - !lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - QMAKE_IOS_SDK_INFO = $$system(/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -showsdks) - } else: QMAKE_IOS_SDK_INFO = $$system(/Developer/usr/bin/xcodebuild -showsdks) - # Get names of installed device SDKs - QMAKE_IOS_SDK_INFO = $$find(QMAKE_IOS_SDK_INFO, ^iphoneos) - for(v, QMAKE_IOS_SDK_INFO): { + iphoneos_sdks = $$find(QMAKE_XCODE_SDKS, ^iphoneos) + for(v, iphoneos_sdks): { # Extract SDK version number from output v = $$replace(v,iphoneos,) # Use latest SDK version greaterThan(v, $$QMAKE_IOS_SDK_VERSION): QMAKE_IOS_SDK_VERSION = $$v } - QMAKE_IOS_SDK_INFO = } # Make sure iOS SDK version is valid - !exists($$QMAKE_IOS_PLATFORM_PATH/iPhoneOS.platform/Developer/SDKs/iPhoneOS$${QMAKE_IOS_SDK_VERSION}.sdk) { + !exists($$QMAKE_XCODE_PLATFORM_PATH/iPhoneOS.platform/Developer/SDKs/iPhoneOS$${QMAKE_IOS_SDK_VERSION}.sdk) { error("iOS $$QMAKE_IOS_SDK_VERSION SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.") } @@ -134,25 +120,19 @@ QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 } else { # No iOS simulator SDK version specified? isEmpty(QMAKE_IOS_SIMULATOR_SDK_VERSION) { - # Get version string from installed Xcode - !lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - QMAKE_IOS_SDK_INFO = $$system(/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -showsdks) - } else: QMAKE_IOS_SDK_INFO = $$system(/Developer/usr/bin/xcodebuild -showsdks) - # Get names of installed device SDKs - QMAKE_IOS_SDK_INFO = $$find(QMAKE_IOS_SDK_INFO, ^iphonesimulator) - for(v, QMAKE_IOS_SDK_INFO): { + iphone_simulator_sdks = $$find(QMAKE_XCODE_SDKS, ^iphonesimulator) + for(v, iphone_simulator_sdks): { # Extract SDK version number from output v = $$replace(v,iphonesimulator,) # Use latest SDK version greaterThan(v, $$QMAKE_IOS_SIMULATOR_SDK_VERSION): QMAKE_IOS_SIMULATOR_SDK_VERSION = $$v } - QMAKE_IOS_SDK_INFO = } # Make sure iOS simulator SDK version is valid - !exists($$QMAKE_IOS_PLATFORM_PATH/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$${QMAKE_IOS_SIMULATOR_SDK_VERSION}.sdk) { + !exists($$QMAKE_XCODE_PLATFORM_PATH/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$${QMAKE_IOS_SIMULATOR_SDK_VERSION}.sdk) { error("iOS $$QMAKE_IOS_SIMULATOR_SDK_VERSION simulator SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.") } @@ -170,8 +150,8 @@ QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 } } -QMAKE_IPHONEOS_PREFERRED_TARGET = -QMAKE_IOS_PLATFORM_PATH = +unset(QMAKE_IPHONEOS_PREFERRED_TARGET) +unset(QMAKE_XCODE_PLATFORM_PATH) # Set deployment target QMAKE_IOS_VERSION_FLAGS = -miphoneos-version-min=$$QMAKE_IPHONEOS_DEPLOYMENT_TARGET diff --git a/mkspecs/unsupported/macx-iosdevice-clang-legacy/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang-legacy/qmake.conf deleted file mode 100644 index ff8e0b6aa9..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-clang-legacy/qmake.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# qmake configuration for ios-device-clang -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/clang.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/clang.conf) -include(../../common/ios/qmake.conf) - -# Version check -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.2.x or earlier") - -# iOS build tools -QMAKE_CC = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -QMAKE_CXX = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ -QMAKE_FIX_RPATH = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler") - -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) diff --git a/mkspecs/unsupported/macx-iosdevice-clang-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-clang-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-clang-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf index 777b5ab6e2..ed6852e0d6 100644 --- a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf @@ -18,11 +18,11 @@ include(../../common/ios/qmake.conf) lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") # iOS build tools -QMAKE_CC = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -QMAKE_CXX = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -QMAKE_FIX_RPATH = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool -id -QMAKE_AR = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cq -QMAKE_RANLIB = /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib -s +QMAKE_CC = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang +QMAKE_CXX = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ +QMAKE_FIX_RPATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool -id +QMAKE_AR = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cq +QMAKE_RANLIB = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib -s QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX diff --git a/mkspecs/unsupported/macx-iosdevice-g++-legacy/qmake.conf b/mkspecs/unsupported/macx-iosdevice-g++-legacy/qmake.conf deleted file mode 100644 index 5fcfb4a51d..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-g++-legacy/qmake.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# qmake configuration for ios-device-g++ -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/g++-macx.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/g++.conf) -include(../../common/ios/qmake.conf) - -# Version check (g++ was discontinued at version 4.2, but user may have added it themselves) -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.2.x or earlier") - -# iOS build tools -QMAKE_CC = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -QMAKE_CXX = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-4.2 -QMAKE_FIX_RPATH = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the g++ 4.2 compiler") - -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) diff --git a/mkspecs/unsupported/macx-iosdevice-g++-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-g++-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-g++-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qmake.conf b/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qmake.conf deleted file mode 100644 index 4554843610..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qmake.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# qmake configuration for ios-device-llvm -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/llvm.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/llvm.conf) -include(../../common/ios/qmake.conf) - -# Version check -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.2.x or earlier") - -# iOS build tools -QMAKE_CC = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2 -QMAKE_CXX = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-g++-4.2 -QMAKE_FIX_RPATH = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the llvm-g++ 4.2 compiler") - -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) diff --git a/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-llvm-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-clang-legacy/qmake.conf b/mkspecs/unsupported/macx-iossimulator-clang-legacy/qmake.conf deleted file mode 100644 index b042766a39..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-clang-legacy/qmake.conf +++ /dev/null @@ -1,6 +0,0 @@ -# -# qmake configuration for ios-simulator-clang -# - -# All differences between device and simulator are handled in iOS include files -include(../macx-iosdevice-clang-legacy/qmake.conf) diff --git a/mkspecs/unsupported/macx-iossimulator-clang-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-clang-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-clang-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-g++-legacy/qmake.conf b/mkspecs/unsupported/macx-iossimulator-g++-legacy/qmake.conf deleted file mode 100644 index abc695231e..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-g++-legacy/qmake.conf +++ /dev/null @@ -1,33 +0,0 @@ -# -# qmake configuration for ios-simulator-g++ -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/g++-macx.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/arch.conf) -include(../../common/ios/g++.conf) -include(../../common/ios/qmake.conf) - -# Version check (g++ was discontinued at version 4.2) -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.2"): error("This mkspec requires Xcode 4.1.x or earlier") - -# iOS build tools -QMAKE_CC = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -QMAKE_CXX = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/g++-4.2 -QMAKE_FIX_RPATH = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the g++ 4.2 compiler") - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-g++-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-g++-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-g++-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qmake.conf b/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qmake.conf deleted file mode 100644 index 95d530cc18..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qmake.conf +++ /dev/null @@ -1,33 +0,0 @@ -# -# qmake configuration for ios-simulator-llvm -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/llvm.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/arch.conf) -include(../../common/ios/llvm.conf) -include(../../common/ios/qmake.conf) - -# Version check -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.2.x or earlier") - -# iOS build tools -QMAKE_CC = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -QMAKE_CXX = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-g++-4.2 -QMAKE_FIX_RPATH = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the llvm-g++ 4.2 compiler") - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-llvm-legacy/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" -- cgit v1.2.3 From 6382105f3d777398fb8a5aeed20892f68c78ffaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 26 Oct 2012 13:07:39 +0200 Subject: iOS: Get rid of GCC/LLVM makespecs for iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We only want to support Clang. Change-Id: Id0558df905106158f4c25ca10462bf4ca41e1e45 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/arch.conf | 1 - mkspecs/common/ios/g++.conf | 21 ----------- mkspecs/common/ios/llvm.conf | 31 ---------------- mkspecs/common/ios/qmake.conf | 13 +++---- mkspecs/common/ios/versions.conf | 8 ----- mkspecs/unsupported/macx-iosdevice-g++/qmake.conf | 35 ------------------ .../unsupported/macx-iosdevice-g++/qplatformdefs.h | 42 ---------------------- mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf | 35 ------------------ .../macx-iosdevice-llvm/qplatformdefs.h | 42 ---------------------- .../unsupported/macx-iossimulator-g++/qmake.conf | 33 ----------------- .../macx-iossimulator-g++/qplatformdefs.h | 42 ---------------------- .../unsupported/macx-iossimulator-llvm/qmake.conf | 33 ----------------- .../macx-iossimulator-llvm/qplatformdefs.h | 42 ---------------------- 13 files changed, 5 insertions(+), 373 deletions(-) delete mode 100644 mkspecs/common/ios/g++.conf delete mode 100644 mkspecs/common/ios/llvm.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-g++/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-g++/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-llvm/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-g++/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-g++/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-llvm/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-llvm/qplatformdefs.h diff --git a/mkspecs/common/ios/arch.conf b/mkspecs/common/ios/arch.conf index 4ad96874fe..bf03fe752e 100644 --- a/mkspecs/common/ios/arch.conf +++ b/mkspecs/common/ios/arch.conf @@ -44,7 +44,6 @@ QMAKE_IOS_TARGET_ARCH = QMAKE_IOS_ARM_ARCH += __MARM_THUMB__ # NEON instructions - *-g++*: QMAKE_IOS_ARM_FLAGS += -mfloat-abi=softfp -mfpu=neon QMAKE_IOS_ARM_ARCH += __ARM_NEON__ } else { # Samsung S5L8900 diff --git a/mkspecs/common/ios/g++.conf b/mkspecs/common/ios/g++.conf deleted file mode 100644 index 8a1e0b20c0..0000000000 --- a/mkspecs/common/ios/g++.conf +++ /dev/null @@ -1,21 +0,0 @@ -# -# compiler settings for iOS g++ compilers -# - -# iOS build flags -QMAKE_IOS_CFLAGS = -fvisibility=hidden -fexceptions -fmessage-length=0 -QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wunused-variable -QMAKE_IOS_CXXFLAGS = -fvisibility-inlines-hidden - -# Device or simulator specific flags -!*simulator*: QMAKE_IOS_OBJ_CFLAGS = -else: QMAKE_IOS_OBJ_CFLAGS = -fobjc-abi-version=2 -fobjc-legacy-dispatch - -# Set build flags -QMAKE_CFLAGS += $$QMAKE_IOS_CFLAGS -QMAKE_CXXFLAGS += $$QMAKE_IOS_CFLAGS $$QMAKE_IOS_CXXFLAGS -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_CFLAGS $$QMAKE_IOS_CXXFLAGS $$QMAKE_IOS_OBJ_CFLAGS - -QMAKE_IOS_CFLAGS = -QMAKE_IOS_CXXFLAGS = -QMAKE_IOS_OBJ_CFLAGS = diff --git a/mkspecs/common/ios/llvm.conf b/mkspecs/common/ios/llvm.conf deleted file mode 100644 index fa2e519dd9..0000000000 --- a/mkspecs/common/ios/llvm.conf +++ /dev/null @@ -1,31 +0,0 @@ -# -# compiler settings for iOS llvm-g++ compilers -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -# iOS build flags -QMAKE_IOS_CFLAGS = -fvisibility=hidden -fpascal-strings -fmessage-length=0 -QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wunused-variable -QMAKE_IOS_CXXFLAGS = -fvisibility-inlines-hidden - -# Device or simulator specific flags -!*simulator*: QMAKE_IOS_OBJ_CFLAGS = -else: QMAKE_IOS_OBJ_CFLAGS = -fobjc-abi-version=2 -fobjc-legacy-dispatch - -# Compiler version specific flags -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - # Xcode 4.3+ specific flags - QMAKE_IOS_CFLAGS += -Wuninitialized -} - -# Set build flags -QMAKE_CFLAGS += $$QMAKE_IOS_CFLAGS -QMAKE_CXXFLAGS += $$QMAKE_IOS_CFLAGS $$QMAKE_IOS_CXXFLAGS -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_CFLAGS $$QMAKE_IOS_CXXFLAGS $$QMAKE_IOS_OBJ_CFLAGS - -QMAKE_IOS_CFLAGS = -QMAKE_IOS_CXXFLAGS = -QMAKE_IOS_OBJ_CFLAGS = diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index dcc674556b..1b7a7d2328 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -50,11 +50,8 @@ QMAKE_LIBS_OPENGL_ES2 = -framework OpenGLES QMAKE_INCDIR_OPENGL = QMAKE_LIBS_OPENGL = -# Compiler-specific flags -!*-g++* { - # Objective-C/C++ precompile flags - QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} - QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE - QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} - QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE -} +# Objective-C/C++ precompile flags +QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE +QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index 319144627a..8f9804e5cf 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -10,16 +10,8 @@ # Used in: # # mkspecs/common/ios/clang.conf -# mkspecs/common/ios/llvm.conf # mkspecs/common/ios/qmake.conf -# mkspecs/unsupported/macx-iosdevice-clang-legacy/qmake.conf # mkspecs/unsupported/macx-iosdevice-clang/qmake.conf -# mkspecs/unsupported/macx-iosdevice-llvm-legacy/qmake.conf -# mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf -# mkspecs/unsupported/macx-iosdevice-g++-legacy/qmake.conf -# mkspecs/unsupported/macx-iossimulator-llvm-legacy/qmake.conf -# mkspecs/unsupported/macx-iossimulator-llvm/qmake.conf -# mkspecs/unsupported/macx-iossimulator-g++-legacy/qmake.conf # # diff --git a/mkspecs/unsupported/macx-iosdevice-g++/qmake.conf b/mkspecs/unsupported/macx-iosdevice-g++/qmake.conf deleted file mode 100644 index 2a29335334..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-g++/qmake.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# qmake configuration for ios-device-g++ -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/g++-macx.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/g++.conf) -include(../../common/ios/qmake.conf) - -# Version check (g++ was discontinued at version 4.2, but user may have added it themselves) -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -# iOS build tools -QMAKE_CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -QMAKE_CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/g++-4.2 -QMAKE_FIX_RPATH = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the g++ 4.2 compiler") - -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) diff --git a/mkspecs/unsupported/macx-iosdevice-g++/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-g++/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-g++/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf b/mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf deleted file mode 100644 index 335c68fd42..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-llvm/qmake.conf +++ /dev/null @@ -1,35 +0,0 @@ -# -# qmake configuration for ios-device-llvm -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/llvm.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/llvm.conf) -include(../../common/ios/qmake.conf) - -# Version check -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -# iOS build tools -QMAKE_CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2 -QMAKE_CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-g++-4.2 -QMAKE_FIX_RPATH = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the llvm-g++ 4.2 compiler") - -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) diff --git a/mkspecs/unsupported/macx-iosdevice-llvm/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-llvm/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-llvm/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-g++/qmake.conf b/mkspecs/unsupported/macx-iossimulator-g++/qmake.conf deleted file mode 100644 index 99848be410..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-g++/qmake.conf +++ /dev/null @@ -1,33 +0,0 @@ -# -# qmake configuration for ios-simulator-g++ -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/g++-macx.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/arch.conf) -include(../../common/ios/g++.conf) -include(../../common/ios/qmake.conf) - -# Version check (g++ was discontinued at version 4.2, but user may have added it themselves) -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -# iOS build tools -QMAKE_CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 -QMAKE_CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/g++-4.2 -QMAKE_FIX_RPATH = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the g++ 4.2 compiler") - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-g++/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-g++/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-g++/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-llvm/qmake.conf b/mkspecs/unsupported/macx-iossimulator-llvm/qmake.conf deleted file mode 100644 index 7e3d4b5710..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-llvm/qmake.conf +++ /dev/null @@ -1,33 +0,0 @@ -# -# qmake configuration for ios-simulator-llvm -# -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/llvm.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/arch.conf) -include(../../common/ios/llvm.conf) -include(../../common/ios/qmake.conf) - -# Version check -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -# iOS build tools -QMAKE_CC = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -QMAKE_CXX = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-g++-4.2 -QMAKE_FIX_RPATH = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/install_name_tool -id -QMAKE_AR = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ar cq -QMAKE_RANLIB = /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the llvm-g++ 4.2 compiler") - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-llvm/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-llvm/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-llvm/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" -- cgit v1.2.3 From 8cbdb25ee63ad702fdd91aae264b093bf3927a5c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 30 Oct 2012 14:55:46 +0100 Subject: iOS: copy brute-force port of Qt4 uikit plugin into Qt5. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plugin has been renamed from uikit to ios. Other than that, the plugin will now build, but do nothing. Most of the Qt4 code is preserved, with a rough translation into the Qt5 qpa API. A lot of code has simply been commented out so far, and most lacking at the moment is the event dispatcher which will need to be rewritten, and the opengl paint device implementation. But it should suffice as a starting ground. Also: The plugin will currently not automatically build when building Qt, this needs to be enabled from configure first. Change-Id: I0d229a453a8477618e06554655bffc5505203b44 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.json | 3 + src/plugins/platforms/ios/ios.pro | 27 ++ src/plugins/platforms/ios/main.mm | 69 ++++ src/plugins/platforms/ios/qiosbackingstore.h | 65 +++ src/plugins/platforms/ios/qiosbackingstore.mm | 139 +++++++ src/plugins/platforms/ios/qioseventdispatcher.h | 110 +++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 154 +++++++ src/plugins/platforms/ios/qiosintegration.h | 75 ++++ src/plugins/platforms/ios/qiosintegration.mm | 106 +++++ src/plugins/platforms/ios/qiosscreen.h | 76 ++++ src/plugins/platforms/ios/qiosscreen.mm | 120 ++++++ .../platforms/ios/qiossoftwareinputhandler.h | 73 ++++ src/plugins/platforms/ios/qioswindow.h | 135 +++++++ src/plugins/platforms/ios/qioswindow.mm | 449 +++++++++++++++++++++ 14 files changed, 1601 insertions(+) create mode 100644 src/plugins/platforms/ios/ios.json create mode 100644 src/plugins/platforms/ios/ios.pro create mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/qiosbackingstore.h create mode 100644 src/plugins/platforms/ios/qiosbackingstore.mm create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.h create mode 100644 src/plugins/platforms/ios/qioseventdispatcher.mm create mode 100644 src/plugins/platforms/ios/qiosintegration.h create mode 100644 src/plugins/platforms/ios/qiosintegration.mm create mode 100644 src/plugins/platforms/ios/qiosscreen.h create mode 100644 src/plugins/platforms/ios/qiosscreen.mm create mode 100644 src/plugins/platforms/ios/qiossoftwareinputhandler.h create mode 100644 src/plugins/platforms/ios/qioswindow.h create mode 100644 src/plugins/platforms/ios/qioswindow.mm diff --git a/src/plugins/platforms/ios/ios.json b/src/plugins/platforms/ios/ios.json new file mode 100644 index 0000000000..f0b766dae1 --- /dev/null +++ b/src/plugins/platforms/ios/ios.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "ios" ] +} diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro new file mode 100644 index 0000000000..39f72e9719 --- /dev/null +++ b/src/plugins/platforms/ios/ios.pro @@ -0,0 +1,27 @@ +TARGET = qios +include(../../qpluginbase.pri) +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +QT += opengl +QT += core-private gui-private platformsupport-private opengl-private widgets-private +LIBS += -framework Cocoa -framework UIKit + +OBJECTIVE_SOURCES = main.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm + +OBJECTIVE_HEADERS = qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h + +#HEADERS = qiossoftwareinputhandler.h + +#include(../fontdatabases/coretext/coretext.pri) + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm new file mode 100644 index 0000000000..b09fbce1f4 --- /dev/null +++ b/src/plugins/platforms/ios/main.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "main.moc" + + diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h new file mode 100644 index 0000000000..cb0e9cbedb --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSBACKINGSTORE_H +#define QIOSBACKINGSTORE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSBackingStore : public QPlatformBackingStore +{ +public: + QIOSBackingStore(QWindow *window); + + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + +private: + QPaintDevice *mPaintDevice; +}; + +QT_END_NAMESPACE + +#endif // QIOSBACKINGSTORE_H diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm new file mode 100644 index 0000000000..32ddce38d2 --- /dev/null +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosbackingstore.h" +#include "qioswindow.h" + +#include +#include + +#include + +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + +class EAGLPaintDevice : public QGLPaintDevice +{ +public: + EAGLPaintDevice(QWindow *window) + :QGLPaintDevice(), mWindow(window) + { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast(window->handle())->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif + } + + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } + int devType() const { return QInternal::OpenGL; } + QSize size() const { return mWindow->geometry().size(); } + QGLContext* context() const { + // Todo: siplify this: + return QGLContext::fromOpenGLContext( + static_cast(mWindow->handle())->glContext()->context()); + } + + QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } + +private: + QWindow *mWindow; + PaintDeviceHelper *helper; +}; + +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) +{ +} + +QPaintDevice *QIOSBackingStore::paintDevice() +{ + return mPaintDevice; +} + +void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + Q_UNUSED(offset); + qDebug() << __FUNCTION__ << "not implemented"; + //static_cast(window->handle())->glContext()->swapBuffers(); +} + +void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) +{ + Q_UNUSED(size); + Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h new file mode 100644 index 0000000000..3e70397e63 --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#ifndef QEVENTDISPATCHER_IOS_P_H +#define QEVENTDISPATCHER_IOS_P_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSEventDispatcher : public QAbstractEventDispatcher +{ + Q_OBJECT + +public: + explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags); + bool hasPendingEvents(); + + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object); + bool unregisterTimer(int timerId); + bool unregisterTimers(QObject *object); + QList registeredTimers(QObject *object) const; + + int remainingTime(int timerId); + + void wakeUp(); + void interrupt(); + void flush(); +}; + +QT_END_NAMESPACE + +#endif // QEVENTDISPATCHER_IOS_P_H diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm new file mode 100644 index 0000000000..246c29adde --- /dev/null +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (c) 2007-2008, Apple, Inc. +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are met: +** +** * Redistributions of source code must retain the above copyright notice, +** this list of conditions and the following disclaimer. +** +** * Redistributions in binary form must reproduce the above copyright notice, +** this list of conditions and the following disclaimer in the documentation +** and/or other materials provided with the distribution. +** +** * Neither the name of Apple, Inc. nor the names of its contributors +** may be used to endorse or promote products derived from this software +** without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +****************************************************************************/ + +#include "qioseventdispatcher.h" +#include + +QT_BEGIN_NAMESPACE +QT_USE_NAMESPACE + +QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) +{ + Q_UNUSED(parent); + qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; +} + +QIOSEventDispatcher::~QIOSEventDispatcher() +{} + +bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + Q_UNUSED(flags); + return false; +} + +bool QIOSEventDispatcher::hasPendingEvents() +{ + return false; +} + +void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + Q_UNUSED(notifier); +} + +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +{ + Q_UNUSED(timerId); + Q_UNUSED(interval); + Q_UNUSED(timerType); + Q_UNUSED(object); +} + +bool QIOSEventDispatcher::unregisterTimer(int timerId) +{ + Q_UNUSED(timerId); + return false; +} + +bool QIOSEventDispatcher::unregisterTimers(QObject *object) +{ + Q_UNUSED(object); + return false; +} + +QList QIOSEventDispatcher::registeredTimers(QObject *object) const +{ + Q_UNUSED(object); + return QList(); +} + +int QIOSEventDispatcher::remainingTime(int timerId) +{ + Q_UNUSED(timerId); + return 0; +} + +void QIOSEventDispatcher::wakeUp() +{} + +void QIOSEventDispatcher::interrupt() +{} + +void QIOSEventDispatcher::flush() +{} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h new file mode 100644 index 0000000000..b71379e417 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMINTEGRATION_UIKIT_H +#define QPLATFORMINTEGRATION_UIKIT_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSIntegration : public QPlatformIntegration +{ +public: + QIOSIntegration(); + ~QIOSIntegration(); + + static QIOSIntegration *instance(); + + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + + QList screens() const; + + QPlatformFontDatabase *fontDatabase() const; + + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + +private: + QList mScreens; + QPlatformFontDatabase *mFontDb; +}; + +QT_END_NAMESPACE + +#endif + diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm new file mode 100644 index 0000000000..bd63384004 --- /dev/null +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosIntegration.h" +#include "qioswindow.h" +#include "qiosbackingstore.h" +#include "qiosscreen.h" +#include "qioseventdispatcher.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +static QIOSIntegration *m_instance = 0; + +QIOSIntegration * QIOSIntegration::instance() +{ + return m_instance; +} + +QIOSIntegration::QIOSIntegration() + :mFontDb(new QCoreTextFontDatabase) +{ + if (!m_instance) + m_instance = this; + mScreens << new QIOSScreen(0); +} + +QIOSIntegration::~QIOSIntegration() +{ +} + +QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const +{ + Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; + return 0; + //return new QRasterPixmapData(type); +} + +QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const +{ + return new QIOSWindow(window); +} + +QList QIOSIntegration::screens() const +{ + return mScreens; +} + +QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QIOSBackingStore(window); +} + +QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const +{ + return new QIOSEventDispatcher(); +} + +QPlatformFontDatabase * QIOSIntegration::fontDatabase() const +{ + return mFontDb; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h new file mode 100644 index 0000000000..628d764f53 --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSSCREEN_H +#define QIOSSCREEN_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen : public QPlatformScreen +{ +public: + QIOSScreen(int screenIndex); + ~QIOSScreen(); + + QRect geometry() const { return m_geometry; } + int depth() const { return m_depth; } + QImage::Format format() const { return m_format; } + QSizeF physicalSize() const { return m_physicalSize; } + + UIScreen *uiScreen() const; + + void updateInterfaceOrientation(); +private: + QRect m_geometry; + int m_depth; + QImage::Format m_format; + QSize m_physicalSize; + int m_index; +}; + +QT_END_NAMESPACE + + +#endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm new file mode 100644 index 0000000000..5d9841734a --- /dev/null +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosscreen.h" +#include "qioswindow.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +QIOSScreen::QIOSScreen(int screenIndex) + : QPlatformScreen(), + m_index(screenIndex) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + updateInterfaceOrientation(); + + m_format = QImage::Format_ARGB32_Premultiplied; + + m_depth = 24; + + const qreal inch = 25.4; + qreal unscaledDpi = 160.; + int dragDistance = 12 * scale; + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { + unscaledDpi = 132.; + dragDistance = 10 * scale; + } + m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); + + //qApp->setStartDragDistance(dragDistance); + + /* + QFont font; // system font is helvetica, so that is fine already + font.setPixelSize([UIFont systemFontSize] * scale); + qApp->setFont(font); + */ + + [pool release]; +} + +QIOSScreen::~QIOSScreen() +{ +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return [[UIScreen screens] objectAtIndex:m_index]; +} + +void QIOSScreen::updateInterfaceOrientation() +{ + qDebug() << __FUNCTION__ << "not implemented"; + /* + CGRect bounds = [uiScreen() bounds]; + CGFloat scale = [uiScreen() scale]; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.width * scale, bounds.size.height * scale);; + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, + bounds.size.height * scale, bounds.size.width * scale); + break; + } + foreach (QWidget *widget, qApp->topLevelWidgets()) { + QIOSWindow *platformWindow = static_cast(widget->platformWindow()); + if (platformWindow && platformWindow->platformScreen() == this) { + platformWindow->updateGeometryAndOrientation(); + } + } + */ +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h new file mode 100644 index 0000000000..bbad656b93 --- /dev/null +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -0,0 +1,73 @@ + + +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSSOFTWAREINPUTHANDLER_H +#define QIOSSOFTWAREINPUTHANDLER_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSSoftwareInputHandler : public QObject +{ + Q_OBJECT + +public: + QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + bool eventFilter(QObject *obj, QEvent *event); + +private slots: + void activeFocusChanged(bool focus); + +private: + bool closeSoftwareInputPanel(QWidget *widget); + + QPointer mCurrentFocusWidget; + QPointer mCurrentFocusObject; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h new file mode 100644 index 0000000000..f43f3db4f9 --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSWINDOW_H +#define QIOSWINDOW_H + +#include + +#import +#import +#import +#import +#import +#import + +@interface EAGLView : UIView +{ + QPlatformWindow *mWindow; + EAGLContext *mContext; + + GLint mFramebufferWidth; + GLint mFramebufferHeight; + + GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + + id delegate; + // ------- Text Input ---------- + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; +} + +- (void)setContext:(EAGLContext *)newContext; +- (void)presentFramebuffer; +- (void)deleteFramebuffer; +- (void)createFramebuffer; +- (void)makeCurrent; +- (void)setWindow:(QPlatformWindow *)window; +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; + +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; + +// ------- Text Input ---------- + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + +class EAGLPlatformContext; + +QT_BEGIN_NAMESPACE + +class QIOSScreen; + +class QIOSWindow : public QPlatformWindow +{ +public: + explicit QIOSWindow(QWindow *window); + ~QIOSWindow(); + + UIWindow *nativeWindow() const { return mWindow; } + EAGLView *nativeView() const { return mView; } + void setGeometry(const QRect &rect); + + UIWindow *ensureNativeWindow(); + + QPlatformOpenGLContext *glContext() const; + + QIOSScreen *platformScreen() const { return mScreen; } + + void updateGeometryAndOrientation(); +private: + QIOSScreen *mScreen; + UIWindow *mWindow; + CGRect mFrame; + EAGLView *mView; + mutable EAGLPlatformContext *mContext; +}; + +QT_END_NAMESPACE + +#endif // QIOSWINDOW_H diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm new file mode 100644 index 0000000000..c63c22dbaa --- /dev/null +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -0,0 +1,449 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +#include "qioswindow.h" + +#include "qiosscreen.h" + +#include +#include +#include +#include + +#include + +static GLint stencilBits() +{ + static GLint bits; + static bool initialized = false; + if (!initialized) { + glGetIntegerv(GL_STENCIL_BITS, &bits); + initialized = true; + } + return bits; +} + +/* +static GLint depthBits() +{ + // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 + return stencilBits() > 0 ? 24 : 16; +} +*/ + +class EAGLPlatformContext : public QPlatformOpenGLContext +{ +public: + EAGLPlatformContext(EAGLView *view) + : mView(view) + { + /* + mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); + mFormat.setDepthBufferSize(depthBits()); + mFormat.setAccumBufferSize(0); + mFormat.setRedBufferSize(8); + mFormat.setGreenBufferSize(8); + mFormat.setBlueBufferSize(8); + mFormat.setAlphaBufferSize(8); + mFormat.setStencilBufferSize(stencilBits()); + mFormat.setSamples(0); + mFormat.setSampleBuffers(false); + mFormat.setDoubleBuffer(true); + mFormat.setDepth(true); + mFormat.setRgba(true); + mFormat.setAlpha(true); + mFormat.setAccum(false); + mFormat.setStencil(stencilBits() > 0); + mFormat.setStereo(false); + mFormat.setDirectRendering(false); + */ + +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif + [mView setContext:aContext]; + } + + ~EAGLPlatformContext() { } + + bool makeCurrent(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::makeCurrent(); + //[mView makeCurrent]; + return false; + } + + void doneCurrent() + { + qDebug() << __FUNCTION__ << "not implemented"; + //QPlatformOpenGLContext::doneCurrent(); + } + + void swapBuffers(QPlatformSurface *surface) + { + Q_UNUSED(surface); + qDebug() << __FUNCTION__ << "not implemented"; + //[mView presentFramebuffer]; + } + + QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } + + QSurfaceFormat format() const + { + return mFormat; + } + +private: + EAGLView *mView; + + QSurfaceFormat mFormat; +}; + +@implementation EAGLView + +@synthesize delegate; + ++ (Class)layerClass +{ + return [CAEAGLLayer class]; +} + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + eaglLayer.opaque = TRUE; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, + nil]; + autocapitalizationType = UITextAutocapitalizationTypeNone; + autocorrectionType = UITextAutocorrectionTypeNo; + enablesReturnKeyAutomatically = NO; + keyboardAppearance = UIKeyboardAppearanceDefault; + keyboardType = UIKeyboardTypeDefault; + returnKeyType = UIReturnKeyDone; + secureTextEntry = NO; + } + return self; +} + +- (void)setContext:(EAGLContext *)newContext +{ + if (mContext != newContext) + { + [self deleteFramebuffer]; + [mContext release]; + mContext = [newContext retain]; + [EAGLContext setCurrentContext:nil]; + } +} + +- (void)presentFramebuffer +{ + if (mContext) { + [EAGLContext setCurrentContext:mContext]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; + } +} + +- (void)deleteFramebuffer +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (mFramebuffer) { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + if (mColorRenderbuffer) { + glDeleteRenderbuffers(1, &mColorRenderbuffer); + mColorRenderbuffer = 0; + } + if (mDepthRenderbuffer) { + glDeleteRenderbuffers(1, &mDepthRenderbuffer); + mDepthRenderbuffer = 0; + } + } +} + +- (void)createFramebuffer +{ + if (mContext && !mFramebuffer) + { + [EAGLContext setCurrentContext:mContext]; + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + if (stencilBits() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } + } +} + +- (void)makeCurrent +{ + if (mContext) + { + [EAGLContext setCurrentContext:mContext]; + if (!mFramebuffer) + [self createFramebuffer]; + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + } +} + +- (GLint)fbo +{ + return mFramebuffer; +} + +- (void)setWindow:(QPlatformWindow *)window +{ + mWindow = window; +} + +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +{ + UITouch *touch = [touches anyObject]; + CGPoint locationInView = [touch locationInView:self]; + CGFloat scaleFactor = [self contentScaleFactor]; + QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? + QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + p, p, buttons); +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; +} + +// ------- Text Input ---------- + +@synthesize autocapitalizationType; +@synthesize autocorrectionType; +@synthesize enablesReturnKeyAutomatically; +@synthesize keyboardAppearance; +@synthesize keyboardType; +@synthesize returnKeyType; +@synthesize secureTextEntry; + +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (BOOL)hasText +{ + return YES; +} + +- (void)insertText:(NSString *)text +{ + QString string = QString::fromUtf8([text UTF8String]); + int key = 0; + if ([text isEqualToString:@"\n"]) + key = (int)Qt::Key_Return; + + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, key, Qt::NoModifier, string, false, int(string.length())); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, key, Qt::NoModifier, string, false, int(string.length())); +} + +- (void)deleteBackward +{ + // Send key event to window system interface + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier); + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier); +} + +@end + +QT_BEGIN_NAMESPACE + +QIOSWindow::QIOSWindow(QWindow *window) : + QPlatformWindow(window), + mWindow(nil), + mContext(0) +{ + mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + mView = [[EAGLView alloc] init]; +} + +QIOSWindow::~QIOSWindow() +{ + delete mContext; mContext = 0; + [mView release]; + [mWindow release]; +} + +void QIOSWindow::setGeometry(const QRect &rect) +{ + // Not supported. Only a single "full screen" window is supported + QPlatformWindow::setGeometry(rect); +} + +UIWindow *QIOSWindow::ensureNativeWindow() +{ + if (!mWindow) { + mWindow = [[UIWindow alloc] init]; + updateGeometryAndOrientation(); + // window + mWindow.screen = mScreen->uiScreen(); + // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards + mWindow.frame = mFrame; + + // view + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill + [mView setContentScaleFactor:[mWindow.screen scale]]; + [mView setMultipleTouchEnabled:YES]; + [mView setWindow:this]; + [mWindow addSubview:mView]; + [mWindow setNeedsDisplay]; + [mWindow makeKeyAndVisible]; + } + return mWindow; +} + +void QIOSWindow::updateGeometryAndOrientation() +{ + if (!mWindow) + return; + mFrame = [mScreen->uiScreen() applicationFrame]; + CGRect screen = [mScreen->uiScreen() bounds]; + QRect geom; + CGFloat angle = 0; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + break; + case UIInterfaceOrientationPortraitUpsideDown: + geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, + screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.size.width, + mFrame.size.height); + angle = M_PI; + break; + case UIInterfaceOrientationLandscapeLeft: + geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.origin.x, + mFrame.size.height, + mFrame.size.width); + angle = -M_PI/2.; + break; + case UIInterfaceOrientationLandscapeRight: + geom = QRect(mFrame.origin.y, + screen.size.width - mFrame.origin.x - mFrame.size.width, + mFrame.size.height, + mFrame.size.width); + angle = +M_PI/2.; + break; + } + + CGFloat scale = [mScreen->uiScreen() scale]; + geom = QRect(geom.x() * scale, geom.y() * scale, + geom.width() * scale, geom.height() * scale); + + if (angle != 0) { + [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + } else { + [mView layer].transform = CATransform3DIdentity; + } + [mView setNeedsDisplay]; + window()->setGeometry(geom); +} + +QPlatformOpenGLContext *QIOSWindow::glContext() const +{ + if (!mContext) { + mContext = new EAGLPlatformContext(mView); + } + return mContext; +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 5d6c57fcba2da07551277901300f98e12eb22020 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 29 Oct 2012 13:28:10 +0100 Subject: iOS: fix build issue, dont link against cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the libraries dont depend on Cocoa. This will be picked up by libtool, and make all apps and examples link against cocoa too (which will ofcourse fail) Change-Id: I5654bb08c4ed376fc7ee74da422d903270a8af38 Reviewed-by: Morten Johan Sørvig --- src/gui/gui.pro | 4 +--- src/plugins/platforms/ios/qioseventdispatcher.h | 2 +- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- src/widgets/kernel/mac.pri | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 058cfe92ec..f21c7a5ce7 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -18,9 +18,7 @@ testcocoon { load(testcocoon) } -mac { - LIBS_PRIVATE += -framework Cocoa -} +mac:!ios: LIBS_PRIVATE += -framework Cocoa CONFIG += simd diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 3e70397e63..479ec1d0a0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 246c29adde..12f448488e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. diff --git a/src/widgets/kernel/mac.pri b/src/widgets/kernel/mac.pri index 5474a41f15..4c507ae80e 100644 --- a/src/widgets/kernel/mac.pri +++ b/src/widgets/kernel/mac.pri @@ -1,4 +1,4 @@ -!x11::mac { +!x11:mac:!ios { LIBS_PRIVATE += -framework Carbon -framework Cocoa -lz *-mwerks:INCLUDEPATH += compat } -- cgit v1.2.3 From 8224e5ac7f5f69a64b6ad62bb60277a274bcc60e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 29 Oct 2012 10:26:40 +0100 Subject: iOS: Don't reference QMacStyle from QStyleOption as we don't build it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMacStyle is not buildt as a part of iOS. So make sure we dont reference it from QStyleOption Change-Id: I98e779c576d0607402e45a19b457144a6bdfc73b Reviewed-by: Tor Arne Vestbø --- src/widgets/styles/qstyleoption.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 01e51d594d..eff6837c5a 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -206,7 +206,7 @@ void QStyleOption::init(const QWidget *widget) if (!(state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget)) state &= ~QStyle::State_Enabled; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) switch (QMacStyle::widgetSizePolicy(widget)) { case QMacStyle::SizeSmall: state |= QStyle::State_Small; -- cgit v1.2.3 From 3bc4afc223bcd56245797a0bd3628f02a992301c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:50 +0100 Subject: iOS: Move Q_OS_IOS out of makesespec to qsystemdetection.h We treat iOS as a variant of Mac OS, so for iOS both Q_OS_MAC and Q_OS_IOS will be defined. This matches what Apple assumes in the header file TargetConditionals.h Change-Id: I55cc851401b748297478e4c32e84e0f6e1fdfc28 Reviewed-by: Thiago Macieira --- mkspecs/common/ios.conf | 2 +- src/corelib/global/qsystemdetection.h | 6 ++++++ src/corelib/kernel/qcore_mac_p.h | 2 ++ src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm | 2 ++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/ios.conf b/mkspecs/common/ios.conf index 7420b56daf..c588222666 100644 --- a/mkspecs/common/ios.conf +++ b/mkspecs/common/ios.conf @@ -16,4 +16,4 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET = INCLUDEPATH += $$PWD/ios # iOS defines -DEFINES += DARWIN_NO_CARBON Q_OS_IOS QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG +DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index eb7aa2e64f..86c724ebb5 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -50,6 +50,8 @@ The operating system, must be one of: (Q_OS_x) DARWIN - Darwin OS (synonym for Q_OS_MAC) + MAC - Mac OS X or iOS (iPhoneOS) + IOS - iOS (treated as a variant of Mac OS) MSDOS - MS-DOS and Windows OS2 - OS/2 OS2EMX - XFree86 on OS/2 (not PM) @@ -166,6 +168,10 @@ # elif defined(Q_OS_DARWIN32) # define Q_OS_MAC32 # endif +# include +# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +# define Q_OS_IOS +# endif #endif #if defined(Q_OS_WIN) diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index b833eb4962..361a6c2c67 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -63,6 +63,8 @@ #include #endif +#include "qglobal.h" + #ifndef Q_OS_IOS #include #endif diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index ef5bdbbf0d..fbd836f763 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -39,6 +39,8 @@ ** ****************************************************************************/ +#include "qglobal.h" + #ifndef Q_OS_IOS #import #import -- cgit v1.2.3 From 978eb6bdecdc111a96637be0441ae0230fc0a2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:33 +0100 Subject: iOS: Simplify SDK resolving in mkspec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need to duplicate the logic for device vs simulator. The only difference is the iPhoneOS/iPhoneSimulator name. Change-Id: I87c57fa785279a3ee258b76fdac8317e52e7daa2 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/qmake.conf | 27 ++-------- mkspecs/common/ios/versions.conf | 103 +++++++++++++++------------------------ 2 files changed, 42 insertions(+), 88 deletions(-) diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 1b7a7d2328..ce2124f4fe 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -9,29 +9,10 @@ # QMAKE_IOSSIMULATOR_SDK_VERSION - set in mkspecs/common/ios/versions.conf # -# iOS SDK device type -!*simulator*: QMAKE_IOS_DEVICE_TYPE = iPhoneOS -else { - QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator - - # Use simulator SDK version - QMAKE_IOS_SDK_VERSION = $$QMAKE_IOS_SIMULATOR_SDK_VERSION - QMAKE_IOS_SIMULATOR_SDK_VERSION = -} - -# iOS platform /Developer path -QMAKE_IOS_DEV_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer - -# iOS platform SDK path -QMAKE_IOS_SDK = $$QMAKE_IOS_DEV_PATH/SDKs/$${QMAKE_IOS_DEVICE_TYPE}$${QMAKE_IOS_SDK_VERSION}.sdk -QMAKE_IOS_DEV_PATH = -QMAKE_IOS_DEVICE_TYPE = - -QMAKE_CFLAGS += -isysroot $$QMAKE_IOS_SDK -QMAKE_CXXFLAGS += -isysroot $$QMAKE_IOS_SDK -QMAKE_OBJECTIVE_CFLAGS += -isysroot $$QMAKE_IOS_SDK -QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_IOS_SDK -QMAKE_IOS_SDK = +QMAKE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH +QMAKE_CXXFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH +QMAKE_OBJECTIVE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH +QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_IOS_SDK_PATH # Basic iOS frameworks needed for any GUI app QMAKE_LFLAGS += -framework Foundation -framework UIKit -framework QuartzCore -lz diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index 8f9804e5cf..b46905ff65 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -4,8 +4,7 @@ # This file sets up the following configuration variables: # # QMAKE_IOS_XCODE_VERSION - version number of Xcode being used -# QMAKE_IOS_SDK_VERSION - version number of iOS device SDK -# QMAKE_IOS_SIMULATOR_SDK_VERSION - version number of iOS simulator SDK +# QMAKE_IOS_SDK_VERSION - version number of iOS SDK # # Used in: # @@ -29,15 +28,12 @@ # autodetection (slower!) # -# Xcode version used for cross-compiling +# Xcode version used QMAKE_IOS_XCODE_VERSION = -# iOS SDK version used for cross-compiling for iOS devices +# iOS SDK version used QMAKE_IOS_SDK_VERSION = -# iOS SDK version used for cross-compiling for the iOS simulator -QMAKE_IOS_SIMULATOR_SDK_VERSION = - # # Do not edit values below here if using a pre-built SDK # @@ -73,73 +69,50 @@ QMAKE_XCODE_PLATFORM_PATH = $${QMAKE_XCODE_DEVELOPER_PATH}/Platforms # iOS 4.3 is the preferred version as it is the earliest version that is armv7/gles2 only QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 +# iOS SDK device type +!*simulator*: QMAKE_IOS_DEVICE_TYPE = iPhoneOS +else: QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator + +# iOS platform /Developer path +QMAKE_IOS_DEV_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer + # Get lists of installed SDKs from Xcode QMAKE_XCODE_SDKS = $$system($${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -showsdks) -# Building for iOS device? -!*simulator* { - # No iOS SDK version specified? - isEmpty(QMAKE_IOS_SDK_VERSION) { - # Get names of installed device SDKs - iphoneos_sdks = $$find(QMAKE_XCODE_SDKS, ^iphoneos) - for(v, iphoneos_sdks): { - # Extract SDK version number from output - v = $$replace(v,iphoneos,) - - # Use latest SDK version - greaterThan(v, $$QMAKE_IOS_SDK_VERSION): QMAKE_IOS_SDK_VERSION = $$v - } +# No iOS SDK version specified? +isEmpty(QMAKE_IOS_SDK_VERSION) { + # Get names of installed SDKs + sdk_identifier = $$lower($$QMAKE_IOS_DEVICE_TYPE) + sdks = $$find(QMAKE_XCODE_SDKS, ^$$sdk_identifier) + for(v, sdks): { + # Extract SDK version number from output + v = $$replace(v,$$sdk_identifier,) + + # Use latest SDK version + greaterThan(v, $$QMAKE_IOS_SDK_VERSION): QMAKE_IOS_SDK_VERSION = $$v } - # Make sure iOS SDK version is valid - !exists($$QMAKE_XCODE_PLATFORM_PATH/iPhoneOS.platform/Developer/SDKs/iPhoneOS$${QMAKE_IOS_SDK_VERSION}.sdk) { - error("iOS $$QMAKE_IOS_SDK_VERSION SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.") - } + isEmpty(QMAKE_IOS_SDK_VERSION): error("Could not find a usable SDK, please install using Xcode") +} - # No deployment target specified? - isEmpty(QMAKE_IPHONEOS_DEPLOYMENT_TARGET) { - # Use SDK version for iOS versions < preferred - lessThan(QMAKE_IOS_SDK_VERSION, $$QMAKE_IPHONEOS_PREFERRED_TARGET) { - QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IOS_SDK_VERSION - } else: QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IPHONEOS_PREFERRED_TARGET - } +# iOS platform SDK path +QMAKE_IOS_SDK_PATH = $$QMAKE_IOS_DEV_PATH/SDKs/$${QMAKE_IOS_DEVICE_TYPE}$${QMAKE_IOS_SDK_VERSION}.sdk - # Make sure iOS SDK version is >= iOS target version - !lessThan(QMAKE_IPHONEOS_DEPLOYMENT_TARGET, $$QMAKE_IOS_SDK_VERSION) { - error("Target iOS version is greater that iOS SDK version $$QMAKE_IOS_SDK_VERSION! Edit mkspecs/common/ios/versions.conf to specify target iOS version.") - } -# Building for iOS simulator -} else { - # No iOS simulator SDK version specified? - isEmpty(QMAKE_IOS_SIMULATOR_SDK_VERSION) { - # Get names of installed device SDKs - iphone_simulator_sdks = $$find(QMAKE_XCODE_SDKS, ^iphonesimulator) - for(v, iphone_simulator_sdks): { - # Extract SDK version number from output - v = $$replace(v,iphonesimulator,) - - # Use latest SDK version - greaterThan(v, $$QMAKE_IOS_SIMULATOR_SDK_VERSION): QMAKE_IOS_SIMULATOR_SDK_VERSION = $$v - } - } - - # Make sure iOS simulator SDK version is valid - !exists($$QMAKE_XCODE_PLATFORM_PATH/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator$${QMAKE_IOS_SIMULATOR_SDK_VERSION}.sdk) { - error("iOS $$QMAKE_IOS_SIMULATOR_SDK_VERSION simulator SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.") - } +# Make sure iOS SDK version is valid +!exists($$QMAKE_IOS_SDK_PATH): error("iOS $$QMAKE_IOS_SDK_VERSION SDK not found at $$QMAKE_IOS_SDK_PATH") - # No deployment target specified? - isEmpty(QMAKE_IPHONEOS_DEPLOYMENT_TARGET) { - # Use SDK version for iOS versions < preferred - lessThan(QMAKE_IOS_SIMULATOR_SDK_VERSION, $$QMAKE_IPHONEOS_PREFERRED_TARGET) { - QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IOS_SIMULATOR_SDK_VERSION - } else: QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IPHONEOS_PREFERRED_TARGET - } +# No deployment target specified? +isEmpty(QMAKE_IPHONEOS_DEPLOYMENT_TARGET) { + # Use SDK version for iOS versions < preferred + lessThan(QMAKE_IOS_SDK_VERSION, $$QMAKE_IPHONEOS_PREFERRED_TARGET): \ + QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IOS_SDK_VERSION + else: \ + QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IPHONEOS_PREFERRED_TARGET +} - # Make sure iOS simulator SDK version is >= iOS target version - !lessThan(QMAKE_IPHONEOS_DEPLOYMENT_TARGET, $$QMAKE_IOS_SIMULATOR_SDK_VERSION) { - error("Target iOS version is greater that iOS simulator SDK version $$QMAKE_IOS_SIMULATOR_SDK_VERSION! Edit mkspecs/common/ios/versions.conf to specify target iOS version.") - } +# Make sure iOS SDK version is >= iOS target version +!lessThan(QMAKE_IPHONEOS_DEPLOYMENT_TARGET, $$QMAKE_IOS_SDK_VERSION) { + error("Target iOS version is greater that iOS SDK version $$QMAKE_IOS_SDK_VERSION! Edit mkspecs/common/ios/versions.conf to specify target iOS version.") } unset(QMAKE_IPHONEOS_PREFERRED_TARGET) -- cgit v1.2.3 From 810eee8c773019168c1fcad8262b847009ec149a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:36 +0100 Subject: iOS: Bump arch and iOS SDK, now that we require GLES 2.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now require SDK version 4.3 or above, and armv7. Change-Id: I4766e277a3a4a32712bf2ec27fede694e8316c95 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/GLES/gl.h | 43 ----------------- mkspecs/common/ios/arch.conf | 55 +++++----------------- mkspecs/common/ios/clang.conf | 23 +++------ mkspecs/common/ios/qmake.conf | 6 +-- mkspecs/common/ios/versions.conf | 8 +--- .../unsupported/macx-iosdevice-clang/qmake.conf | 6 +-- 6 files changed, 25 insertions(+), 116 deletions(-) delete mode 100644 mkspecs/common/ios/GLES/gl.h diff --git a/mkspecs/common/ios/GLES/gl.h b/mkspecs/common/ios/GLES/gl.h deleted file mode 100644 index 2b94b162eb..0000000000 --- a/mkspecs/common/ios/GLES/gl.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include diff --git a/mkspecs/common/ios/arch.conf b/mkspecs/common/ios/arch.conf index bf03fe752e..3ac84081af 100644 --- a/mkspecs/common/ios/arch.conf +++ b/mkspecs/common/ios/arch.conf @@ -1,38 +1,16 @@ # # Helper to set CPU architecture flags for iOS configurations # -# Depends on: -# -# QMAKE_IPHONEOS_DEPLOYMENT_TARGET - set in mkspecs/common/ios/versions.conf -# -# Note: -# -# Must be included after load(qt_config) in mkspec for auto-detection based -# on GL/ES version (GL/ES 2.x implies armv7 on iOS). -# -# Target architecture for iOS devices (armv6, armv7 or leave blank for default) -QMAKE_IOS_TARGET_ARCH = +# Target architecture for iOS devices (armv7 or leave blank for default) +QMAKE_IOS_TARGET_ARCH = ########################################################################### # Device? !*simulator* { - # Let mkspec specify archictecture - *armv6*: QMAKE_IOS_TARGET_ARCH = armv6 - else:*armv7*: QMAKE_IOS_TARGET_ARCH = armv7 - - # ARMv7 architecture device (see below) is required for OpenGL/ES 2.x - isEmpty(QMAKE_IOS_TARGET_ARCH):contains(QT_CONFIG, opengles2): QMAKE_IOS_TARGET_ARCH = armv7 - - # No target architecture specified? - isEmpty(QMAKE_IOS_TARGET_ARCH) { - # iOS versions < 4.3 can be armv6 or armv7, so need armv6 for max. compatibility, - # assume that building for OpenGL/ES 1.x is targeting armv6 - lessThan(QMAKE_IPHONEOS_DEPLOYMENT_TARGET, "4.3")|contains(QT_CONFIG, opengles1) { - QMAKE_IOS_TARGET_ARCH = armv6 - } else: QMAKE_IOS_TARGET_ARCH = armv7 - } + # ARMv7 architecture device is required for OpenGL/ES 2.x + isEmpty(QMAKE_IOS_TARGET_ARCH): QMAKE_IOS_TARGET_ARCH = armv7 # Samsung S5PC100, Apple A4, A5, A5X equals(QMAKE_IOS_TARGET_ARCH, "armv7") { @@ -46,38 +24,29 @@ QMAKE_IOS_TARGET_ARCH = # NEON instructions QMAKE_IOS_ARM_ARCH += __ARM_NEON__ } else { - # Samsung S5L8900 - if(equals(QMAKE_IOS_TARGET_ARCH, "armv6")) { - # iOS CPU architecture (armv6) - QMAKE_IOS_ARM_ARCH = __ARM_ARCH_6__ - - # ARM instructions - QMAKE_IOS_ARM_FLAGS = -marm -mcpu=arm1176jzf-s - !*clang*: QMAKE_IOS_ARM_FLAGS += -march=armv6 - } else { - # Unsupported architecture - error("Invalid iOS target $${QMAKE_IOS_TARGET_ARCH}! Edit mkspecs/common/ios/arch.conf to specify target architecture.") - } + # Unsupported architecture + error("Invalid iOS target $${QMAKE_IOS_TARGET_ARCH}!") } # Simulator is i386 only } else: QMAKE_IOS_TARGET_ARCH = i386 # iOS architecture build flags QMAKE_IOS_ARCH_FLAGS = -arch $$QMAKE_IOS_TARGET_ARCH + QMAKE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_CXXFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_LFLAGS += $$QMAKE_IOS_ARCH_FLAGS -QMAKE_IOS_TARGET_ARCH = -QMAKE_IOS_ARCH_FLAGS = # Architecture specific defines/flags !*simulator* { DEFINES += $$QMAKE_IOS_ARM_ARCH - QMAKE_IOS_ARM_ARCH = - QMAKE_CFLAGS += $$QMAKE_IOS_ARM_FLAGS QMAKE_CXXFLAGS += $$QMAKE_IOS_ARM_FLAGS QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARM_FLAGS - QMAKE_IOS_ARM_FLAGS = } + +unset(QMAKE_IOS_TARGET_ARCH) +unset(QMAKE_IOS_ARCH_FLAGS) +unset(QMAKE_IOS_ARM_ARCH) +unset(QMAKE_IOS_ARM_FLAGS) diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index 10d1dbd24e..eb7b058c6b 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -18,24 +18,13 @@ QMAKE_IOS_OBJ_CFLAGS = -Wno-arc-abi -Wc++0x-extensions QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch } -# Compiler version-specific flags -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.3") { - # Clang 3.1 flags (will be used for later versions too) - QMAKE_IOS_CFLAGS += -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wformat -Wno-missing-braces -Wno-unused-function -Wno-unused-label -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-sign-compare -Wpointer-sign -Wno-newline-eof -Wdeprecated-declarations -Winvalid-offsetof -Wno-conversion - QMAKE_IOS_CXXFLAGS += -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wc++11-extensions - QMAKE_IOS_OBJ_CFLAGS += -Wno-deprecated-implementations -Wprotocol -Wno-selector -Wno-strict-selector-match -Wno-undeclared-selector +# Clang 3.1 (and above) flags +QMAKE_IOS_CFLAGS += -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wformat -Wno-missing-braces -Wno-unused-function -Wno-unused-label -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-sign-compare -Wpointer-sign -Wno-newline-eof -Wdeprecated-declarations -Winvalid-offsetof -Wno-conversion +QMAKE_IOS_CXXFLAGS += -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wc++11-extensions +QMAKE_IOS_OBJ_CFLAGS += -Wno-deprecated-implementations -Wprotocol -Wno-selector -Wno-strict-selector-match -Wno-undeclared-selector - # Warn about unsupported (later than 4.5) Xcode versions - !lessThan(QMAKE_IOS_XCODE_VERSION, "4.6"): warning("The version of Xcode installed on this system is not recognised - custom compiler settings may be necessary") -} else { - if (!lessThan(QMAKE_IOS_XCODE_VERSION, "4.2")) { - # Clang 3.0 flags - QMAKE_IOS_CFLAGS += -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits - } else { - # Older Clang versions are not supported - error("Unsupported Xcode version $${QMAKE_IOS_XCODE_VERSION}") - } -} +# Warn about unsupported (later than 4.5) Xcode versions +!lessThan(QMAKE_IOS_XCODE_VERSION, "4.6"): warning("The version of Xcode installed on this system is not recognised - custom compiler settings may be necessary") # Set build flags QMAKE_CFLAGS += $$QMAKE_IOS_CFLAGS diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index ce2124f4fe..7f6a4df544 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -17,10 +17,10 @@ QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_IOS_SDK_PATH # Basic iOS frameworks needed for any GUI app QMAKE_LFLAGS += -framework Foundation -framework UIKit -framework QuartzCore -lz -# OpenGL ES1 -QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_IOS_SDK/System/Library/Frameworks/OpenGLES.framework/Headers +# No OpenGL ES1 +QMAKE_INCDIR_OPENGL_ES1 = QMAKE_LIBDIR_OPENGL_ES1 = -QMAKE_LIBS_OPENGL_ES1 = -framework OpenGLES +QMAKE_LIBS_OPENGL_ES1 = # OpenGL ES2 QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_IOS_SDK/System/Library/Frameworks/OpenGLES.framework/Headers diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index b46905ff65..ef6f94cdb6 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -38,12 +38,8 @@ QMAKE_IOS_SDK_VERSION = # Do not edit values below here if using a pre-built SDK # -# Minimum iOS version required on deployment target (if not specified, will -# default to minimum version that guarantees ARMv7 & OpenGL/ES 2.x). -# -# No part of Qt or any known plugin uses features that require iOS versions -# later than 4.0. -QMAKE_IPHONEOS_DEPLOYMENT_TARGET = 4.0 +# Minimum iOS version required on deployment target +QMAKE_IPHONEOS_DEPLOYMENT_TARGET = 4.3 ########################################################################### diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf index ed6852e0d6..b04d6070ae 100644 --- a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf @@ -13,6 +13,7 @@ include(../../common/ios.conf) include(../../common/ios/versions.conf) include(../../common/ios/clang.conf) include(../../common/ios/qmake.conf) +include(../../common/ios/arch.conf) # Version check lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") @@ -29,7 +30,4 @@ QMAKE_LINK_SHLIB = $$QMAKE_CXX # Check that compiler is valid !exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler") -load(qt_config) - -# Include after config is loaded to allow autodetection on GL/ES version -include(../../common/ios/arch.conf) +load(qt_config) \ No newline at end of file -- cgit v1.2.3 From 89fbad0827ba25e8936f57ac63a127cf7082255f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Feb 2013 18:13:16 +0100 Subject: iOS: Force static builds so that apps can be submitted to the App Store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I66c917e98e40c07ae9532c106ee1c47caa61abd5 Reviewed-by: Morten Johan Sørvig --- configure | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configure b/configure index 45673a356d..e8c53a47ed 100755 --- a/configure +++ b/configure @@ -2512,6 +2512,7 @@ fi case `basename "$XPLATFORM"` in win32-g++*) XPLATFORM_MINGW=yes;; esac case "$XPLATFORM" in *-maemo*) XPLATFORM_MAEMO=yes;; esac case "$XPLATFORM" in *qnx-*|*blackberry-*) XPLATFORM_QNX=yes;; esac +case "$XPLATFORM" in *ios*) XPLATFORM_IOS=yes;; esac if [ -d "$PLATFORM" ]; then QMAKESPEC="$PLATFORM" @@ -2620,6 +2621,11 @@ if [ "$CFG_FORCEDEBUGINFO" = "yes" ]; then QT_CONFIG="$QT_CONFIG force_debug_info" fi +# iOS builds should be static to be able to submit to the App Store +if [ "$XPLATFORM_IOS" = "yes" ]; then + CFG_SHARED="no" +fi + # disable GTK style support auto-detection on Mac if [ "$BUILD_ON_MAC" = "yes" ] && [ "$CFG_QGTKSTYLE" = "auto" ]; then CFG_QGTKSTYLE=no -- cgit v1.2.3 From 935bb943850d79959188c2f60267b182a8529168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:44 +0100 Subject: iOS: Simplify arch detection/configuration in mkspec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NEON detection is handled by configure's arch test, and THUMB2 is the default for ARMv7. Change-Id: I8ec3ce0ec6af9ad8d9509890aa1f8c87e18364d5 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/arch.conf | 40 ++++++---------------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/mkspecs/common/ios/arch.conf b/mkspecs/common/ios/arch.conf index 3ac84081af..3e469fe306 100644 --- a/mkspecs/common/ios/arch.conf +++ b/mkspecs/common/ios/arch.conf @@ -1,36 +1,18 @@ # # Helper to set CPU architecture flags for iOS configurations # - -# Target architecture for iOS devices (armv7 or leave blank for default) -QMAKE_IOS_TARGET_ARCH = - ########################################################################### # Device? -!*simulator* { - # ARMv7 architecture device is required for OpenGL/ES 2.x - isEmpty(QMAKE_IOS_TARGET_ARCH): QMAKE_IOS_TARGET_ARCH = armv7 - +!*simulator*: \ # Samsung S5PC100, Apple A4, A5, A5X - equals(QMAKE_IOS_TARGET_ARCH, "armv7") { - # iOS CPU architecture (armv7) - QMAKE_IOS_ARM_ARCH = __ARM_ARCH_7__ + QMAKE_IOS_TARGET_ARCH = armv7 +else: \ + # Simulator is i386 only + QMAKE_IOS_TARGET_ARCH = i386 - # Thumb2 instructions - QMAKE_IOS_ARM_FLAGS = -mthumb - QMAKE_IOS_ARM_ARCH += __MARM_THUMB__ +# FIXME: Add armv7s support when we need it - # NEON instructions - QMAKE_IOS_ARM_ARCH += __ARM_NEON__ - } else { - # Unsupported architecture - error("Invalid iOS target $${QMAKE_IOS_TARGET_ARCH}!") - } -# Simulator is i386 only -} else: QMAKE_IOS_TARGET_ARCH = i386 - -# iOS architecture build flags QMAKE_IOS_ARCH_FLAGS = -arch $$QMAKE_IOS_TARGET_ARCH QMAKE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS @@ -38,15 +20,5 @@ QMAKE_CXXFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_LFLAGS += $$QMAKE_IOS_ARCH_FLAGS -# Architecture specific defines/flags -!*simulator* { - DEFINES += $$QMAKE_IOS_ARM_ARCH - QMAKE_CFLAGS += $$QMAKE_IOS_ARM_FLAGS - QMAKE_CXXFLAGS += $$QMAKE_IOS_ARM_FLAGS - QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARM_FLAGS -} - unset(QMAKE_IOS_TARGET_ARCH) unset(QMAKE_IOS_ARCH_FLAGS) -unset(QMAKE_IOS_ARM_ARCH) -unset(QMAKE_IOS_ARM_FLAGS) -- cgit v1.2.3 From d8986893003b2080d2b3383ee283f1b8ee13d645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 12:31:47 +0100 Subject: iOS: Disable NEON until LLVM handles the GAS syntax of the draw-helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LLVM version in Xcode 4.5 and below does not handle the GNU assembler syntax in the pixman assembly file. A possible alternative workaround is to include a preprocessed assembly file using https://github.com/hollylee/gas-preprocessor. Change-Id: Id95add669c60d3a7da823e5975afdd1f88f71977 Reviewed-by: Morten Johan Sørvig --- configure | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure b/configure index e8c53a47ed..59e6103b1c 100755 --- a/configure +++ b/configure @@ -4032,7 +4032,8 @@ fi # detect neon support if [ "$CFG_ARCH" = "arm" ] && [ "${CFG_NEON}" = "auto" ]; then - if compileTest unix/neon "neon"; then + # The iOS toolchain has trouble building the pixman NEON draw-helpers + if [ "$XPLATFORM_IOS" != "yes" ] && compileTest unix/neon "neon"; then CFG_NEON=yes else CFG_NEON=no -- cgit v1.2.3 From 6e594a945164d661d0e1336fcdde784ccd41f5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 13:18:15 +0100 Subject: iOS: Move device/simulator conditionals out of common mkspecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead we deal with any differenced by setting variables in the top level makespecs, that are used by the common makespec configs. Change-Id: Iae1fb5fef8c95778511ed400008731989b446f3c Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/arch.conf | 11 --------- mkspecs/common/ios/clang.conf | 12 +++------- mkspecs/common/ios/qmake.conf | 14 +++++++++++ mkspecs/common/ios/versions.conf | 7 +++--- .../unsupported/macx-iosdevice-clang/qmake.conf | 28 +++++++--------------- .../unsupported/macx-iossimulator-clang/qmake.conf | 20 ++++++++++++++-- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/mkspecs/common/ios/arch.conf b/mkspecs/common/ios/arch.conf index 3e469fe306..6bd27a6136 100644 --- a/mkspecs/common/ios/arch.conf +++ b/mkspecs/common/ios/arch.conf @@ -3,16 +3,6 @@ # ########################################################################### -# Device? -!*simulator*: \ - # Samsung S5PC100, Apple A4, A5, A5X - QMAKE_IOS_TARGET_ARCH = armv7 -else: \ - # Simulator is i386 only - QMAKE_IOS_TARGET_ARCH = i386 - -# FIXME: Add armv7s support when we need it - QMAKE_IOS_ARCH_FLAGS = -arch $$QMAKE_IOS_TARGET_ARCH QMAKE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS @@ -20,5 +10,4 @@ QMAKE_CXXFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS QMAKE_LFLAGS += $$QMAKE_IOS_ARCH_FLAGS -unset(QMAKE_IOS_TARGET_ARCH) unset(QMAKE_IOS_ARCH_FLAGS) diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index eb7b058c6b..42400c9775 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -7,16 +7,10 @@ # # iOS build flags -QMAKE_IOS_CFLAGS = -fvisibility=hidden -fpascal-strings -fmessage-length=0 +QMAKE_IOS_CFLAGS += -fvisibility=hidden -fpascal-strings -fmessage-length=0 QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -Wno-sign-conversion -QMAKE_IOS_CXXFLAGS = -fvisibility-inlines-hidden -QMAKE_IOS_OBJ_CFLAGS = -Wno-arc-abi -Wc++0x-extensions - -# Device or simulator specific flags -*simulator* { - QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks - QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch -} +QMAKE_IOS_CXXFLAGS += -fvisibility-inlines-hidden +QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi -Wc++0x-extensions # Clang 3.1 (and above) flags QMAKE_IOS_CFLAGS += -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wformat -Wno-missing-braces -Wno-unused-function -Wno-unused-label -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-sign-compare -Wpointer-sign -Wno-newline-eof -Wdeprecated-declarations -Winvalid-offsetof -Wno-conversion diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 7f6a4df544..ee3010f451 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -9,6 +9,20 @@ # QMAKE_IOSSIMULATOR_SDK_VERSION - set in mkspecs/common/ios/versions.conf # +QMAKE_XCODE_TOOLCHAIN_BIN_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin + +# iOS build tools +QMAKE_CC = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/clang +QMAKE_CXX = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/clang++ +QMAKE_FIX_RPATH = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/install_name_tool -id +QMAKE_AR = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/ar cq +QMAKE_RANLIB = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/ranlib -s +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_CXX + +# Check that compiler is valid +!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler") + QMAKE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH QMAKE_CXXFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH QMAKE_OBJECTIVE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index ef6f94cdb6..488116a2a6 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -60,15 +60,14 @@ isEmpty(QMAKE_IOS_XCODE_VERSION) { QMAKE_IOS_XCODE_INFO = } +# Version check +lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") + QMAKE_XCODE_PLATFORM_PATH = $${QMAKE_XCODE_DEVELOPER_PATH}/Platforms # iOS 4.3 is the preferred version as it is the earliest version that is armv7/gles2 only QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 -# iOS SDK device type -!*simulator*: QMAKE_IOS_DEVICE_TYPE = iPhoneOS -else: QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator - # iOS platform /Developer path QMAKE_IOS_DEV_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf index b04d6070ae..330dcf6c3c 100644 --- a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf @@ -1,10 +1,13 @@ # # qmake configuration for ios-device-clang # -# Depends on: -# -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# + +QMAKE_IOS_DEVICE_TYPE = iPhoneOS + +# Samsung S5PC100, Apple A4, A5, A5X +QMAKE_IOS_TARGET_ARCH = armv7 + +# FIXME: Add armv7s (A6) support when we need it include(../../common/mac.conf) include(../../common/gcc-base-ios.conf) @@ -15,19 +18,4 @@ include(../../common/ios/clang.conf) include(../../common/ios/qmake.conf) include(../../common/ios/arch.conf) -# Version check -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -# iOS build tools -QMAKE_CC = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -QMAKE_CXX = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -QMAKE_FIX_RPATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool -id -QMAKE_AR = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar cq -QMAKE_RANLIB = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib -s -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX - -# Check that compiler is valid -!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler") - -load(qt_config) \ No newline at end of file +load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf b/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf index 11301cb72f..bf334b9960 100644 --- a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf @@ -2,5 +2,21 @@ # qmake configuration for ios-simulator-clang # -# All differences between device and simulator are handled in iOS include files -include(../macx-iosdevice-clang/qmake.conf) +QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator + +# Simulator is i386 only +QMAKE_IOS_TARGET_ARCH = i386 + +QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks +QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch + +include(../../common/mac.conf) +include(../../common/gcc-base-ios.conf) +include(../../common/clang.conf) +include(../../common/ios.conf) +include(../../common/ios/versions.conf) +include(../../common/ios/clang.conf) +include(../../common/ios/qmake.conf) +include(../../common/ios/arch.conf) + +load(qt_config) -- cgit v1.2.3 From 2aeb742a581efa354e0ff93296d5caf66c38d88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Feb 2013 16:35:52 +0100 Subject: iOS: Use sdk.prf to set -isysroot based on the chosen SDK Change-Id: I4683ab422ad886b86604fbd68f8dfb4cf6bfc06e Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios.conf | 2 +- mkspecs/common/ios/qmake.conf | 7 +------ mkspecs/common/ios/versions.conf | 10 +++------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/mkspecs/common/ios.conf b/mkspecs/common/ios.conf index c588222666..890446d844 100644 --- a/mkspecs/common/ios.conf +++ b/mkspecs/common/ios.conf @@ -3,7 +3,7 @@ # MAKEFILE_GENERATOR = UNIX -CONFIG += ios reduce_exports incremental global_init_link_order lib_version_first plugin_no_soname +CONFIG += ios reduce_exports incremental global_init_link_order lib_version_first plugin_no_soname sdk QMAKE_INCREMENTAL_STYLE = sublib # Qt can't build iOS app bundle :( diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index ee3010f451..260eaaeddb 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -23,11 +23,6 @@ QMAKE_LINK_SHLIB = $$QMAKE_CXX # Check that compiler is valid !exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler") -QMAKE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH -QMAKE_CXXFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH -QMAKE_OBJECTIVE_CFLAGS += -isysroot $$QMAKE_IOS_SDK_PATH -QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_IOS_SDK_PATH - # Basic iOS frameworks needed for any GUI app QMAKE_LFLAGS += -framework Foundation -framework UIKit -framework QuartzCore -lz @@ -37,7 +32,7 @@ QMAKE_LIBDIR_OPENGL_ES1 = QMAKE_LIBS_OPENGL_ES1 = # OpenGL ES2 -QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_IOS_SDK/System/Library/Frameworks/OpenGLES.framework/Headers +QMAKE_INCDIR_OPENGL_ES2 = QMAKE_LIBDIR_OPENGL_ES2 = QMAKE_LIBS_OPENGL_ES2 = -framework OpenGLES diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf index 488116a2a6..7c2acf9da5 100644 --- a/mkspecs/common/ios/versions.conf +++ b/mkspecs/common/ios/versions.conf @@ -87,15 +87,11 @@ isEmpty(QMAKE_IOS_SDK_VERSION) { greaterThan(v, $$QMAKE_IOS_SDK_VERSION): QMAKE_IOS_SDK_VERSION = $$v } - isEmpty(QMAKE_IOS_SDK_VERSION): error("Could not find a usable SDK, please install using Xcode") + # We have at least one version of this SDK, so we choose the latest one by + # passing the SDK identifier as QMAKE_MAC_SDK, as reccomended by Apple. + QMAKE_MAC_SDK = $$sdk_identifier } -# iOS platform SDK path -QMAKE_IOS_SDK_PATH = $$QMAKE_IOS_DEV_PATH/SDKs/$${QMAKE_IOS_DEVICE_TYPE}$${QMAKE_IOS_SDK_VERSION}.sdk - -# Make sure iOS SDK version is valid -!exists($$QMAKE_IOS_SDK_PATH): error("iOS $$QMAKE_IOS_SDK_VERSION SDK not found at $$QMAKE_IOS_SDK_PATH") - # No deployment target specified? isEmpty(QMAKE_IPHONEOS_DEPLOYMENT_TARGET) { # Use SDK version for iOS versions < preferred -- cgit v1.2.3 From 67f925701b490e3e9cdbb0dbbfc1a14d1b409bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 13 Nov 2012 15:52:25 +0100 Subject: iOS: Include clang-mac.conf instead of defining precompile flags ourselves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1a3b9ad16e54457068d3451c066a8d7965a622df Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/qmake.conf | 6 ------ mkspecs/unsupported/macx-iosdevice-clang/qmake.conf | 1 + mkspecs/unsupported/macx-iossimulator-clang/qmake.conf | 1 + 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 260eaaeddb..9235e68b0d 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -39,9 +39,3 @@ QMAKE_LIBS_OPENGL_ES2 = -framework OpenGLES # No desktop OpenGL QMAKE_INCDIR_OPENGL = QMAKE_LIBS_OPENGL = - -# Objective-C/C++ precompile flags -QMAKE_OBJCFLAGS_PRECOMPILE = -x objective-c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} -QMAKE_OBJCFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE -QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} -QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf index 330dcf6c3c..3e1a669905 100644 --- a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf @@ -12,6 +12,7 @@ QMAKE_IOS_TARGET_ARCH = armv7 include(../../common/mac.conf) include(../../common/gcc-base-ios.conf) include(../../common/clang.conf) +include(../../common/clang-mac.conf) include(../../common/ios.conf) include(../../common/ios/versions.conf) include(../../common/ios/clang.conf) diff --git a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf b/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf index bf334b9960..a8072fed00 100644 --- a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf +++ b/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf @@ -13,6 +13,7 @@ QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch include(../../common/mac.conf) include(../../common/gcc-base-ios.conf) include(../../common/clang.conf) +include(../../common/clang-mac.conf) include(../../common/ios.conf) include(../../common/ios/versions.conf) include(../../common/ios/clang.conf) -- cgit v1.2.3 From c3278e33534fe937fe367dfbf648282ceba68c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 20 Nov 2012 15:25:34 +0100 Subject: iOS: Replace device and simulator makespecs with single makespec And use configure's -sdk argument to choose between the iphoneos and the iphonesimulator SDK. xcodebuild -showsdks can be used to list the available SDKs. Passing an SDK without a version postfix implies the latest version of the SDK. Change-Id: I881df754d522fc91aaa16ba3e39cf0c37a21a1f1 Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios.conf | 3 + mkspecs/common/ios/arch.conf | 13 --- mkspecs/common/ios/clang.conf | 9 +- mkspecs/common/ios/qmake.conf | 6 +- mkspecs/common/ios/versions.conf | 120 --------------------- mkspecs/common/xcode.conf | 13 +++ mkspecs/features/ios.prf | 25 +++++ mkspecs/features/mac/sdk.prf | 10 +- mkspecs/unsupported/macx-ios-clang/qmake.conf | 30 ++++++ mkspecs/unsupported/macx-ios-clang/qplatformdefs.h | 42 ++++++++ .../unsupported/macx-iosdevice-clang/qmake.conf | 22 ---- .../macx-iosdevice-clang/qplatformdefs.h | 42 -------- .../unsupported/macx-iossimulator-clang/qmake.conf | 23 ---- .../macx-iossimulator-clang/qplatformdefs.h | 42 -------- 14 files changed, 131 insertions(+), 269 deletions(-) delete mode 100644 mkspecs/common/ios/arch.conf delete mode 100644 mkspecs/common/ios/versions.conf create mode 100644 mkspecs/common/xcode.conf create mode 100644 mkspecs/features/ios.prf create mode 100644 mkspecs/unsupported/macx-ios-clang/qmake.conf create mode 100644 mkspecs/unsupported/macx-ios-clang/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iosdevice-clang/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iosdevice-clang/qplatformdefs.h delete mode 100644 mkspecs/unsupported/macx-iossimulator-clang/qmake.conf delete mode 100644 mkspecs/unsupported/macx-iossimulator-clang/qplatformdefs.h diff --git a/mkspecs/common/ios.conf b/mkspecs/common/ios.conf index 890446d844..0d68d37ff8 100644 --- a/mkspecs/common/ios.conf +++ b/mkspecs/common/ios.conf @@ -12,6 +12,9 @@ CONFIG -= app_bundle # Not deploying to Mac OSX QMAKE_MACOSX_DEPLOYMENT_TARGET = +# But to iOS +QMAKE_IOS_DEPLOYMENT_TARGET = 4.3 + # Add iOS common folder to include path INCLUDEPATH += $$PWD/ios diff --git a/mkspecs/common/ios/arch.conf b/mkspecs/common/ios/arch.conf deleted file mode 100644 index 6bd27a6136..0000000000 --- a/mkspecs/common/ios/arch.conf +++ /dev/null @@ -1,13 +0,0 @@ -# -# Helper to set CPU architecture flags for iOS configurations -# -########################################################################### - -QMAKE_IOS_ARCH_FLAGS = -arch $$QMAKE_IOS_TARGET_ARCH - -QMAKE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS -QMAKE_CXXFLAGS += $$QMAKE_IOS_ARCH_FLAGS -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_ARCH_FLAGS -QMAKE_LFLAGS += $$QMAKE_IOS_ARCH_FLAGS - -unset(QMAKE_IOS_ARCH_FLAGS) diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index 42400c9775..9b092d3fa4 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -3,7 +3,7 @@ # # Depends on: # -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf +# QMAKE_IOS_XCODE_VERSION - set in macx-ios-clang/qmake.conf # # iOS build flags @@ -12,6 +12,13 @@ QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wparentheses -Wswitch -W QMAKE_IOS_CXXFLAGS += -fvisibility-inlines-hidden QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi -Wc++0x-extensions +# Based on the following information, http://clang.llvm.org/doxygen/ObjCRuntime_8h_source.html, +# we can conclude that it's safe to always pass the following flags +QMAKE_IOS_OBJ_CFLAGS += -fobjc-nonfragile-abi -fobjc-legacy-dispatch + +# But these only apply to non-ARM targets +!contains(QT_ARCH, arm): QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks + # Clang 3.1 (and above) flags QMAKE_IOS_CFLAGS += -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wformat -Wno-missing-braces -Wno-unused-function -Wno-unused-label -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-sign-compare -Wpointer-sign -Wno-newline-eof -Wdeprecated-declarations -Winvalid-offsetof -Wno-conversion QMAKE_IOS_CXXFLAGS += -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wc++11-extensions diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 9235e68b0d..2a8d64fd9f 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -3,11 +3,7 @@ # # Depends on: # -# QMAKE_XCODE_DEVELOPER_PATH - set in mkspecs/common/ios/versions.conf -# QMAKE_IOS_XCODE_VERSION - set in mkspecs/common/ios/versions.conf -# QMAKE_IOS_SDK_VERSION - set in mkspecs/common/ios/versions.conf -# QMAKE_IOSSIMULATOR_SDK_VERSION - set in mkspecs/common/ios/versions.conf -# +# QMAKE_XCODE_DEVELOPER_PATH - set in mkspecs/common/xcode.conf QMAKE_XCODE_TOOLCHAIN_BIN_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin diff --git a/mkspecs/common/ios/versions.conf b/mkspecs/common/ios/versions.conf deleted file mode 100644 index 7c2acf9da5..0000000000 --- a/mkspecs/common/ios/versions.conf +++ /dev/null @@ -1,120 +0,0 @@ -# -# Helper to set build tool & SDK versions for iOS configurations -# -# This file sets up the following configuration variables: -# -# QMAKE_IOS_XCODE_VERSION - version number of Xcode being used -# QMAKE_IOS_SDK_VERSION - version number of iOS SDK -# -# Used in: -# -# mkspecs/common/ios/clang.conf -# mkspecs/common/ios/qmake.conf -# mkspecs/unsupported/macx-iosdevice-clang/qmake.conf -# - -# -# IMPORTANT: -# -# Xcode versions >= 4.10 & < 5.0 and versions >= 10.0 are not supported due to -# the way the version checks are done here. As Apple (so far) has not used -# minor version numbers greater than 3 for Xcode, and the Xcode major version -# has only changed three times in the period 2003-2012, this is viewed as an -# acceptable limitation. -# - -# -# Edit values below to match iOS build environment, or leave blank for -# autodetection (slower!) -# - -# Xcode version used -QMAKE_IOS_XCODE_VERSION = - -# iOS SDK version used -QMAKE_IOS_SDK_VERSION = - -# -# Do not edit values below here if using a pre-built SDK -# - -# Minimum iOS version required on deployment target -QMAKE_IPHONEOS_DEPLOYMENT_TARGET = 4.3 - -########################################################################### - -# Get path of Xcode's Developer directory -QMAKE_XCODE_DEVELOPER_PATH = $$system(xcode-select --print-path) - -# Make sure Xcode path is valid -!exists($$QMAKE_XCODE_DEVELOPER_PATH): \ - error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}! Please use xcode-select to choose Xcode installation path") - -# No Xcode version specified? -isEmpty(QMAKE_IOS_XCODE_VERSION) { - # Get version string from installed Xcode - QMAKE_IOS_XCODE_INFO = $$system($${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -version) - - # Extract Xcode version number from output - QMAKE_IOS_XCODE_VERSION = $$member(QMAKE_IOS_XCODE_INFO, 1) - QMAKE_IOS_XCODE_INFO = -} - -# Version check -lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") - -QMAKE_XCODE_PLATFORM_PATH = $${QMAKE_XCODE_DEVELOPER_PATH}/Platforms - -# iOS 4.3 is the preferred version as it is the earliest version that is armv7/gles2 only -QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3 - -# iOS platform /Developer path -QMAKE_IOS_DEV_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer - -# Get lists of installed SDKs from Xcode -QMAKE_XCODE_SDKS = $$system($${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -showsdks) - -# No iOS SDK version specified? -isEmpty(QMAKE_IOS_SDK_VERSION) { - # Get names of installed SDKs - sdk_identifier = $$lower($$QMAKE_IOS_DEVICE_TYPE) - sdks = $$find(QMAKE_XCODE_SDKS, ^$$sdk_identifier) - for(v, sdks): { - # Extract SDK version number from output - v = $$replace(v,$$sdk_identifier,) - - # Use latest SDK version - greaterThan(v, $$QMAKE_IOS_SDK_VERSION): QMAKE_IOS_SDK_VERSION = $$v - } - - # We have at least one version of this SDK, so we choose the latest one by - # passing the SDK identifier as QMAKE_MAC_SDK, as reccomended by Apple. - QMAKE_MAC_SDK = $$sdk_identifier -} - -# No deployment target specified? -isEmpty(QMAKE_IPHONEOS_DEPLOYMENT_TARGET) { - # Use SDK version for iOS versions < preferred - lessThan(QMAKE_IOS_SDK_VERSION, $$QMAKE_IPHONEOS_PREFERRED_TARGET): \ - QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IOS_SDK_VERSION - else: \ - QMAKE_IPHONEOS_DEPLOYMENT_TARGET = $$QMAKE_IPHONEOS_PREFERRED_TARGET -} - -# Make sure iOS SDK version is >= iOS target version -!lessThan(QMAKE_IPHONEOS_DEPLOYMENT_TARGET, $$QMAKE_IOS_SDK_VERSION) { - error("Target iOS version is greater that iOS SDK version $$QMAKE_IOS_SDK_VERSION! Edit mkspecs/common/ios/versions.conf to specify target iOS version.") -} - -unset(QMAKE_IPHONEOS_PREFERRED_TARGET) -unset(QMAKE_XCODE_PLATFORM_PATH) - -# Set deployment target -QMAKE_IOS_VERSION_FLAGS = -miphoneos-version-min=$$QMAKE_IPHONEOS_DEPLOYMENT_TARGET - -# Set build flags -QMAKE_CFLAGS += $$QMAKE_IOS_VERSION_FLAGS -QMAKE_CXXFLAGS += $$QMAKE_IOS_VERSION_FLAGS -QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_IOS_VERSION_FLAGS -QMAKE_LFLAGS += $$QMAKE_IOS_VERSION_FLAGS -QMAKE_IOS_VERSION_FLAGS = diff --git a/mkspecs/common/xcode.conf b/mkspecs/common/xcode.conf new file mode 100644 index 0000000000..800e2e849c --- /dev/null +++ b/mkspecs/common/xcode.conf @@ -0,0 +1,13 @@ +# +# qmake configuration for Xcode +# + +# Get path of Xcode's Developer directory +QMAKE_XCODE_DEVELOPER_PATH = $$system(xcode-select --print-path) +isEmpty(QMAKE_XCODE_DEVELOPER_PATH): \ + error("Xcode path is not set. Please use xcode-select to choose Xcode installation path.") + +# Make sure Xcode path is valid +!exists($$QMAKE_XCODE_DEVELOPER_PATH): \ + error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.") + diff --git a/mkspecs/features/ios.prf b/mkspecs/features/ios.prf new file mode 100644 index 0000000000..841378e8dd --- /dev/null +++ b/mkspecs/features/ios.prf @@ -0,0 +1,25 @@ +isEmpty(QT_ARCH) { + # The iPhoneOS and iPhoneSimulator targets share the same toolchain, + # so when configure runs the arch tests it passes the correct sysroot, + # but we fail to pick up the architecture since we're not passing -arch + # yet. Xcode does not seem to have a way to run the shared toolchain + # in a way that will automatically do this (for example xcrun -sdk). + contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = armv7 + else: QT_ARCH = i386 # Simulator +} else { + # Fix up the QT_ARCH to be more specific + equals(QT_ARCH, arm) { + # Samsung S5PC100, Apple A4, A5, A5X + QT_ARCH = armv7 + + # FIXME: How do we support armv7s when Qt can't do universal builds? + } +} + +!equals(MAKEFILE_GENERATOR, XCODE) { + arch_flag = -arch $$QT_ARCH + QMAKE_CFLAGS += $$arch_flag + QMAKE_CXXFLAGS += $$arch_flag + QMAKE_OBJECTIVE_CFLAGS += $$arch_flag + QMAKE_LFLAGS += $$arch_flag +} diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 4c3e2d2b5a..57dcf7f5eb 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -36,7 +36,15 @@ } !equals(MAKEFILE_GENERATOR, XCODE) { - version_min_flag = -m$${QMAKE_MAC_PLATFORM_NAME}-version-min=$$QMAKE_MACOSX_DEPLOYMENT_TARGET + # FIXME: Get the version_min_flag out of the platform's 'Native Build System.xcspec' + version_identifier = $$replace(QMAKE_MAC_PLATFORM_NAME, iphonesimulator, ios-simulator) + + ios:!host_build: \ + deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET + else: \ + deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET + + version_min_flag = -m$${version_identifier}-version-min=$$deployment_target QMAKE_CFLAGS += $$version_min_flag QMAKE_CXXFLAGS += $$version_min_flag QMAKE_OBJECTIVE_CFLAGS += $$version_min_flag diff --git a/mkspecs/unsupported/macx-ios-clang/qmake.conf b/mkspecs/unsupported/macx-ios-clang/qmake.conf new file mode 100644 index 0000000000..8f176f3f83 --- /dev/null +++ b/mkspecs/unsupported/macx-ios-clang/qmake.conf @@ -0,0 +1,30 @@ +# +# qmake configuration for macx-ios-clang +# + +!load(device_config): error("Could not successfully load device configuration.") + +isEmpty(QMAKE_MAC_SDK): QMAKE_MAC_SDK = iphoneos + +# iOS is considered a variant of MacOS by Apple. We follow this to +# keep things simple, e.g. by defining Q_OS_MAC _and_ Q_OS_IOS. +include(../../common/mac.conf) + +include(../../common/gcc-base-ios.conf) +include(../../common/xcode.conf) +include(../../common/clang.conf) +include(../../common/clang-mac.conf) + +# Extract Xcode version using xcodebuild +version_info = $$system("$${QMAKE_XCODE_DEVELOPER_PATH}/usr/bin/xcodebuild -version") +QMAKE_IOS_XCODE_VERSION = $$member(version_info, 1) +unset(version_info) + +# Version check +lessThan(QMAKE_IOS_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later") + +include(../../common/ios.conf) +include(../../common/ios/clang.conf) +include(../../common/ios/qmake.conf) + +load(qt_config) diff --git a/mkspecs/unsupported/macx-ios-clang/qplatformdefs.h b/mkspecs/unsupported/macx-ios-clang/qplatformdefs.h new file mode 100644 index 0000000000..5f80a17860 --- /dev/null +++ b/mkspecs/unsupported/macx-ios-clang/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf b/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf deleted file mode 100644 index 3e1a669905..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-clang/qmake.conf +++ /dev/null @@ -1,22 +0,0 @@ -# -# qmake configuration for ios-device-clang -# - -QMAKE_IOS_DEVICE_TYPE = iPhoneOS - -# Samsung S5PC100, Apple A4, A5, A5X -QMAKE_IOS_TARGET_ARCH = armv7 - -# FIXME: Add armv7s (A6) support when we need it - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/clang.conf) -include(../../common/clang-mac.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/clang.conf) -include(../../common/ios/qmake.conf) -include(../../common/ios/arch.conf) - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iosdevice-clang/qplatformdefs.h b/mkspecs/unsupported/macx-iosdevice-clang/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iosdevice-clang/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" diff --git a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf b/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf deleted file mode 100644 index a8072fed00..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-clang/qmake.conf +++ /dev/null @@ -1,23 +0,0 @@ -# -# qmake configuration for ios-simulator-clang -# - -QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator - -# Simulator is i386 only -QMAKE_IOS_TARGET_ARCH = i386 - -QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks -QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch - -include(../../common/mac.conf) -include(../../common/gcc-base-ios.conf) -include(../../common/clang.conf) -include(../../common/clang-mac.conf) -include(../../common/ios.conf) -include(../../common/ios/versions.conf) -include(../../common/ios/clang.conf) -include(../../common/ios/qmake.conf) -include(../../common/ios/arch.conf) - -load(qt_config) diff --git a/mkspecs/unsupported/macx-iossimulator-clang/qplatformdefs.h b/mkspecs/unsupported/macx-iossimulator-clang/qplatformdefs.h deleted file mode 100644 index 5f80a17860..0000000000 --- a/mkspecs/unsupported/macx-iossimulator-clang/qplatformdefs.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../../common/ios/qplatformdefs.h" -- cgit v1.2.3 From 77168c03ffb2d8eeef231766e4322601495778c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 23 Nov 2012 13:26:50 +0100 Subject: iOS: Make Xcode output the default for GUI applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As long as Qt Creator does not provide any iOS integration, and the app bundle we create using the Makefile generator is not good enough to deploy to a device anyways, producing Xcode projects make the most sense. We base the decicion on whether or not the project depends on QtGui and has app_bundles enabled. This prevents configure tests and other tools from having Xcode projects, but allows examples and demos to build out of the box. Instead of setting the generator unconditionally we unset it in default_pre so that we can detect if the user set it manually. This means the user won't be able to inspect the MAKEFILE_GENERATOR variable from the pro file, but this is less of a use-case then overriding the generator from the command line or prooject file. Change-Id: I881cf3e29631445f83ea4ff0979f7a566e4810f5 Reviewed-by: Morten Johan Sørvig Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios.conf | 6 +++--- mkspecs/features/ios/default_post.prf | 13 +++++++++++++ mkspecs/features/ios/default_pre.prf | 4 ++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 mkspecs/features/ios/default_post.prf create mode 100644 mkspecs/features/ios/default_pre.prf diff --git a/mkspecs/common/ios.conf b/mkspecs/common/ios.conf index 0d68d37ff8..4c1c1f093d 100644 --- a/mkspecs/common/ios.conf +++ b/mkspecs/common/ios.conf @@ -3,11 +3,11 @@ # MAKEFILE_GENERATOR = UNIX -CONFIG += ios reduce_exports incremental global_init_link_order lib_version_first plugin_no_soname sdk +CONFIG += app_bundle reduce_exports incremental global_init_link_order lib_version_first plugin_no_soname sdk QMAKE_INCREMENTAL_STYLE = sublib -# Qt can't build iOS app bundle :( -CONFIG -= app_bundle +# FIXME: Transform ios.conf to follow the same inheritance pattern as eg mac.conf and unix.conf +QMAKE_PLATFORM = ios $$QMAKE_PLATFORM # Not deploying to Mac OSX QMAKE_MACOSX_DEPLOYMENT_TARGET = diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf new file mode 100644 index 0000000000..3e9d12be3b --- /dev/null +++ b/mkspecs/features/ios/default_post.prf @@ -0,0 +1,13 @@ + +CONFIG(qt):contains(QT, gui):equals(TEMPLATE, app): CONFIG += gui_app + +isEmpty(MAKEFILE_GENERATOR) { + gui_app:app_bundle: \ + # For applications we want Xcode project files + MAKEFILE_GENERATOR = XCODE + else: \ + # For libs, etc we still want regular Makefiles + MAKEFILE_GENERATOR = UNIX +} + +load(default_post) diff --git a/mkspecs/features/ios/default_pre.prf b/mkspecs/features/ios/default_pre.prf new file mode 100644 index 0000000000..e2956bd77d --- /dev/null +++ b/mkspecs/features/ios/default_pre.prf @@ -0,0 +1,4 @@ +# Unset makefile generator, so we can auto-detect value in default_post +unset(MAKEFILE_GENERATOR) + +load(default_pre) -- cgit v1.2.3 From 5b99d46b3985b435fbf4b786a4abaf77714711d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 14:06:25 +0100 Subject: iOS: Link to the platform plugin and iosmain plugin and define main Ideally we'd only have to do QTPLUGIN += ios, but this doesn't work as we need to link with the force_load linker option. Even trying to build on QTPLUGIN and then replace the -l line with what we need will fail, as the prl logic in qmake which runs after all the prf files does not know about the force_load option and will then fail to resolve dependencies from the prl file. Since we load the platform plugin using -force_load, there's no need to generate a cpp file that does the plugin import. The main wrapper is not a real Qt plugin, and doesn't have an import function that we can call, so we link it manually instead of relying on QTPLUGIN. Change-Id: I0381a3c9ed7f8d41a4121e1fc0b7c0e210a8b832 Reviewed-by: Richard Moe Gustavsen --- mkspecs/features/ios/default_post.prf | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf index 3e9d12be3b..6c6d8d89ce 100644 --- a/mkspecs/features/ios/default_post.prf +++ b/mkspecs/features/ios/default_post.prf @@ -10,4 +10,26 @@ isEmpty(MAKEFILE_GENERATOR) { MAKEFILE_GENERATOR = UNIX } +gui_app { + # We have to do the link and dependency resolution for the platform plugin + # manually, since QTPLUGIN and the prl lookup logic does not support + # the -force_load link style. The -force_load option ensures that all + # symbols from the static library are included, not just the ones the + # linker have seen a use for so far. We need this because we load the platform + # plugin from the platform plugin itself, using Q_IMPORT_PLUGIN. + lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/libqios$$qtPlatformTargetSuffix() + LIBS += "-force_load $${lib_path_and_base}.$${QMAKE_EXTENSION_STATICLIB}" + LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) + + # Which means we don't want the auto-generated import for the platform plugin + CONFIG -= import_qpa_plugin + + # We link the iosmain library manually as well, since it's not really a plugin + lib_name = qiosmain + lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() + LIBS += -L$$[QT_INSTALL_PLUGINS/get]/platforms -l$${lib_name}$$qtPlatformTargetSuffix() + LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) + DEFINES += main=qt_main +} + load(default_post) -- cgit v1.2.3 From e846edff33ecbd3fc5f4206febc01265ef916d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Feb 2013 13:36:21 +0100 Subject: iOS: Allow projects to disable the main wrapper In case they provide their own main that calls UIApplicationMain. Change-Id: Ia050277ae5cbcbf01bc57b87ec37a74db9568059 Reviewed-by: Richard Moe Gustavsen --- mkspecs/features/ios/default_post.prf | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf index 6c6d8d89ce..e4221e4b65 100644 --- a/mkspecs/features/ios/default_post.prf +++ b/mkspecs/features/ios/default_post.prf @@ -24,12 +24,14 @@ gui_app { # Which means we don't want the auto-generated import for the platform plugin CONFIG -= import_qpa_plugin - # We link the iosmain library manually as well, since it's not really a plugin - lib_name = qiosmain - lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() - LIBS += -L$$[QT_INSTALL_PLUGINS/get]/platforms -l$${lib_name}$$qtPlatformTargetSuffix() - LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) - DEFINES += main=qt_main + !no_main_wrapper { + # We link the iosmain library manually as well, since it's not really a plugin + lib_name = qiosmain + lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() + LIBS += -L$$[QT_INSTALL_PLUGINS/get]/platforms -l$${lib_name}$$qtPlatformTargetSuffix() + LIBS += $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) + DEFINES += main=qt_main + } } load(default_post) -- cgit v1.2.3 From 5da648043df5b2e8ccfa720ee56b04dea47c0601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 15:29:05 +0100 Subject: iOS: Target both iPhone and iPad by default Change-Id: I3122b9391c6187da17389c889a456c58210dca09 Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios.conf | 3 +++ mkspecs/features/ios/default_post.prf | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/mkspecs/common/ios.conf b/mkspecs/common/ios.conf index 4c1c1f093d..5ff2f9b416 100644 --- a/mkspecs/common/ios.conf +++ b/mkspecs/common/ios.conf @@ -20,3 +20,6 @@ INCLUDEPATH += $$PWD/ios # iOS defines DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG + +# Universal target (iPhone and iPad) +QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2 diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/features/ios/default_post.prf index e4221e4b65..f5e7b3c02d 100644 --- a/mkspecs/features/ios/default_post.prf +++ b/mkspecs/features/ios/default_post.prf @@ -34,4 +34,10 @@ gui_app { } } +contains(MAKEFILE_GENERATOR, XCODE) { + ios_device_family.name = TARGETED_DEVICE_FAMILY + ios_device_family.value = $$QMAKE_IOS_TARGETED_DEVICE_FAMILY + QMAKE_MAC_XCODE_SETTINGS += ios_device_family +} + load(default_post) -- cgit v1.2.3 From a6286039babdd3680124c9449d14911ed29b2295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 21 Nov 2012 14:49:47 +0100 Subject: iOS: Write default code signing identify for iOS in Xcode generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic04da6063863585665c9133caba0279ba478fbb4 Reviewed-by: Oswald Buddenhagen Reviewed-by: Ian Dean Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/qmake.conf | 2 ++ qmake/generators/mac/pbuilder_pbx.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 2a8d64fd9f..1a0748873b 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -7,6 +7,8 @@ QMAKE_XCODE_TOOLCHAIN_BIN_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin +QMAKE_XCODE_CODE_SIGN_IDENTITY = "iPhone Developer" + # iOS build tools QMAKE_CC = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/clang QMAKE_CXX = $$QMAKE_XCODE_TOOLCHAIN_BIN_PATH/clang++ diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 41af3d2a53..923639d89d 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1355,6 +1355,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if (!project->isEmpty("QMAKE_IOS_DEPLOYMENT_TARGET")) t << "\t\t\t\t" << writeSettings("IPHONEOS_DEPLOYMENT_TARGET", project->first("QMAKE_IOS_DEPLOYMENT_TARGET")) << ";" << "\n"; + if (!project->isEmpty("QMAKE_XCODE_CODE_SIGN_IDENTITY")) + t << "\t\t\t\t" << writeSettings("CODE_SIGN_IDENTITY", project->first("QMAKE_XCODE_CODE_SIGN_IDENTITY")) << ";" << "\n"; + tmp = project->values("QMAKE_PBX_VARS"); for (int i = 0; i < tmp.count(); i++) { QString var = tmp[i].toQString(), val = QString::fromLocal8Bit(qgetenv(var.toLatin1().constData())); -- cgit v1.2.3 From e5111d5e021e8168fa9deb00abae5c403a5313e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:11:35 +0100 Subject: iOS: Build ios platform plugin when appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defining QT_QPA_DEFAULT_PLATFORM_NAME in qplatformdefs.h is not neccecary, as qconfig.h will already have this define written by configure. Change-Id: I89d9191533f6b4e6bfd5eade6cc0dced02b50f81 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/qmake.conf | 2 ++ mkspecs/common/mac/qplatformdefs.h | 2 -- src/plugins/platforms/platforms.pro | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mkspecs/common/ios/qmake.conf b/mkspecs/common/ios/qmake.conf index 1a0748873b..5164c48e12 100644 --- a/mkspecs/common/ios/qmake.conf +++ b/mkspecs/common/ios/qmake.conf @@ -5,6 +5,8 @@ # # QMAKE_XCODE_DEVELOPER_PATH - set in mkspecs/common/xcode.conf +QT_QPA_DEFAULT_PLATFORM = ios + QMAKE_XCODE_TOOLCHAIN_BIN_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin QMAKE_XCODE_CODE_SIGN_IDENTITY = "iPhone Developer" diff --git a/mkspecs/common/mac/qplatformdefs.h b/mkspecs/common/mac/qplatformdefs.h index 7d4b6a2427..7ee337cce4 100644 --- a/mkspecs/common/mac/qplatformdefs.h +++ b/mkspecs/common/mac/qplatformdefs.h @@ -42,8 +42,6 @@ #ifndef QPLATFORMDEFS_H #define QPLATFORMDEFS_H -#define QT_QPA_DEFAULT_PLATFORM_NAME "cocoa" - // Get Qt defines/settings #include "qglobal.h" diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 173757568f..a60a3626fa 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -6,7 +6,10 @@ contains(QT_CONFIG, xcb) { SUBDIRS += xcb } -mac:!ios: SUBDIRS += cocoa +mac { + ios: SUBDIRS += ios + else: SUBDIRS += cocoa +} win32: SUBDIRS += windows -- cgit v1.2.3 From f2168f2688d44ccb604d761fdbe199c69de0dcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 16:31:06 +0100 Subject: iOS: Build platform plugin like other platform plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... by loading(qt_plugin) Change-Id: I9be438b72be986a991a81c2cf1a3e5047bcf0a60 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 39f72e9719..66af44cbe8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,6 +1,7 @@ TARGET = qios -include(../../qpluginbase.pri) -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms + +load(qt_plugin) +DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private @@ -21,7 +22,5 @@ OBJECTIVE_HEADERS = qiosintegration.h \ #HEADERS = qiossoftwareinputhandler.h -#include(../fontdatabases/coretext/coretext.pri) - target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target -- cgit v1.2.3 From cb25d67f01d129d877ffb56d15f7c5e32f4955ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 22:30:37 +0100 Subject: iOS: Don't link ios platform plugin to Cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2348b19617d3e342cd344bf7d0fa894118cbfae8 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 66af44cbe8..d274fda8bd 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework Cocoa -framework UIKit +LIBS += -framework UIKit OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From 8716c42ee2a3d5ca42eab5850f711fd5feabb9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 1 Nov 2012 23:01:56 +0100 Subject: iOS: Add missing QuartzCore dependency to platform plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic69a5a7faa9b7f9907d0325260b6b6e2389a4c3a Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index d274fda8bd..2cc730f061 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -5,7 +5,7 @@ DESTDIR = $$QT.gui.plugins/platforms QT += opengl QT += core-private gui-private platformsupport-private opengl-private widgets-private -LIBS += -framework UIKit +LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ qiosintegration.mm \ -- cgit v1.2.3 From f6dc54ded4957f7afdbed9f84516099b067648ff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 10:09:31 +0100 Subject: iOS: network should not link against CoreServices on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia3e21a3d73f696f0e77c427bdb263333646c48d3 Reviewed-by: Tor Arne Vestbø --- src/network/kernel/kernel.pri | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 57df8c8bc8..580e0b31b3 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -39,7 +39,11 @@ win32: { } integrity:SOURCES += kernel/qdnslookup_unix.cpp kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp -mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation -framework CoreServices +mac { + LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation + !ios: LIBS_PRIVATE += -framework CoreServices +} + mac:!ios:SOURCES += kernel/qnetworkproxy_mac.cpp else:win32:SOURCES += kernel/qnetworkproxy_win.cpp else:blackberry:SOURCES += kernel/qnetworkproxy_blackberry.cpp -- cgit v1.2.3 From c7fbff7bf255f9fc0123f37fc475bd8ae8cf38e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 4 Dec 2012 15:50:49 +0100 Subject: iOS: Add required public dependencies of the CoreText font database CoreText and CoreGraphics are available on iOS as stand-alone frameworks, but on Mac OS X they are part of the ApplicationServices umbrella framework. Mac OS 10.8 actually introduced both as stand-alone frameworks, but for simplicity we link to ApplicationServices, as there's still symlinks from ApplicationServices to the real frameworks. Change-Id: I7f7ef795629cc37da85857d5c42283754acc4474 Reviewed-by: Richard Moe Gustavsen --- src/platformsupport/fontdatabases/mac/coretext.pri | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri index f7977964fe..d1abf123aa 100644 --- a/src/platformsupport/fontdatabases/mac/coretext.pri +++ b/src/platformsupport/fontdatabases/mac/coretext.pri @@ -1,2 +1,10 @@ HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm + +ios: \ + # On iOS CoreText and CoreGraphics are stand-alone frameworks + LIBS += -framework CoreText -framework CoreGraphics +else: \ + # On Mac OS they are part of the ApplicationServices umbrella framework, + # even in 10.8 where they were also made available stand-alone. + LIBS += -framework ApplicationServices -- cgit v1.2.3 From 8c0014907893e0ac7c0b0c33d54415830f36ddaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2012 16:46:29 +0100 Subject: iOS: Don't include QtPrintSupport dialogs on iOS It pulls in a dependency on Cocoa. Change-Id: I293063adfdef8b92f80ffda0c66ac6e6d12958ff Reviewed-by: Richard Moe Gustavsen --- src/printsupport/dialogs/dialogs.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/dialogs/dialogs.pri b/src/printsupport/dialogs/dialogs.pri index 9db975e202..9659046f60 100644 --- a/src/printsupport/dialogs/dialogs.pri +++ b/src/printsupport/dialogs/dialogs.pri @@ -8,7 +8,7 @@ HEADERS += \ dialogs/qprintdialog.h \ dialogs/qprintpreviewdialog.h -mac { +mac:!ios { OBJECTIVE_SOURCES += dialogs/qpagesetupdialog_mac.mm \ dialogs/qprintdialog_mac.mm LIBS += -framework Cocoa -- cgit v1.2.3 From 9c8ce6afb0bb19e0cb5902b65efbd1a1b55344eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 2 Nov 2012 15:44:46 +0100 Subject: iOS: Don't add to OBJECTIVE_HEADERS, there's no such thing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should add to HEADERS, so that moc will realize it needs to run on the headers. Change-Id: I582e989e4faf0835c4bf9a677cbd8ac075559319 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/ios.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2cc730f061..c6c104f2f3 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -14,7 +14,7 @@ OBJECTIVE_SOURCES = main.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm -OBJECTIVE_HEADERS = qiosintegration.h \ +HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ -- cgit v1.2.3 From 3020d06fdb9fd4e539876c9fb1945b50d55cc21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 17:19:09 +0100 Subject: iOS: Change member variable style to be consistent with Qt's de facto standard Change-Id: Idd65ad9cbb77114466c5b69a799b98a7fee5068f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.h | 2 +- src/plugins/platforms/ios/qiosbackingstore.mm | 12 +- src/plugins/platforms/ios/qiosintegration.h | 4 +- src/plugins/platforms/ios/qiosintegration.mm | 8 +- .../platforms/ios/qiossoftwareinputhandler.h | 6 +- src/plugins/platforms/ios/qioswindow.h | 26 +-- src/plugins/platforms/ios/qioswindow.mm | 186 ++++++++++----------- 7 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index cb0e9cbedb..d83a5c21ad 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -57,7 +57,7 @@ public: void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *mPaintDevice; + QPaintDevice *m_paintDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 32ddce38d2..20f7c1f2d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -63,7 +63,7 @@ class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), mWindow(window) + :QGLPaintDevice(), m_window(window) { #if defined(QT_OPENGL_ES_2) helper = [[PaintDeviceHelper alloc] init]; @@ -83,17 +83,17 @@ public: void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } - QSize size() const { return mWindow->geometry().size(); } + QSize size() const { return m_window->geometry().size(); } QGLContext* context() const { // Todo: siplify this: return QGLContext::fromOpenGLContext( - static_cast(mWindow->handle())->glContext()->context()); + static_cast(m_window->handle())->glContext()->context()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } private: - QWindow *mWindow; + QWindow *m_window; PaintDeviceHelper *helper; }; @@ -112,13 +112,13 @@ private: QT_BEGIN_NAMESPACE QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), mPaintDevice(new EAGLPaintDevice(window)) + : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) { } QPaintDevice *QIOSBackingStore::paintDevice() { - return mPaintDevice; + return m_paintDevice; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index b71379e417..f44403fbba 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -65,8 +65,8 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList mScreens; - QPlatformFontDatabase *mFontDb; + QList m_screens; + QPlatformFontDatabase *m_fontDb; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index bd63384004..98b08ed72a 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -59,11 +59,11 @@ QIOSIntegration * QIOSIntegration::instance() } QIOSIntegration::QIOSIntegration() - :mFontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase) { if (!m_instance) m_instance = this; - mScreens << new QIOSScreen(0); + m_screens << new QIOSScreen(0); } QIOSIntegration::~QIOSIntegration() @@ -85,7 +85,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const QList QIOSIntegration::screens() const { - return mScreens; + return m_screens; } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const @@ -100,7 +100,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return mFontDb; + return m_fontDb; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index bbad656b93..99e8fac61b 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -55,7 +55,7 @@ class QIOSSoftwareInputHandler : public QObject Q_OBJECT public: - QIOSSoftwareInputHandler() : mCurrentFocusWidget(0), mCurrentFocusObject(0) {} + QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {} bool eventFilter(QObject *obj, QEvent *event); private slots: @@ -64,8 +64,8 @@ private slots: private: bool closeSoftwareInputPanel(QWidget *widget); - QPointer mCurrentFocusWidget; - QPointer mCurrentFocusObject; + QPointer m_currentFocusWidget; + QPointer m_currentFocusObject; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index f43f3db4f9..2d3d5b072f 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -53,13 +53,13 @@ @interface EAGLView : UIView { - QPlatformWindow *mWindow; - EAGLContext *mContext; + QPlatformWindow *m_window; + EAGLContext *m_context; - GLint mFramebufferWidth; - GLint mFramebufferHeight; + GLint m_framebufferWidth; + GLint m_framebufferHeight; - GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; id delegate; // ------- Text Input ---------- @@ -111,23 +111,23 @@ public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return mWindow; } - EAGLView *nativeView() const { return mView; } + UIWindow *nativeWindow() const { return m_window; } + EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); QPlatformOpenGLContext *glContext() const; - QIOSScreen *platformScreen() const { return mScreen; } + QIOSScreen *platformScreen() const { return m_screen; } void updateGeometryAndOrientation(); private: - QIOSScreen *mScreen; - UIWindow *mWindow; - CGRect mFrame; - EAGLView *mView; - mutable EAGLPlatformContext *mContext; + QIOSScreen *m_screen; + UIWindow *m_window; + CGRect m_frame; + EAGLView *m_view; + mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c63c22dbaa..28aaaf2189 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -75,7 +75,7 @@ class EAGLPlatformContext : public QPlatformOpenGLContext { public: EAGLPlatformContext(EAGLView *view) - : mView(view) + : m_view(view) { /* mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); @@ -103,7 +103,7 @@ public: #else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; #endif - [mView setContext:aContext]; + [m_view setContext:aContext]; } ~EAGLPlatformContext() { } @@ -113,7 +113,7 @@ public: Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; //QPlatformOpenGLContext::makeCurrent(); - //[mView makeCurrent]; + //[m_view makeCurrent]; return false; } @@ -127,7 +127,7 @@ public: { Q_UNUSED(surface); qDebug() << __FUNCTION__ << "not implemented"; - //[mView presentFramebuffer]; + //[m_view presentFramebuffer]; } QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } @@ -138,7 +138,7 @@ public: } private: - EAGLView *mView; + EAGLView *m_view; QSurfaceFormat mFormat; }; @@ -174,97 +174,97 @@ private: - (void)setContext:(EAGLContext *)newContext { - if (mContext != newContext) + if (m_context != newContext) { [self deleteFramebuffer]; - [mContext release]; - mContext = [newContext retain]; + [m_context release]; + m_context = [newContext retain]; [EAGLContext setCurrentContext:nil]; } } - (void)presentFramebuffer { - if (mContext) { - [EAGLContext setCurrentContext:mContext]; - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER]; + if (m_context) { + [EAGLContext setCurrentContext:m_context]; + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context presentRenderbuffer:GL_RENDERBUFFER]; } } - (void)deleteFramebuffer { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (mFramebuffer) { - glDeleteFramebuffers(1, &mFramebuffer); - mFramebuffer = 0; + [EAGLContext setCurrentContext:m_context]; + if (m_framebuffer) { + glDeleteFramebuffers(1, &m_framebuffer); + m_framebuffer = 0; } - if (mColorRenderbuffer) { - glDeleteRenderbuffers(1, &mColorRenderbuffer); - mColorRenderbuffer = 0; + if (m_colorRenderbuffer) { + glDeleteRenderbuffers(1, &m_colorRenderbuffer); + m_colorRenderbuffer = 0; } - if (mDepthRenderbuffer) { - glDeleteRenderbuffers(1, &mDepthRenderbuffer); - mDepthRenderbuffer = 0; + if (m_depthRenderbuffer) { + glDeleteRenderbuffers(1, &m_depthRenderbuffer); + m_depthRenderbuffer = 0; } } } - (void)createFramebuffer { - if (mContext && !mFramebuffer) + if (m_context && !m_framebuffer) { - [EAGLContext setCurrentContext:mContext]; - glGenFramebuffers(1, &mFramebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - - glGenRenderbuffers(1, &mColorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); - - glGenRenderbuffers(1, &mDepthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + [EAGLContext setCurrentContext:m_context]; + glGenFramebuffers(1, &m_framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + + glGenRenderbuffers(1, &m_colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); + [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); + + glGenRenderbuffers(1, &m_depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mFramebufferWidth, mFramebufferHeight); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:mFramebuffer]; + [delegate eaglView:self usesFramebuffer:m_framebuffer]; } } } - (void)makeCurrent { - if (mContext) + if (m_context) { - [EAGLContext setCurrentContext:mContext]; - if (!mFramebuffer) + [EAGLContext setCurrentContext:m_context]; + if (!m_framebuffer) [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); + glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); + glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); } } - (GLint)fbo { - return mFramebuffer; + return m_framebuffer; } - (void)setWindow:(QPlatformWindow *)window { - mWindow = window; + m_window = window; } - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons @@ -274,7 +274,7 @@ private: CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(mWindow->window(), (ulong)(event.timestamp*1000), + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); } @@ -347,18 +347,18 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window), - mWindow(nil), - mContext(0) + m_window(nil), + m_context(0) { - mScreen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - mView = [[EAGLView alloc] init]; + m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); + m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete mContext; mContext = 0; - [mView release]; - [mWindow release]; + delete m_context; m_context = 0; + [m_view release]; + [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) @@ -369,81 +369,81 @@ void QIOSWindow::setGeometry(const QRect &rect) UIWindow *QIOSWindow::ensureNativeWindow() { - if (!mWindow) { - mWindow = [[UIWindow alloc] init]; + if (!m_window) { + m_window = [[UIWindow alloc] init]; updateGeometryAndOrientation(); // window - mWindow.screen = mScreen->uiScreen(); + m_window.screen = m_screen->uiScreen(); // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - mWindow.frame = mFrame; + m_window.frame = m_frame; // view - [mView deleteFramebuffer]; - mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill - [mView setContentScaleFactor:[mWindow.screen scale]]; - [mView setMultipleTouchEnabled:YES]; - [mView setWindow:this]; - [mWindow addSubview:mView]; - [mWindow setNeedsDisplay]; - [mWindow makeKeyAndVisible]; + [m_view deleteFramebuffer]; + m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill + [m_view setContentScaleFactor:[m_window.screen scale]]; + [m_view setMultipleTouchEnabled:YES]; + [m_view setWindow:this]; + [m_window addSubview:m_view]; + [m_window setNeedsDisplay]; + [m_window makeKeyAndVisible]; } - return mWindow; + return m_window; } void QIOSWindow::updateGeometryAndOrientation() { - if (!mWindow) + if (!m_window) return; - mFrame = [mScreen->uiScreen() applicationFrame]; - CGRect screen = [mScreen->uiScreen() bounds]; + m_frame = [m_screen->uiScreen() applicationFrame]; + CGRect screen = [m_screen->uiScreen() bounds]; QRect geom; CGFloat angle = 0; switch ([[UIApplication sharedApplication] statusBarOrientation]) { case UIInterfaceOrientationPortrait: - geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); break; case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, - screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.size.width, - mFrame.size.height); + geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, + screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.size.width, + m_frame.size.height); angle = M_PI; break; case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, - mFrame.origin.x, - mFrame.size.height, - mFrame.size.width); + geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, + m_frame.origin.x, + m_frame.size.height, + m_frame.size.width); angle = -M_PI/2.; break; case UIInterfaceOrientationLandscapeRight: - geom = QRect(mFrame.origin.y, - screen.size.width - mFrame.origin.x - mFrame.size.width, - mFrame.size.height, - mFrame.size.width); + geom = QRect(m_frame.origin.y, + screen.size.width - m_frame.origin.x - m_frame.size.width, + m_frame.size.height, + m_frame.size.width); angle = +M_PI/2.; break; } - CGFloat scale = [mScreen->uiScreen() scale]; + CGFloat scale = [m_screen->uiScreen() scale]; geom = QRect(geom.x() * scale, geom.y() * scale, geom.width() * scale, geom.height() * scale); if (angle != 0) { - [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); } else { - [mView layer].transform = CATransform3DIdentity; + [m_view layer].transform = CATransform3DIdentity; } - [mView setNeedsDisplay]; + [m_view setNeedsDisplay]; window()->setGeometry(geom); } QPlatformOpenGLContext *QIOSWindow::glContext() const { - if (!mContext) { - mContext = new EAGLPlatformContext(mView); + if (!m_context) { + m_context = new EAGLPlatformContext(m_view); } - return mContext; + return m_context; } QT_END_NAMESPACE -- cgit v1.2.3 From 6d36a83b419e0b0bc0270e45983ed2bbfa453996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 18:56:45 +0100 Subject: iOS: Get rid of singleton instance accessor in platform plugin None of the other platform plugins have one, and it's not used anywhere. Change-Id: Id46ab5f75c9819511c3e9d123d0338c3c8799869 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 -- src/plugins/platforms/ios/qiosintegration.mm | 9 --------- 2 files changed, 11 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index f44403fbba..ef839a89b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -52,8 +52,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - static QIOSIntegration *instance(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 98b08ed72a..1b03b410cb 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -51,18 +51,9 @@ QT_BEGIN_NAMESPACE -static QIOSIntegration *m_instance = 0; - -QIOSIntegration * QIOSIntegration::instance() -{ - return m_instance; -} - QIOSIntegration::QIOSIntegration() :m_fontDb(new QCoreTextFontDatabase) { - if (!m_instance) - m_instance = this; m_screens << new QIOSScreen(0); } -- cgit v1.2.3 From 14e93f7e8e0ef58b0e47bfe277d52b2fa8f24ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:01:44 +0100 Subject: iOS: Add screen like other platform plugins We may add support for external displays at a later point, but for now we follow the same pattern as the other platform plugins. Either way we should call screenAdded() to let the platform integration know about the screen. Change-Id: Id01785a5262df0180caf957c7de8ecbbf169f233 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 4 +--- src/plugins/platforms/ios/qiosintegration.mm | 9 ++------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index ef839a89b0..8b2ac70a9f 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -56,15 +56,13 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QList screens() const; - QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QList m_screens; QPlatformFontDatabase *m_fontDb; + QPlatformScreen *m_screen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 1b03b410cb..68a9bf343f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,9 +52,9 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) { - m_screens << new QIOSScreen(0); + screenAdded(m_screen); } QIOSIntegration::~QIOSIntegration() @@ -74,11 +74,6 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } -QList QIOSIntegration::screens() const -{ - return m_screens; -} - QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { return new QIOSBackingStore(window); -- cgit v1.2.3 From 5e85aa9ab4c30c123de6431679d3870a4b7836c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:39:45 +0100 Subject: iOS: Keep UIScreen* for current QIOSScreen instead of looking up each time Also, add enum for screen numbers, for better code readability. Change-Id: Id5162c34e80ff5efb149ae86b49f51df183d1c1d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qiosscreen.h | 7 ++++--- src/plugins/platforms/ios/qiosscreen.mm | 12 ++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 68a9bf343f..7a6dec43d4 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(0)) + :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 628d764f53..98771b9ac2 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -51,9 +51,11 @@ QT_BEGIN_NAMESPACE class QIOSScreen : public QPlatformScreen { public: - QIOSScreen(int screenIndex); + QIOSScreen(unsigned int screenIndex); ~QIOSScreen(); + enum ScreenIndex { MainScreen = 0 }; + QRect geometry() const { return m_geometry; } int depth() const { return m_depth; } QImage::Format format() const { return m_format; } @@ -63,14 +65,13 @@ public: void updateInterfaceOrientation(); private: + UIScreen *m_uiScreen; QRect m_geometry; int m_depth; QImage::Format m_format; QSize m_physicalSize; - int m_index; }; QT_END_NAMESPACE - #endif diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5d9841734a..64b9022a29 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE -QIOSScreen::QIOSScreen(int screenIndex) - : QPlatformScreen(), - m_index(screenIndex) +QIOSScreen::QIOSScreen(unsigned int screenIndex) + : QPlatformScreen() + , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; + CGRect bounds = [m_uiScreen bounds]; + CGFloat scale = [m_uiScreen scale]; updateInterfaceOrientation(); m_format = QImage::Format_ARGB32_Premultiplied; @@ -87,7 +87,7 @@ QIOSScreen::~QIOSScreen() UIScreen *QIOSScreen::uiScreen() const { - return [[UIScreen screens] objectAtIndex:m_index]; + return m_uiScreen; } void QIOSScreen::updateInterfaceOrientation() -- cgit v1.2.3 From 422eed16eb22772357aab06feb12c59f5d188b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 19:43:57 +0100 Subject: iOS: Style nitpicking, rename m_fontDb to m_fontDatabase Change-Id: I9d92843af9018d51b73fadcc7c20d792fad772fa Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 2 +- src/plugins/platforms/ios/qiosintegration.mm | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 8b2ac70a9f..d744cf377a 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -61,7 +61,7 @@ public: QAbstractEventDispatcher *guiThreadEventDispatcher() const; private: - QPlatformFontDatabase *m_fontDb; + QPlatformFontDatabase *m_fontDatabase; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 7a6dec43d4..d3e9572f83 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -52,7 +52,8 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() - :m_fontDb(new QCoreTextFontDatabase), m_screen(new QIOSScreen(QIOSScreen::MainScreen)) + : m_fontDatabase(new QCoreTextFontDatabase) + , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { screenAdded(m_screen); } @@ -86,7 +87,7 @@ QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const QPlatformFontDatabase * QIOSIntegration::fontDatabase() const { - return m_fontDb; + return m_fontDatabase; } QT_END_NAMESPACE -- cgit v1.2.3 From a685df05841a3dd45095e40ca0f40ab796bfc86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 21:59:00 +0100 Subject: iOS: Add ability to get the UIView for a QWindow through QPlatformNativeInterface Change-Id: Iab2742bbaa97ff345871ad07ef0162b12248506a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 6 +++++- src/plugins/platforms/ios/qiosintegration.mm | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d744cf377a..d72eefa1fa 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -43,10 +43,11 @@ #define QPLATFORMINTEGRATION_UIKIT_H #include +#include QT_BEGIN_NAMESPACE -class QIOSIntegration : public QPlatformIntegration +class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface { public: QIOSIntegration(); @@ -59,6 +60,9 @@ public: QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; + QPlatformNativeInterface *nativeInterface() const; + + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); private: QPlatformFontDatabase *m_fontDatabase; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d3e9572f83..0c876bf1b2 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -90,4 +90,24 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformNativeInterface *QIOSIntegration::nativeInterface() const +{ + return const_cast(this); +} + +void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window) +{ + if (!window || !window->handle()) + return 0; + + QByteArray lowerCaseResource = resource.toLower(); + + QIOSWindow *platformWindow = static_cast(window->handle()); + + if (lowerCaseResource == "uiview") + return platformWindow->nativeView(); + + return 0; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 145abdc4429f636b365ce6ebd51f81e216bc7fa3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 10:53:59 +0100 Subject: iOS: QIOSEventDispatcher: add runloop source for processing events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6cd649a493dab9a982d71921f19d2a9252fc14b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 9 +++- src/plugins/platforms/ios/qioseventdispatcher.mm | 61 +++++++++++++++++++++--- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 479ec1d0a0..db3eb85ffc 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include QT_BEGIN_NAMESPACE @@ -85,7 +86,8 @@ class QIOSEventDispatcher : public QAbstractEventDispatcher Q_OBJECT public: - explicit QIOSEventDispatcher(QObject *parent = 0); ~QIOSEventDispatcher(); + explicit QIOSEventDispatcher(QObject *parent = 0); + ~QIOSEventDispatcher(); bool processEvents(QEventLoop::ProcessEventsFlags flags); bool hasPendingEvents(); @@ -103,6 +105,11 @@ public: void wakeUp(); void interrupt(); void flush(); + +private: + CFRunLoopSourceRef m_postedEventsSource; + static void postedEventsSourceCallback(void *info); + void processPostedEvents(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 12f448488e..85854f711e 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -75,42 +75,80 @@ #include "qioseventdispatcher.h" #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE +static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) +{ + return info1 == info2; +} + +void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +{ + QIOSEventDispatcher *self = static_cast(info); + self->processPostedEvents(); +} + +void QIOSEventDispatcher::processPostedEvents() +{ + qDebug() << __FUNCTION__ << "called"; + QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); +} + QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) + : QAbstractEventDispatcher(parent) { - Q_UNUSED(parent); - qDebug() << __FUNCTION__ << "eventdispatcher not implemented"; + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + + CFRunLoopSourceContext context; + bzero(&context, sizeof(CFRunLoopSourceContext)); + context.equal = runLoopSourceEqualCallback; + context.info = this; + + // source used to send posted events: + context.perform = QIOSEventDispatcher::postedEventsSourceCallback; + m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() -{} +{ + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsSource); +} bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_UNUSED(flags); + qDebug() << __FUNCTION__ << "not implemented"; return false; } bool QIOSEventDispatcher::hasPendingEvents() { + qDebug() << __FUNCTION__ << "not implemented"; return false; } void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); Q_UNUSED(interval); Q_UNUSED(timerType); @@ -119,36 +157,47 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return false; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return false; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(object); return QList(); } int QIOSEventDispatcher::remainingTime(int timerId) { + qDebug() << __FUNCTION__ << "not implemented"; Q_UNUSED(timerId); return 0; } void QIOSEventDispatcher::wakeUp() -{} +{ + CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopWakeUp(CFRunLoopGetMain()); +} void QIOSEventDispatcher::interrupt() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} void QIOSEventDispatcher::flush() -{} +{ + qDebug() << __FUNCTION__ << "not implemented"; +} QT_END_NAMESPACE -- cgit v1.2.3 From 407cf7341e70feeb24ff63ad11bd2e79dac5823f Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 5 Nov 2012 14:07:47 +0100 Subject: iOS: QIOSEventDispatcher: implement timer support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1966a64e6535f32005681db37b4fe5d89dafc70c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 15 ++- src/plugins/platforms/ios/qioseventdispatcher.mm | 136 ++++++++++++++++++++--- 2 files changed, 132 insertions(+), 19 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index db3eb85ffc..da8464f5ee 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -77,6 +77,7 @@ #define QEVENTDISPATCHER_IOS_P_H #include +#include #include QT_BEGIN_NAMESPACE @@ -107,9 +108,19 @@ public: void flush(); private: - CFRunLoopSourceRef m_postedEventsSource; - static void postedEventsSourceCallback(void *info); + CFRunLoopSourceRef m_postedEventsRunLoopSource; + CFRunLoopSourceRef m_blockingTimerRunLoopSource; + + QTimerInfoList m_timerInfoList; + CFRunLoopTimerRef m_runLoopTimerRef; + void processPostedEvents(); + void maybeStartCFRunLoopTimer(); + void maybeStopCFRunLoopTimer(); + + static void postedEventsRunLoopCallback(void *info); + static void nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info); + static void blockingTimerRunLoopCallback(void *info); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 85854f711e..191e80668d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -76,6 +76,7 @@ #include "qioseventdispatcher.h" #include #include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -85,40 +86,134 @@ static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2) return info1 == info2; } -void QIOSEventDispatcher::postedEventsSourceCallback(void *info) +void QIOSEventDispatcher::postedEventsRunLoopCallback(void *info) { QIOSEventDispatcher *self = static_cast(info); self->processPostedEvents(); } +void QIOSEventDispatcher::nonBlockingTimerRunLoopCallback(CFRunLoopTimerRef, void *info) +{ + // The (one and only) CFRunLoopTimer has fired, which means that at least + // one QTimer should now fire as well. Note that CFRunLoopTimer's callback will + // never recurse. So if the app starts a new QEventLoop within this callback, other + // timers will stop working. The work-around is to forward the callback to a + // dedicated CFRunLoopSource that can recurse: + QIOSEventDispatcher *self = static_cast(info); + CFRunLoopSourceSignal(self->m_blockingTimerRunLoopSource); +} + +void QIOSEventDispatcher::blockingTimerRunLoopCallback(void *info) +{ + // TODO: + // We also need to block this new timer source + // along with the posted event source when calling processEvents() + // "manually" to prevent livelock deep in CFRunLoop. + + QIOSEventDispatcher *self = static_cast(info); + self->m_timerInfoList.activateTimers(); + self->maybeStartCFRunLoopTimer(); +} + +void QIOSEventDispatcher::maybeStartCFRunLoopTimer() +{ + // Find out when the next registered timer should fire, and schedule + // runLoopTimer accordingly. If the runLoopTimer does not yet exist, and + // at least one timer is registered, start by creating the timer: + if (m_timerInfoList.isEmpty()) { + Q_ASSERT(m_runLoopTimerRef == 0); + return; + } + + CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent(); + CFTimeInterval interval; + + if (m_runLoopTimerRef == 0) { + // start the CFRunLoopTimer + CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.); + + // calculate when the next timer should fire: + struct timespec tv; + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // this shouldn't really happen, but in case it does, set the timer + // to fire a some point in the distant future: + interval = oneyear; + } + + ttf += interval; + CFRunLoopTimerContext info = { 0, this, 0, 0, 0 }; + // create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate() + // documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working + m_runLoopTimerRef = CFRunLoopTimerCreate(0, ttf, oneyear, 0, 0, QIOSEventDispatcher::nonBlockingTimerRunLoopCallback, &info); + Q_ASSERT(m_runLoopTimerRef != 0); + + CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimerRef, kCFRunLoopCommonModes); + } else { + struct timespec tv; + // Calculate when the next timer should fire: + if (m_timerInfoList.timerWait(tv)) { + interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001); + } else { + // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some + // point in the distant future (the timer interval is one year) + interval = CFRunLoopTimerGetInterval(m_runLoopTimerRef); + } + + ttf += interval; + CFRunLoopTimerSetNextFireDate(m_runLoopTimerRef, ttf); + } +} + +void QIOSEventDispatcher::maybeStopCFRunLoopTimer() +{ + if (m_runLoopTimerRef == 0) + return; + + CFRunLoopTimerInvalidate(m_runLoopTimerRef); + CFRelease(m_runLoopTimerRef); + m_runLoopTimerRef = 0; +} + void QIOSEventDispatcher::processPostedEvents() { - qDebug() << __FUNCTION__ << "called"; QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents); } QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); context.equal = runLoopSourceEqualCallback; context.info = this; - // source used to send posted events: - context.perform = QIOSEventDispatcher::postedEventsSourceCallback; - m_postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); - Q_ASSERT(m_postedEventsSource); - CFRunLoopAddSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); + // source used to handle timers: + context.perform = QIOSEventDispatcher::blockingTimerRunLoopCallback; + m_blockingTimerRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_blockingTimerRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + + // source used to handle posted events: + context.perform = QIOSEventDispatcher::postedEventsRunLoopCallback; + m_postedEventsRunLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context); + Q_ASSERT(m_postedEventsRunLoopSource); + CFRunLoopAddSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); } QIOSEventDispatcher::~QIOSEventDispatcher() { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); - CFRunLoopRemoveSource(mainRunLoop, m_postedEventsSource, kCFRunLoopCommonModes); - CFRelease(m_postedEventsSource); + CFRunLoopRemoveSource(mainRunLoop, m_postedEventsRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_postedEventsRunLoopSource); + + qDeleteAll(m_timerInfoList); + maybeStopCFRunLoopTimer(); + CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); + CFRelease(m_blockingTimerRunLoopSource); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -146,13 +241,20 @@ void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) Q_UNUSED(notifier); } -void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) +void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - Q_UNUSED(interval); - Q_UNUSED(timerType); - Q_UNUSED(object); +#ifndef QT_NO_DEBUG + if (timerId < 1 || interval < 0 || !obj) { + qWarning("QIOSEventDispatcher::registerTimer: invalid arguments"); + return; + } else if (obj->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QIOSEventDispatcher: timers cannot be started from another thread"); + return; + } +#endif + + m_timerInfoList.registerTimer(timerId, interval, timerType, obj); + maybeStartCFRunLoopTimer(); } bool QIOSEventDispatcher::unregisterTimer(int timerId) @@ -185,7 +287,7 @@ int QIOSEventDispatcher::remainingTime(int timerId) void QIOSEventDispatcher::wakeUp() { - CFRunLoopSourceSignal(m_postedEventsSource); + CFRunLoopSourceSignal(m_postedEventsRunLoopSource); CFRunLoopWakeUp(CFRunLoopGetMain()); } -- cgit v1.2.3 From 44c3ef790e6105b913b514dfda64fd5957df78af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 5 Nov 2012 13:59:53 +0100 Subject: iOS: Fix build on case sensitive filesystems Change-Id: Ic7a2b38ffcc2bd83e268c5caf5bec17006879969 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c876bf1b2..0c324d5275 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qiosIntegration.h" +#include "qiosintegration.h" #include "qioswindow.h" #include "qiosbackingstore.h" #include "qiosscreen.h" -- cgit v1.2.3 From 05d0f60ebefaeb7721ac572f1253c2c7b2f42dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 4 Nov 2012 23:30:50 +0100 Subject: iOS: Flesh out initial QPlatformScreen implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We check the device's model identifier to tweak the screen values based on the precense of older iPhone/iPod touch models, or the iPad Mini. This does not work when running under the simulator, which reports its model identifier as the architecture of the host platform. There doesn't appear to be any APIs to get the simulated device of the simulator, but if this becomes an issue we can always look at the UIDevice model and screen resolution and apply a few heuristics. We do not update the screen geometry on orientation-changes. This matches what UIScreen reports for bounds, but may not be the most intuitive solution from a Qt perspective compared to the way other platform-plugins work. Change-Id: I74783e053601de9ce805f8b52b944c116f9a1e3e Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosscreen.h | 13 ++-- src/plugins/platforms/ios/qiosscreen.mm | 105 +++++++++++++++++--------------- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 98771b9ac2..8af7779f9d 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -52,24 +52,21 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); - ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - QSizeF physicalSize() const { return m_physicalSize; } + QRect geometry() const; + int depth() const; + QImage::Format format() const; + QSizeF physicalSize() const; UIScreen *uiScreen() const; - void updateInterfaceOrientation(); private: UIScreen *m_uiScreen; QRect m_geometry; int m_depth; - QImage::Format m_format; - QSize m_physicalSize; + QSizeF m_physicalSize; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 64b9022a29..93b22953e2 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,79 +42,86 @@ #include "qiosscreen.h" #include "qioswindow.h" -#include - -#include +#include QT_BEGIN_NAMESPACE +/*! + Returns the model identifier of the device. + + When running under the simulator, the identifier will not + match the simulated device, but will be x86_64 or i386. +*/ +static QString deviceModelIdentifier() +{ + static const char key[] = "hw.machine"; + + size_t size; + sysctlbyname(key, NULL, &size, NULL, 0); + + char value[size]; + sysctlbyname(key, &value, &size, NULL, 0); + + return QString::fromLatin1(value); +} + QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - CGRect bounds = [m_uiScreen bounds]; - CGFloat scale = [m_uiScreen scale]; - updateInterfaceOrientation(); - m_format = QImage::Format_ARGB32_Premultiplied; + QString deviceIdentifier = deviceModelIdentifier(); - m_depth = 24; - - const qreal inch = 25.4; - qreal unscaledDpi = 160.; - int dragDistance = 12 * scale; - if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { - unscaledDpi = 132.; - dragDistance = 10 * scale; + if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */ + || deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) { + m_depth = 18; + } else { + m_depth = 24; } - m_physicalSize = QSize(qRound(bounds.size.width * inch / unscaledDpi), qRound(bounds.size.height * inch / unscaledDpi)); - //qApp->setStartDragDistance(dragDistance); + int unscaledDpi = 163; // Regular iPhone DPI + if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad + && deviceIdentifier != QStringLiteral("iPad2,5") /* iPad Mini */) { + unscaledDpi = 132; + }; + + // UIScreen does not report different bounds for different orientations. We + // match this behavior by staying with a fixed QScreen geometry. + CGRect bounds = [m_uiScreen bounds]; + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); - /* - QFont font; // system font is helvetica, so that is fine already - font.setPixelSize([UIFont systemFontSize] * scale); - qApp->setFont(font); - */ + const qreal millimetersPerInch = 25.4; + m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; [pool release]; } -QIOSScreen::~QIOSScreen() +QRect QIOSScreen::geometry() const { + // FIXME: Do we need to reimplement availableGeometry() to take the + // system statusbar into account? + return m_geometry; } -UIScreen *QIOSScreen::uiScreen() const +int QIOSScreen::depth() const { - return m_uiScreen; + return m_depth; } -void QIOSScreen::updateInterfaceOrientation() +QImage::Format QIOSScreen::format() const { - qDebug() << __FUNCTION__ << "not implemented"; - /* - CGRect bounds = [uiScreen() bounds]; - CGFloat scale = [uiScreen() scale]; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.width * scale, bounds.size.height * scale);; - break; - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - m_geometry = QRect(bounds.origin.x * scale, bounds.origin.y * scale, - bounds.size.height * scale, bounds.size.width * scale); - break; - } - foreach (QWidget *widget, qApp->topLevelWidgets()) { - QIOSWindow *platformWindow = static_cast(widget->platformWindow()); - if (platformWindow && platformWindow->platformScreen() == this) { - platformWindow->updateGeometryAndOrientation(); - } - } - */ + return QImage::Format_ARGB32_Premultiplied; +} + +QSizeF QIOSScreen::physicalSize() const +{ + return m_physicalSize; +} + +UIScreen *QIOSScreen::uiScreen() const +{ + return m_uiScreen; } QT_END_NAMESPACE -- cgit v1.2.3 From 458382f35b62c98a283bb08770029f21827b9ae6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 11:00:58 +0100 Subject: iOS: call UIApplicationMain from event dispatcher, and add application delegate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will let you call QApplication::exec() instead of UiApplicationMain from main. Also added an application delegate that we will need sooner or later for catching application activation events. Change-Id: I4edba5ce2059a804782d67c160755fc0e2e5267d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/ios.pro | 6 +- .../platforms/ios/qiosapplicationdelegate.h | 50 ++++++++++++ .../platforms/ios/qiosapplicationdelegate.mm | 89 ++++++++++++++++++++++ src/plugins/platforms/ios/qioseventdispatcher.mm | 58 ++++++-------- 4 files changed, 165 insertions(+), 38 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.h create mode 100644 src/plugins/platforms/ios/qiosapplicationdelegate.mm diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index c6c104f2f3..76f5e3420e 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -12,13 +12,15 @@ OBJECTIVE_SOURCES = main.mm \ qioswindow.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ - qiosbackingstore.mm + qiosbackingstore.mm \ + qiosapplicationdelegate.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ - qiosbackingstore.h + qiosbackingstore.h \ + qiosapplicationdelegate.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h new file mode 100644 index 0000000000..10e415831d --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import +#import + +@interface QIOSApplicationDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm new file mode 100644 index 0000000000..d88b2b83f1 --- /dev/null +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosapplicationdelegate.h" +#include + +@implementation QIOSApplicationDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + Q_UNUSED(application) + Q_UNUSED(launchOptions) + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + + // Override point for customization after application launch. + self.window.backgroundColor = [UIColor whiteColor]; + [self.window makeKeyAndVisible]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationDidEnterBackground:(UIApplication *)application +{ + Q_UNUSED(application) +} + +- (void)applicationWillEnterForeground:(UIApplication *)application +{ + Q_UNUSED(application) + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application +{ + Q_UNUSED(application) + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + +- (void)applicationWillTerminate:(UIApplication *)application +{ + Q_UNUSED(application) + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end + + diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 191e80668d..64f853233d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -39,44 +39,13 @@ ** ****************************************************************************/ -/**************************************************************************** -** -** Copyright (c) 2007-2008, Apple, Inc. -** -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** -** * Redistributions of source code must retain the above copyright notice, -** this list of conditions and the following disclaimer. -** -** * Redistributions in binary form must reproduce the above copyright notice, -** this list of conditions and the following disclaimer in the documentation -** and/or other materials provided with the distribution. -** -** * Neither the name of Apple, Inc. nor the names of its contributors -** may be used to endorse or promote products derived from this software -** without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -** -****************************************************************************/ - #include "qioseventdispatcher.h" +#import "qiosapplicationdelegate.h" #include #include #include +#include +#include QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -218,8 +187,25 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { - Q_UNUSED(flags); - qDebug() << __FUNCTION__ << "not implemented"; + UIApplication *uiApplication = [UIApplication sharedApplication]; + bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; + bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); + bool useExecMode = execFlagSet && !excludeUserEvents; + + if (useExecMode) { + if (!uiApplication) { + // No UIApplication has been started yet. We therefore start it now. Note that application + // developers are free to call UIApplicationMain themselves instead of QApplication::exec() + @autoreleasepool { + QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); + return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); + } + } else { + // todo: start NSRunLoop... + } + } else { + // todo: manual processEvents... + } return false; } -- cgit v1.2.3 From ac8d906a3a61b3dd43aaf546e5f83e25d117631c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2012 14:52:22 +0100 Subject: iOS: support killing timers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the remaining timer functions in the event dispatcher Change-Id: Ie323962c898a2ee95ea60a8ca63b93cbd4544fd1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 54 ++++++++++++++++++------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 64f853233d..a7f01a33a9 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -245,30 +245,60 @@ void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType bool QIOSEventDispatcher::unregisterTimer(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return false; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::unregisterTimer: invalid argument"); + return false; + } else if (thread() != QThread::currentThread()) { + qWarning("QObject::killTimer: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimer(timerId); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } bool QIOSEventDispatcher::unregisterTimers(QObject *object) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return false; +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher::unregisterTimers: invalid argument"); + return false; + } else if (object->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QObject::killTimers: timers cannot be stopped from another thread"); + return false; + } +#endif + + bool returnValue = m_timerInfoList.unregisterTimers(object); + m_timerInfoList.isEmpty() ? maybeStopCFRunLoopTimer() : maybeStartCFRunLoopTimer(); + return returnValue; } QList QIOSEventDispatcher::registeredTimers(QObject *object) const { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(object); - return QList(); +#ifndef QT_NO_DEBUG + if (!object) { + qWarning("QIOSEventDispatcher:registeredTimers: invalid argument"); + return QList(); + } +#endif + + return m_timerInfoList.registeredTimers(object); } int QIOSEventDispatcher::remainingTime(int timerId) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(timerId); - return 0; +#ifndef QT_NO_DEBUG + if (timerId < 1) { + qWarning("QIOSEventDispatcher::remainingTime: invalid argument"); + return -1; + } +#endif + + return m_timerInfoList.timerRemainingTime(timerId); } void QIOSEventDispatcher::wakeUp() -- cgit v1.2.3 From 3c4f48f9e2ad9163d012d4afb36037d7efea8e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 16:24:19 +0100 Subject: iOS: Implement QPlatformOpenGLContext The iOS platform GL context is an EAGLContext, which is wrapped by the new class QIOSContext. The class takes care of makeCurrent() and swapBuffers(), but defers framebuffer management to the corresponding QIOSWindow. At the moment only a single framebuffer is created, and changing the geometry of the QWindow does not trigger any sort of invalidation of the buffers. The implementation assumes OpenGL ES2.x support. Though strictly speaking we could support ES1 for QtGui, it serves little purpose as Qt Quick 2 requires ES2. This patch also disabled touch event synthesization until we have figured out where we will maintain the connection to UIWindow. QPlatformOpenGLContext::getProcAddress() for getting extensions is implemented by using dlsym() to look up the symbol. This should not present any issues for App Store deployment, like dlopen() would. Change-Id: I166f800f3ecc0d180133c590465371ac1642b0ec Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 6 +- src/plugins/platforms/ios/qiosbackingstore.mm | 1 + src/plugins/platforms/ios/qioscontext.h | 76 +++++ src/plugins/platforms/ios/qioscontext.mm | 124 ++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 13 +- src/plugins/platforms/ios/qioswindow.h | 97 ++----- src/plugins/platforms/ios/qioswindow.mm | 400 +++++++------------------- 8 files changed, 343 insertions(+), 376 deletions(-) create mode 100644 src/plugins/platforms/ios/qioscontext.h create mode 100644 src/plugins/platforms/ios/qioscontext.mm diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 76f5e3420e..22b0fec9e8 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -13,14 +13,16 @@ OBJECTIVE_SOURCES = main.mm \ qiosscreen.mm \ qioseventdispatcher.mm \ qiosbackingstore.mm \ - qiosapplicationdelegate.mm + qiosapplicationdelegate.mm \ + qioscontext.mm HEADERS = qiosintegration.h \ qioswindow.h \ qiosscreen.h \ qioseventdispatcher.h \ qiosbackingstore.h \ - qiosapplicationdelegate.h + qiosapplicationdelegate.h \ + qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 20f7c1f2d1..2ffa43b5d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -133,6 +133,7 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { Q_UNUSED(size); Q_UNUSED(staticContents); + qDebug() << __FUNCTION__ << "not implemented"; } diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h new file mode 100644 index 0000000000..102aaaa387 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSCONTEXT_H +#define QIOSCONTEXT_H + +#include + +@class EAGLContext; + +QT_BEGIN_NAMESPACE + +class QIOSContext : public QPlatformOpenGLContext +{ +public: + QIOSContext(QOpenGLContext *context); + ~QIOSContext(); + + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + GLuint defaultFramebufferObject(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); + + EAGLContext *nativeContext() const; + +private: + EAGLContext *m_eaglContext; + QSurfaceFormat m_format; +}; + +QT_END_NAMESPACE + +#endif // QIOSCONTEXT_H diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm new file mode 100644 index 0000000000..e512b3d4c8 --- /dev/null +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qioscontext.h" +#include "qioswindow.h" + +#include + +#include + +#import +#import + +QIOSContext::QIOSContext(QOpenGLContext *context) + : QPlatformOpenGLContext() + , m_eaglContext([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]) +{ + // Start out with the requested format + QSurfaceFormat format = context->format(); + + format.setRenderableType(QSurfaceFormat::OpenGLES); + format.setMajorVersion(2); + format.setMinorVersion(0); + + // Even though iOS internally double-buffers its rendering, we + // report single-buffered here since the buffer remains unchanged + // when swapping unlesss you manually clear it yourself. + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + + m_format = format; +} + +QIOSContext::~QIOSContext() +{ + [m_eaglContext release]; +} + +QSurfaceFormat QIOSContext::format() const +{ + return m_format; +} + +bool QIOSContext::makeCurrent(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + + return true; +} + +void QIOSContext::doneCurrent() +{ + [EAGLContext setCurrentContext:nil]; +} + +void QIOSContext::swapBuffers(QPlatformSurface *surface) +{ + Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + + [EAGLContext setCurrentContext:m_eaglContext]; + + GLint renderbuffer; + glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; +} + +GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const +{ + return static_cast(surface)->framebufferObject(*const_cast(this)); +} + +QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) +{ + return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); +} + +EAGLContext *QIOSContext::nativeContext() const +{ + return m_eaglContext; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d72eefa1fa..e411ce2905 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -57,6 +57,8 @@ public: QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformFontDatabase *fontDatabase() const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0c324d5275..b9fef71abc 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -44,6 +44,7 @@ #include "qiosbackingstore.h" #include "qiosscreen.h" #include "qioseventdispatcher.h" +#include "qioscontext.h" #include @@ -65,21 +66,31 @@ QIOSIntegration::~QIOSIntegration() QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const { Q_UNUSED(type); + qDebug() << __FUNCTION__ << "not yet implemented"; return 0; - //return new QRasterPixmapData(type); } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { + qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } +// Used when the QWindow's surface type is set by the client to QSurface::OpenGLSurface +QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ + Q_UNUSED(context); + qDebug() << __FUNCTION__ << "Creating platform opengl context"; + return new QIOSContext(context); +} + QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const { return new QIOSEventDispatcher(); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d3d5b072f..d8f49db55b 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -45,24 +45,11 @@ #include #import -#import -#import -#import -#import -#import + +class QIOSContext; @interface EAGLView : UIView { - QPlatformWindow *m_window; - EAGLContext *m_context; - - GLint m_framebufferWidth; - GLint m_framebufferHeight; - - GLuint m_framebuffer, m_colorRenderbuffer, m_depthRenderbuffer; - - id delegate; - // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; BOOL enablesReturnKeyAutomatically; @@ -72,19 +59,8 @@ BOOL secureTextEntry; } -- (void)setContext:(EAGLContext *)newContext; -- (void)presentFramebuffer; -- (void)deleteFramebuffer; -- (void)createFramebuffer; -- (void)makeCurrent; -- (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; -@property (readonly,getter=fbo) GLint fbo; -@property (nonatomic, assign) id delegate; - -// ------- Text Input ---------- - @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; @property(nonatomic) UITextAutocorrectionType autocorrectionType; @property(nonatomic) BOOL enablesReturnKeyAutomatically; @@ -95,39 +71,22 @@ @end -@protocol EAGLViewDelegate -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; -@end - -class EAGLPlatformContext; - QT_BEGIN_NAMESPACE -class QIOSScreen; - class QIOSWindow : public QPlatformWindow { public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); - UIWindow *nativeWindow() const { return m_window; } - EAGLView *nativeView() const { return m_view; } void setGeometry(const QRect &rect); - UIWindow *ensureNativeWindow(); + GLuint framebufferObject(const QIOSContext &context) const; - QPlatformOpenGLContext *glContext() const; - - QIOSScreen *platformScreen() const { return m_screen; } + EAGLView *nativeView() const { return m_view; } - void updateGeometryAndOrientation(); private: - QIOSScreen *m_screen; - UIWindow *m_window; - CGRect m_frame; EAGLView *m_view; - mutable EAGLPlatformContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 28aaaf2189..46612ae699 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -1,152 +1,57 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#import - #include "qioswindow.h" - +#include "qioscontext.h" #include "qiosscreen.h" -#include +#import + #include -#include #include #include -static GLint stencilBits() -{ - static GLint bits; - static bool initialized = false; - if (!initialized) { - glGetIntegerv(GL_STENCIL_BITS, &bits); - initialized = true; - } - return bits; -} - -/* -static GLint depthBits() -{ - // we can choose between GL_DEPTH24_STENCIL8_OES and GL_DEPTH_COMPONENT16 - return stencilBits() > 0 ? 24 : 16; -} -*/ - -class EAGLPlatformContext : public QPlatformOpenGLContext -{ -public: - EAGLPlatformContext(EAGLView *view) - : m_view(view) - { - /* - mFormat.setWindowApi(QPlatformWindowFormat::OpenGL); - mFormat.setDepthBufferSize(depthBits()); - mFormat.setAccumBufferSize(0); - mFormat.setRedBufferSize(8); - mFormat.setGreenBufferSize(8); - mFormat.setBlueBufferSize(8); - mFormat.setAlphaBufferSize(8); - mFormat.setStencilBufferSize(stencilBits()); - mFormat.setSamples(0); - mFormat.setSampleBuffers(false); - mFormat.setDoubleBuffer(true); - mFormat.setDepth(true); - mFormat.setRgba(true); - mFormat.setAlpha(true); - mFormat.setAccum(false); - mFormat.setStencil(stencilBits() > 0); - mFormat.setStereo(false); - mFormat.setDirectRendering(false); - */ - -#if defined(QT_OPENGL_ES_2) - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; -#else - EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; -#endif - [m_view setContext:aContext]; - } - - ~EAGLPlatformContext() { } - - bool makeCurrent(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::makeCurrent(); - //[m_view makeCurrent]; - return false; - } - - void doneCurrent() - { - qDebug() << __FUNCTION__ << "not implemented"; - //QPlatformOpenGLContext::doneCurrent(); - } - - void swapBuffers(QPlatformSurface *surface) - { - Q_UNUSED(surface); - qDebug() << __FUNCTION__ << "not implemented"; - //[m_view presentFramebuffer]; - } - - QFunctionPointer getProcAddress(const QByteArray& ) { return 0; } - - QSurfaceFormat format() const - { - return mFormat; - } - -private: - EAGLView *m_view; - - QSurfaceFormat mFormat; -}; - @implementation EAGLView -@synthesize delegate; - + (Class)layerClass { return [CAEAGLLayer class]; @@ -155,12 +60,14 @@ private: - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + // Set up EAGL layer + CAEAGLLayer *eaglLayer = static_cast(self.layer); eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, - nil]; + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + // Set up text input autocapitalizationType = UITextAutocapitalizationTypeNone; autocorrectionType = UITextAutocorrectionTypeNo; enablesReturnKeyAutomatically = NO; @@ -169,113 +76,28 @@ private: returnKeyType = UIReturnKeyDone; secureTextEntry = NO; } - return self; -} - -- (void)setContext:(EAGLContext *)newContext -{ - if (m_context != newContext) - { - [self deleteFramebuffer]; - [m_context release]; - m_context = [newContext retain]; - [EAGLContext setCurrentContext:nil]; - } -} - -- (void)presentFramebuffer -{ - if (m_context) { - [EAGLContext setCurrentContext:m_context]; - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context presentRenderbuffer:GL_RENDERBUFFER]; - } -} -- (void)deleteFramebuffer -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (m_framebuffer) { - glDeleteFramebuffers(1, &m_framebuffer); - m_framebuffer = 0; - } - if (m_colorRenderbuffer) { - glDeleteRenderbuffers(1, &m_colorRenderbuffer); - m_colorRenderbuffer = 0; - } - if (m_depthRenderbuffer) { - glDeleteRenderbuffers(1, &m_depthRenderbuffer); - m_depthRenderbuffer = 0; - } - } -} - -- (void)createFramebuffer -{ - if (m_context && !m_framebuffer) - { - [EAGLContext setCurrentContext:m_context]; - glGenFramebuffers(1, &m_framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - - glGenRenderbuffers(1, &m_colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer); - [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_framebufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRenderbuffer); - - glGenRenderbuffers(1, &m_depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer); - if (stencilBits() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_framebufferWidth, m_framebufferHeight); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_framebufferWidth, m_framebufferHeight); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthRenderbuffer); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { - [delegate eaglView:self usesFramebuffer:m_framebuffer]; - } - } -} - -- (void)makeCurrent -{ - if (m_context) - { - [EAGLContext setCurrentContext:m_context]; - if (!m_framebuffer) - [self createFramebuffer]; - glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); - glViewport(0, 0, m_framebufferWidth, m_framebufferHeight); - } + return self; } -- (GLint)fbo +- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - return m_framebuffer; -} + Q_UNUSED(touches); + Q_UNUSED(event); + Q_UNUSED(buttons); -- (void)setWindow:(QPlatformWindow *)window -{ - m_window = window; -} + // FIXME: Reintroduce relation to UIWindow + qDebug() << __FUNCTION__ << "not implemented"; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons -{ +#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), - p, p, buttons); + QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); +#endif } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -298,8 +120,6 @@ private: [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; } -// ------- Text Input ---------- - @synthesize autocapitalizationType; @synthesize autocorrectionType; @synthesize enablesReturnKeyAutomatically; @@ -343,107 +163,79 @@ private: @end + QT_BEGIN_NAMESPACE -QIOSWindow::QIOSWindow(QWindow *window) : - QPlatformWindow(window), - m_window(nil), - m_context(0) +QIOSWindow::QIOSWindow(QWindow *window) + : QPlatformWindow(window) + , m_view([[EAGLView alloc] init]) { - m_screen = static_cast(QPlatformScreen::platformScreenForWindow(window)); - m_view = [[EAGLView alloc] init]; } QIOSWindow::~QIOSWindow() { - delete m_context; m_context = 0; [m_view release]; - [m_window release]; } void QIOSWindow::setGeometry(const QRect &rect) { - // Not supported. Only a single "full screen" window is supported QPlatformWindow::setGeometry(rect); -} -UIWindow *QIOSWindow::ensureNativeWindow() -{ - if (!m_window) { - m_window = [[UIWindow alloc] init]; - updateGeometryAndOrientation(); - // window - m_window.screen = m_screen->uiScreen(); - // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards - m_window.frame = m_frame; - - // view - [m_view deleteFramebuffer]; - m_view.frame = CGRectMake(0, 0, m_window.bounds.size.width, m_window.bounds.size.height); // fill - [m_view setContentScaleFactor:[m_window.screen scale]]; - [m_view setMultipleTouchEnabled:YES]; - [m_view setWindow:this]; - [m_window addSubview:m_view]; - [m_window setNeedsDisplay]; - [m_window makeKeyAndVisible]; - } - return m_window; + qDebug() << __FUNCTION__ << "not implemented"; } -void QIOSWindow::updateGeometryAndOrientation() +GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - if (!m_window) - return; - m_frame = [m_screen->uiScreen() applicationFrame]; - CGRect screen = [m_screen->uiScreen() bounds]; - QRect geom; - CGFloat angle = 0; - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - geom = QRect(m_frame.origin.x, m_frame.origin.y, m_frame.size.width, m_frame.size.height); - break; - case UIInterfaceOrientationPortraitUpsideDown: - geom = QRect(screen.size.width - m_frame.origin.x - m_frame.size.width, - screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.size.width, - m_frame.size.height); - angle = M_PI; - break; - case UIInterfaceOrientationLandscapeLeft: - geom = QRect(screen.size.height - m_frame.origin.y - m_frame.size.height, - m_frame.origin.x, - m_frame.size.height, - m_frame.size.width); - angle = -M_PI/2.; - break; - case UIInterfaceOrientationLandscapeRight: - geom = QRect(m_frame.origin.y, - screen.size.width - m_frame.origin.x - m_frame.size.width, - m_frame.size.height, - m_frame.size.width); - angle = +M_PI/2.; - break; - } + static GLuint framebuffer = 0; - CGFloat scale = [m_screen->uiScreen() scale]; - geom = QRect(geom.x() * scale, geom.y() * scale, - geom.width() * scale, geom.height() * scale); + // FIXME: Cache context and recreate framebuffer if window + // is used with a different context then last time. - if (angle != 0) { - [m_view layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); - } else { - [m_view layer].transform = CATransform3DIdentity; - } - [m_view setNeedsDisplay]; - window()->setGeometry(geom); -} + if (!framebuffer) { + EAGLContext* eaglContext = context.nativeContext(); -QPlatformOpenGLContext *QIOSWindow::glContext() const -{ - if (!m_context) { - m_context = new EAGLPlatformContext(m_view); + [EAGLContext setCurrentContext:eaglContext]; + + // Create the framebuffer and bind it + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + GLint width; + GLint height; + + // Create a color renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s color attachment point. + GLuint colorRenderbuffer; + glGenRenderbuffers(1, &colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); + [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); + + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + // Create a depth or depth/stencil renderbuffer, allocate storage for it, + // and attach it to the framebuffer’s depth attachment point. + GLuint depthRenderbuffer; + glGenRenderbuffers(1, &depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (requestedFormat.stencilBufferSize() > 0) { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } else { + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); + } + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return m_context; + + return framebuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 09187f602c8ac84c9982bb2e433af5524ac2d37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 6 Nov 2012 12:01:50 +0100 Subject: iOS: Implement QIOSBackingStore in terms of a QOpenGLPaintDevice We build on top of the QPlatformOpenGLContext implementation to get automatic support for QBackingStore-based painting. Since the OpenGL renderer does not clear the backingstore between frames, we actually also get support for partial updates, and we get the benefit of an accelerated paint engine for Qt Quick 1 without setting a GLWidget as the viewport, which would cause issues such as an extra QWindow. This patch also removes the dependency to QtOpenGL and QtWidgets, which were leftovers from the Qt4 platform plugin. In Qt5 the needed GL bits are in QtGui. Change-Id: Id9b736bfb2e4aec56c0fa9f5b7b4d8bff8e3d1dc Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 3 +- src/plugins/platforms/ios/qiosbackingstore.h | 57 +++++----- src/plugins/platforms/ios/qiosbackingstore.mm | 147 ++++++++++---------------- src/plugins/platforms/ios/qiosintegration.mm | 1 + 4 files changed, 89 insertions(+), 119 deletions(-) diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 22b0fec9e8..2fe6a4cb3f 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -3,8 +3,7 @@ TARGET = qios load(qt_plugin) DESTDIR = $$QT.gui.plugins/platforms -QT += opengl -QT += core-private gui-private platformsupport-private opengl-private widgets-private +QT += core-private gui-private platformsupport-private LIBS += -framework UIKit -framework QuartzCore OBJECTIVE_SOURCES = main.mm \ diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index d83a5c21ad..c110f0e4d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,7 +42,6 @@ #ifndef QIOSBACKINGSTORE_H #define QIOSBACKINGSTORE_H -#include #include QT_BEGIN_NAMESPACE @@ -51,13 +50,19 @@ class QIOSBackingStore : public QPlatformBackingStore { public: QIOSBackingStore(QWindow *window); + ~QIOSBackingStore(); QPaintDevice *paintDevice(); + + void beginPaint(const QRegion &); + void endPaint(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); private: - QPaintDevice *m_paintDevice; + QOpenGLContext *m_context; + QPaintDevice *m_device; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 2ffa43b5d1..71f14fdd91 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ @@ -42,91 +42,54 @@ #include "qiosbackingstore.h" #include "qioswindow.h" -#include -#include +#include +#include #include -class EAGLPaintDevice; - -@interface PaintDeviceHelper : NSObject { - EAGLPaintDevice *device; -} - -@property (nonatomic, assign) EAGLPaintDevice *device; - -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; - -@end - -class EAGLPaintDevice : public QGLPaintDevice +QIOSBackingStore::QIOSBackingStore(QWindow *window) + : QPlatformBackingStore(window) + , m_context(new QOpenGLContext) + , m_device(0) { -public: - EAGLPaintDevice(QWindow *window) - :QGLPaintDevice(), m_window(window) - { -#if defined(QT_OPENGL_ES_2) - helper = [[PaintDeviceHelper alloc] init]; - helper.device = this; - EAGLView *view = static_cast(window->handle())->nativeView(); - view.delegate = helper; - m_thisFBO = view.fbo; -#endif - } - - ~EAGLPaintDevice() - { -#if defined(QT_OPENGL_ES_2) - [helper release]; -#endif - } - - void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } - int devType() const { return QInternal::OpenGL; } - QSize size() const { return m_window->geometry().size(); } - QGLContext* context() const { - // Todo: siplify this: - return QGLContext::fromOpenGLContext( - static_cast(m_window->handle())->glContext()->context()); - } - - QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - -private: - QWindow *m_window; - PaintDeviceHelper *helper; -}; - -@implementation PaintDeviceHelper -@synthesize device; + m_context->setFormat(window->requestedFormat()); + m_context->setScreen(window->screen()); + m_context->create(); +} -- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +QIOSBackingStore::~QIOSBackingStore() { - Q_UNUSED(view) - if (device) - device->setFramebuffer(buffer); + delete m_context; } -@end - -QT_BEGIN_NAMESPACE - -QIOSBackingStore::QIOSBackingStore(QWindow *window) - : QPlatformBackingStore(window), m_paintDevice(new EAGLPaintDevice(window)) +void QIOSBackingStore::beginPaint(const QRegion &) { + // Needed to prevent QOpenGLContext::makeCurrent() from failing + window()->setSurfaceType(QSurface::OpenGLSurface); + + m_context->makeCurrent(window()); + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { - return m_paintDevice; + return m_device; } void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(region); Q_UNUSED(offset); - qDebug() << __FUNCTION__ << "not implemented"; - //static_cast(window->handle())->glContext()->swapBuffers(); + + m_context->swapBuffers(window); +} + +void QIOSBackingStore::endPaint() +{ + delete m_device; + + // Calling makeDone() on the context here would be an option, + // but is not needed, and would actually add some overhead. } void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) @@ -134,7 +97,9 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) Q_UNUSED(size); Q_UNUSED(staticContents); - qDebug() << __FUNCTION__ << "not implemented"; + // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper + // around the OpenGL paint-engine, and the real geometry is handled by the + // context and window. } QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b9fef71abc..8abe3c4273 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -77,6 +77,7 @@ QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const return new QIOSWindow(window); } +// Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform backingstore"; -- cgit v1.2.3 From 19de726725dc123f478ecb2b122d03862c725650 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 09:31:00 +0100 Subject: iOS: create top-level UIWindow and UIViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a UIWIndow with a view controller and a view where we can reparent our QIOSWindow views inside. Change-Id: Ic90707d3ebe1af970a3aa2aa0f8c0f4be192456a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 18 ++++++++++++++++++ src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index d88b2b83f1..6fed4c1a23 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #import "qiosapplicationdelegate.h" +#include "qioswindow.h" #include @implementation QIOSApplicationDelegate @@ -48,7 +49,24 @@ { Q_UNUSED(application) Q_UNUSED(launchOptions) + + // If this application delegate is instanciated, it means that + // this plugin also created UIApplication. We then also create a + // window with a view controller, and set all QWindow views + // as children of the controller view: self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + QWindowList windows = QGuiApplication::topLevelWindows(); + for (int i=0; i(windows[i]->handle())) { + UIView *winView = w->nativeView(); + if (winView && !winView.superview) + [controller.view addSubview:winView]; + } + } // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 46612ae699..2888228f18 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,6 +42,7 @@ #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" +#include "qiosapplicationdelegate.h" #import @@ -170,6 +171,11 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] init]) { + UIApplication *uiApplication = [UIApplication sharedApplication]; + if (uiApplication) { + if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) + [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; + } } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From ea1e5ccd621115d8103ceac962ac89dc0db65b70 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 16:34:43 +0100 Subject: iOS: implement QEventLoop support in the event dispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this patch you can now expect the following code to work: QEventLoop l; QTimer::singleShot(1000, &l, SLOT(quit())); l.exec(); Change-Id: Ic73e37affaadf8a859787d84ac02c15621ac7a29 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.h | 2 ++ src/plugins/platforms/ios/qioseventdispatcher.mm | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index da8464f5ee..88d5127855 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -108,6 +108,8 @@ public: void flush(); private: + bool m_interrupted; + CFRunLoopSourceRef m_postedEventsRunLoopSource; CFRunLoopSourceRef m_blockingTimerRunLoopSource; diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index a7f01a33a9..4268b02b6d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -152,6 +152,7 @@ void QIOSEventDispatcher::processPostedEvents() QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) : QAbstractEventDispatcher(parent) + , m_interrupted(false) , m_runLoopTimerRef(0) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); @@ -187,6 +188,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { + m_interrupted = false; + UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); @@ -201,7 +204,8 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); } } else { - // todo: start NSRunLoop... + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } } else { // todo: manual processEvents... @@ -309,7 +313,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { - qDebug() << __FUNCTION__ << "not implemented"; + m_interrupted = true; } void QIOSEventDispatcher::flush() -- cgit v1.2.3 From 0dbee6a5e1e3945dab404f8784df24a9260f0d52 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 22:57:17 +0100 Subject: iOS: send mouse events (from touch events) from EAGLView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia6c955f2c5bcde8e41d5908bfb8fd52bd449b3ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 +++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d8f49db55b..c2bf1bb6f0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -47,6 +47,7 @@ #import class QIOSContext; +class QIOSWindow; @interface EAGLView : UIView { @@ -57,8 +58,10 @@ class QIOSContext; UIKeyboardType keyboardType; UIReturnKeyType returnKeyType; BOOL secureTextEntry; + QIOSWindow *m_qioswindow; } +- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; @property(nonatomic) UITextAutocapitalizationType autocapitalizationType; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2888228f18..59508d83f3 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -58,6 +58,14 @@ return [CAEAGLLayer class]; } +-(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +{ + if (self = [super init]) { + m_qioswindow = qioswindow; + } + return self; +} + - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -83,22 +91,13 @@ - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { - Q_UNUSED(touches); - Q_UNUSED(event); - Q_UNUSED(buttons); - - // FIXME: Reintroduce relation to UIWindow - qDebug() << __FUNCTION__ << "not implemented"; - -#if 0 UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; CGFloat scaleFactor = [self contentScaleFactor]; QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_window->window(), (ulong)(event.timestamp*1000), p, p, buttons); -#endif + QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -169,7 +168,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) - , m_view([[EAGLView alloc] init]) + , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { UIApplication *uiApplication = [UIApplication sharedApplication]; if (uiApplication) { -- cgit v1.2.3 From 6bbe89e2b858564493468c7c5bd9c978c374751a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Nov 2012 19:48:38 +0100 Subject: iOS: support stand-alone qApp->processEvents calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rough implementation to support stand-alone processEvent calls. We probably need to revisit this code to fix corner-cases later on. Change-Id: I72d5639dab599b4d0017aaa52b922f4185a50337 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioseventdispatcher.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 4268b02b6d..252e375a54 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -189,6 +189,7 @@ QIOSEventDispatcher::~QIOSEventDispatcher() bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { m_interrupted = false; + bool eventsProcessed = false; UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; @@ -207,10 +208,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); } + eventsProcessed = true; } else { - // todo: manual processEvents... + if (!(flags & QEventLoop::WaitForMoreEvents)) + wakeUp(); + eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } - return false; + return eventsProcessed; } bool QIOSEventDispatcher::hasPendingEvents() @@ -313,6 +317,7 @@ void QIOSEventDispatcher::wakeUp() void QIOSEventDispatcher::interrupt() { + wakeUp(); m_interrupted = true; } -- cgit v1.2.3 From caacccaaf0fbc0a4f4f88af7dadbfece175776d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 7 Nov 2012 17:30:46 +0100 Subject: iOS: Unset EAGL context if it's current when destroying QIOSContext Change-Id: Ie0b27e6b0dafa2a7283b44d6676871fce15cc42a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index e512b3d4c8..8beb588b03 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,6 +70,9 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { + if ([EAGLContext currentContext] == m_eaglContext) + doneCurrent(); + [m_eaglContext release]; } -- cgit v1.2.3 From 231796c98d317f845209e2b470fa34e00aac3c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 14:48:18 +0100 Subject: iOS: Set background color of UIWindow and root UIView to burn your eyes Convenient to aid debugging during development of the platform plugin. Change-Id: Id429ca95e0452385ee8def1fe4a1bb7de175ba3e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 6fed4c1a23..1b3dc18dd7 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -68,8 +68,10 @@ } } - // Override point for customization after application launch. - self.window.backgroundColor = [UIColor whiteColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + controller.view.backgroundColor = [UIColor magentaColor]; + [self.window makeKeyAndVisible]; return YES; } -- cgit v1.2.3 From 3bc6d7470a88bf1da12aa768c9527fe08d52757a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 15:09:00 +0100 Subject: iOS: Pass QWindow geometry to initWithFrame on window creation Allows the optimal pattern of setting the geometry of the QWindow before showing (and hence creating) it. Change-Id: I29206b5d9a70df0b01e8df8f7df8f35cced51121 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59508d83f3..ce0ea6e0e1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -51,6 +51,11 @@ #include +static CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + @implementation EAGLView + (Class)layerClass @@ -58,11 +63,11 @@ return [CAEAGLLayer class]; } --(id)initWithQIOSWindow:(QIOSWindow *)qioswindow +-(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super init]) { - m_qioswindow = qioswindow; - } + if (self = [super initWithFrame:toCGRect(window->geometry())]) + m_qioswindow = window; + return self; } -- cgit v1.2.3 From e936561a164ce582785eafcfa70ed2924f7bc954 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sun, 11 Nov 2012 10:22:20 +0100 Subject: iOS: Add Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) into the plugin itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the plugin will always be linked in statically, we add this necessary registration code into the plugin itself rather than putting this burden onto the client application. Change-Id: I8691d8080e41bdf0644bb960b5c7102e79a0f0d5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/main.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm index b09fbce1f4..6a04770e3e 100644 --- a/src/plugins/platforms/ios/main.mm +++ b/src/plugins/platforms/ios/main.mm @@ -66,4 +66,4 @@ QT_END_NAMESPACE #include "main.moc" - +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) -- cgit v1.2.3 From 8d7238f57e9a85524ea550917f051b9eb9927922 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Wed, 7 Nov 2012 22:11:35 +0100 Subject: iOS: Use default createPlatformPixmap implementation No need to implement this one, the standard implementation creates a raster pixmap. Change-Id: I9bb25188bd95159d76e760b2be6870e0bede7b56 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosintegration.h | 1 - src/plugins/platforms/ios/qiosintegration.mm | 8 -------- 2 files changed, 9 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index e411ce2905..11c17aced9 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -53,7 +53,6 @@ public: QIOSIntegration(); ~QIOSIntegration(); - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8abe3c4273..d00d4a077f 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -63,14 +63,6 @@ QIOSIntegration::~QIOSIntegration() { } -QPlatformPixmap *QIOSIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const -{ - Q_UNUSED(type); - - qDebug() << __FUNCTION__ << "not yet implemented"; - return 0; -} - QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 3d81b43aa462c66e11f772398550e76ce4cee6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2012 17:12:54 +0100 Subject: iOS: Implement QPlatformScreen::availableGeometry() This will sadly not work as expected until we've found a way to kick off the iOS event loop before QApplication is initialized, as UIScreen does not seem to report the correct applicationFrame (taking the status bar into account) until after the UIApplication has been set up by UIApplicationMain(). Change-Id: I0eaa3b8bca4129d1c4183a202ad2ecd0d8bc52d0 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8af7779f9d..8d67b1ecdf 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -56,6 +56,7 @@ public: enum ScreenIndex { MainScreen = 0 }; QRect geometry() const; + QRect availableGeometry() const; int depth() const; QImage::Format format() const; QSizeF physicalSize() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 93b22953e2..effd19070a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -99,11 +99,15 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) QRect QIOSScreen::geometry() const { - // FIXME: Do we need to reimplement availableGeometry() to take the - // system statusbar into account? return m_geometry; } +QRect QIOSScreen::availableGeometry() const +{ + CGRect frame = m_uiScreen.applicationFrame; + return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); +} + int QIOSScreen::depth() const { return m_depth; -- cgit v1.2.3 From e123056c47e33759e740ea2e25771e0cc1899c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:08:46 +0100 Subject: iOS: Implement QIOSWindow::setGeometry() and pick up UIView geometry changes The best way to pick up geometry changes of the UIView seems to be to override layoutSubviews(), but that will only be called if the size of the UIView changes, not when the position (center) changes. This means that the position reflected by the QWindow will not always be in sync with the position of the native UIView. Fortunately the position of a QWindow is not used for anything critical in Qt itself. Another issue is that the frame property of a UIView is only valid if the transform of the UIView is set to the identity transform. We try to catch cases where this is not the case, and warn the user about this. We could in theory react to changes in the UIView geometry by only updating the size, since this is also reflected through the bounds property of the UIView. This is left for when we know more about how these things interact in practice. Change-Id: I079162c059d377a77569fe3974e261d2e0671fd5 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index c2bf1bb6f0..d16e17124d 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,6 +83,7 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); + void updateGeometry(const QRect &rect); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index ce0ea6e0e1..feabaeb47a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -56,6 +56,11 @@ static CGRect toCGRect(const QRect &rect) return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } +static QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + @implementation EAGLView + (Class)layerClass @@ -94,6 +99,24 @@ static CGRect toCGRect(const QRect &rect) return self; } +- (void)layoutSubviews +{ + // This method is the de facto way to know that view has been resized, + // or otherwise needs invalidation of its buffers. Note though that we + // do not get this callback when the view just changes its position, so + // the position of our QWindow (and platform window) will only get updated + // when the size is also changed. + + if (CGAffineTransformIsIdentity(self.transform)) { + // Reflect the new size (and possibly also position) in the QWindow + m_qioswindow->updateGeometry(fromCGRect(self.frame)); + } else { + qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; + } + + [super layoutSubviews]; +} + - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons { UITouch *touch = [touches anyObject]; @@ -189,9 +212,27 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { + if (!CGAffineTransformIsIdentity(m_view.transform)) { + qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; + return; + } + + // Since we don't support transformations on the UIView, we can set the frame + // directly and let UIKit deal with translating that into bounds and center. + m_view.frame = toCGRect(rect); + + updateGeometry(rect); +} + +void QIOSWindow::updateGeometry(const QRect &rect) +{ + // The baseclass implementation will store the geometry, and allows use to + // re-use the baseclass geometry() implementation, which just returns rect. QPlatformWindow::setGeometry(rect); - qDebug() << __FUNCTION__ << "not implemented"; + // We inform Qt about new geometry, which will trigger resize and + // expose events for the application. + QWindowSystemInterface::handleGeometryChange(window(), rect); } GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const -- cgit v1.2.3 From 3241f37711bd35988c7a21cc8a4833ec2fa3132d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 9 Nov 2012 17:20:47 +0100 Subject: iOS: Implement QPlatformWindow::setWindowState() In both maximized and fullscreen modes we assume that we can use the availableGeometry() of the QScreen, but of course this depends on us showing or hiding the statusbar first, as well as QScreen actually returning the right availableGeometry when the statusbar is shown. The latter is not the case right now, as we initialize QScreen before UIApplication has been set up and UIScreen has had a chance to init itself based on the precense of a statusbar or not. Change-Id: Id44dee3550f7135ffe2852b377bb6c7b6d522d68 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d16e17124d..4e1970d4d4 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,6 +85,8 @@ public: void setGeometry(const QRect &rect); void updateGeometry(const QRect &rect); + void setWindowState(Qt::WindowState state); + GLuint framebufferObject(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index feabaeb47a..cccd5ab133 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -203,6 +203,8 @@ QIOSWindow::QIOSWindow(QWindow *window) if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; } + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() @@ -235,6 +237,22 @@ void QIOSWindow::updateGeometry(const QRect &rect) QWindowSystemInterface::handleGeometryChange(window(), rect); } +void QIOSWindow::setWindowState(Qt::WindowState state) +{ + // FIXME: Figure out where or how we should disable/enable the statusbar. + // Perhaps setting QWindow to maximized should also mean that we'll show + // the statusbar, and vice versa for fullscreen? + + switch (state) { + case Qt::WindowMaximized: + case Qt::WindowFullScreen: + setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + break; + default: + break; + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From e71ca36161626020f7c641dcc83c0c02dc4d561b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 11 Nov 2012 16:32:54 +0100 Subject: iOS: Ensure UIApplicationMain is started before QApplication by wrapping main() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For the typical Qt app the developer will have an existing main() that looks something like: int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); return app.exec(); } To support this, we provide our own 'main' function in the qtmain static library that we link into the application, which calls UIApplicationMain and redirects to the 'main' function of the application after the event loop has started spinning. For this to work, the applications 'main' function needs to manually be renamed 'qt_main' for now. In a later patch, this renaming will happen automatically by redefining main from either a header file, or more likely, from the Makefile created by qmake. For the case of an iOS developer wanting to use Qt in their existing app the main will look something like: int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } This is supported right now by just linking in libqios.a without libqiosmain.a. QGuiApplication should then be created e.g inside the native apps application delegate (but QGuiApplication::exec should not be called). In the future, we plan to but use a wrapper library that brings in all the Qt dependencies into one single static library. This library will not link against qtmain, so there won't be a symbol clash if the -ObjC linker option is used. We should then add the required magic to the future Objective-C convenience wrapper for QML to bring up a QGuiApplication, which would allow using Qt from storyboards and NIBs. This would also be the place to inject our own application delegate into the mix, while proxying the delegate callbacks to the user's application delegate. Change-Id: Iba5ade114b27216be8285f36100fd735a08b9d59 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/ios.pro | 30 +------ src/plugins/platforms/ios/main.mm | 69 --------------- src/plugins/platforms/ios/plugin.mm | 69 +++++++++++++++ src/plugins/platforms/ios/plugin.pro | 30 +++++++ .../platforms/ios/qiosapplicationdelegate.h | 3 + .../platforms/ios/qiosapplicationdelegate.mm | 31 ++----- src/plugins/platforms/ios/qioseventdispatcher.mm | 14 +--- src/plugins/platforms/ios/qiosintegration.mm | 12 +++ src/plugins/platforms/ios/qioswindow.mm | 9 +- src/plugins/platforms/ios/qtmain.mm | 98 ++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.pro | 8 ++ 11 files changed, 234 insertions(+), 139 deletions(-) delete mode 100644 src/plugins/platforms/ios/main.mm create mode 100644 src/plugins/platforms/ios/plugin.mm create mode 100644 src/plugins/platforms/ios/plugin.pro create mode 100644 src/plugins/platforms/ios/qtmain.mm create mode 100644 src/plugins/platforms/ios/qtmain.pro diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro index 2fe6a4cb3f..842ff17f1c 100644 --- a/src/plugins/platforms/ios/ios.pro +++ b/src/plugins/platforms/ios/ios.pro @@ -1,29 +1,3 @@ -TARGET = qios +TEMPLATE = subdirs -load(qt_plugin) -DESTDIR = $$QT.gui.plugins/platforms - -QT += core-private gui-private platformsupport-private -LIBS += -framework UIKit -framework QuartzCore - -OBJECTIVE_SOURCES = main.mm \ - qiosintegration.mm \ - qioswindow.mm \ - qiosscreen.mm \ - qioseventdispatcher.mm \ - qiosbackingstore.mm \ - qiosapplicationdelegate.mm \ - qioscontext.mm - -HEADERS = qiosintegration.h \ - qioswindow.h \ - qiosscreen.h \ - qioseventdispatcher.h \ - qiosbackingstore.h \ - qiosapplicationdelegate.h \ - qioscontext.h - -#HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target +SUBDIRS += plugin.pro qtmain.pro diff --git a/src/plugins/platforms/ios/main.mm b/src/plugins/platforms/ios/main.mm deleted file mode 100644 index 6a04770e3e..0000000000 --- a/src/plugins/platforms/ios/main.mm +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include "qiosintegration.h" - -QT_BEGIN_NAMESPACE - -class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") - public: - QPlatformIntegration *create(const QString&, const QStringList&); -}; - -QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) -{ - Q_UNUSED(paramList); - if (system.toLower() == "ios") - return new QIOSIntegration; - - return 0; -} - -QT_END_NAMESPACE - -#include "main.moc" - -Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm new file mode 100644 index 0000000000..3701ac7e28 --- /dev/null +++ b/src/plugins/platforms/ios/plugin.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qiosintegration.h" + +QT_BEGIN_NAMESPACE + +class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "ios.json") + public: + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QPlatformIntegration * QIOSIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "ios") + return new QIOSIntegration; + + return 0; +} + +QT_END_NAMESPACE + +#include "plugin.moc" + +Q_IMPORT_PLUGIN(QIOSIntegrationPlugin) diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro new file mode 100644 index 0000000000..8a2f63442d --- /dev/null +++ b/src/plugins/platforms/ios/plugin.pro @@ -0,0 +1,30 @@ +TARGET = qios + +load(qt_plugin) + +QT += core-private gui-private platformsupport-private +LIBS += -framework UIKit -framework QuartzCore + +OBJECTIVE_SOURCES = \ + plugin.mm \ + qiosintegration.mm \ + qioswindow.mm \ + qiosscreen.mm \ + qioseventdispatcher.mm \ + qiosbackingstore.mm \ + qiosapplicationdelegate.mm \ + qioscontext.mm + +HEADERS = \ + qiosintegration.h \ + qioswindow.h \ + qiosscreen.h \ + qioseventdispatcher.h \ + qiosbackingstore.h \ + qiosapplicationdelegate.h \ + qioscontext.h + +#HEADERS = qiossoftwareinputhandler.h + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h index 10e415831d..442b37f1b3 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.h +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -48,3 +48,6 @@ @end +@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate +@end + diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 1b3dc18dd7..41a3fff84f 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -45,34 +45,13 @@ @implementation QIOSApplicationDelegate +@synthesize window; + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(application) Q_UNUSED(launchOptions) - // If this application delegate is instanciated, it means that - // this plugin also created UIApplication. We then also create a - // window with a view controller, and set all QWindow views - // as children of the controller view: - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; - - QWindowList windows = QGuiApplication::topLevelWindows(); - for (int i=0; i(windows[i]->handle())) { - UIView *winView = w->nativeView(); - if (winView && !winView.superview) - [controller.view addSubview:winView]; - } - } - - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - controller.view.backgroundColor = [UIColor magentaColor]; - - [self.window makeKeyAndVisible]; return YES; } @@ -104,6 +83,12 @@ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } +- (void)dealloc +{ + [window release]; + [super dealloc]; +} + @end diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 252e375a54..9d455370c0 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -191,23 +191,13 @@ bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) m_interrupted = false; bool eventsProcessed = false; - UIApplication *uiApplication = [UIApplication sharedApplication]; bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents; bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec); bool useExecMode = execFlagSet && !excludeUserEvents; if (useExecMode) { - if (!uiApplication) { - // No UIApplication has been started yet. We therefore start it now. Note that application - // developers are free to call UIApplicationMain themselves instead of QApplication::exec() - @autoreleasepool { - QCoreApplicationPrivate *qAppPriv = static_cast(QObjectPrivate::get(qApp)); - return UIApplicationMain(qAppPriv->argc, qAppPriv->argv, nil, NSStringFromClass([QIOSApplicationDelegate class])); - } - } else { - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); - } + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted); eventsProcessed = true; } else { if (!(flags & QEventLoop::WaitForMoreEvents)) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index d00d4a077f..fed278bffe 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -56,6 +56,18 @@ QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { + if (![UIApplication sharedApplication]) { + qWarning() + << "Error: You are creating QApplication before calling UIApplicationMain.\n" + << "If you are writing a native iOS application, and only want to use Qt for\n" + << "parts of the application, a good place to create QApplication is from within\n" + << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n" + << "If you instead create a cross-platform Qt application and do not intend to call\n" + << "UIApplicationMain, you need to link in libqtmain.a, and substitute main with qt_main.\n" + << "This is normally done automatically by qmake.\n"; + exit(-1); + } + screenAdded(m_screen); } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cccd5ab133..5701ac8aa2 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -198,13 +198,8 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) { - UIApplication *uiApplication = [UIApplication sharedApplication]; - if (uiApplication) { - if ([uiApplication.delegate isMemberOfClass:[QIOSApplicationDelegate class]]) - [uiApplication.delegate.window.rootViewController.view addSubview:m_view]; - } - - setWindowState(window->windowState()); + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; } QIOSWindow::~QIOSWindow() diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm new file mode 100644 index 0000000000..9b4ce9918e --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.mm @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosapplicationdelegate.h" + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([QIOSMainWrapperApplicationDelegate class])); + } +} + +extern int qt_main(int argc, char *argv[]); + +@implementation QIOSMainWrapperApplicationDelegate + +- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + // We may have a window already from a NIB or storyboard + if (!self.window) { + // If not, we create one ourselves + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + UIViewController *controller = [[UIViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; + + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + + [self.window makeKeyAndVisible]; + } + + // We schedule the main-redirection for the next eventloop pass so that we + // can return from this function and let UIApplicationMain finish its job. + [NSTimer scheduledTimerWithTimeInterval:.01f target:self + selector:@selector(runUserMain) userInfo:nil repeats:NO]; + + if ([QIOSApplicationDelegate instancesRespondToSelector:_cmd]) + return [super application:application willFinishLaunchingWithOptions:launchOptions]; + else + return YES; +} + +- (void)runUserMain +{ + NSArray *arguments = [[NSProcessInfo processInfo] arguments]; + int argc = arguments.count; + char **argv = new char*[argc]; + for (int i = 0; i < argc; ++i) { + NSString *arg = [arguments objectAtIndex:i]; + argv[i] = reinterpret_cast(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]])); + strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]); + } + + qt_main(argc, argv); + delete[] argv; +} + +@end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro new file mode 100644 index 0000000000..7835c88eac --- /dev/null +++ b/src/plugins/platforms/ios/qtmain.pro @@ -0,0 +1,8 @@ +TARGET = qiosmain + +load(qt_plugin) + +OBJECTIVE_SOURCES = qtmain.mm + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target -- cgit v1.2.3 From d8b3465dd3482040f0de077f87545415a1a2a5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2012 14:54:13 +0100 Subject: iOS: Don't use IOKit in QTestLib, it's a private framework on iOS Change-Id: I271a480b79c7768942911a28c84d6bb5a8d840d3 Reviewed-by: Richard Moe Gustavsen --- src/testlib/qtestcase.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f9f21c6a8f..ef8ffa570b 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -82,7 +82,7 @@ #include #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) #include #endif @@ -2078,7 +2078,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) int callgrindChildExitCode = 0; #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0); IOPMAssertionID powerID; #endif @@ -2093,7 +2093,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); #endif -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { CFStringRef reasonForActivity= CFSTR("No Display Sleep"); IOReturn ok = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &powerID); @@ -2146,7 +2146,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) } QTestLog::stopLogging(); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { IOPMAssertionRelease(powerID); } @@ -2163,7 +2163,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) QSignalDumper::endDump(); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) if (macNeedsActivate) { IOPMAssertionRelease(powerID); } -- cgit v1.2.3 From f124e098ced89c3014d8bbc08a20db658d1cc7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2012 14:58:11 +0100 Subject: iOS: Set PLUGIN_TYPE = platforms before loading(qt_plugins) This takes care of setting INSTALLS for us, so we can skip that. Change-Id: I351cb9ec08b632fd9867d85e2c5fa59d8e5acc9d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 4 +--- src/plugins/platforms/ios/qtmain.pro | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 8a2f63442d..222d8c8445 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -1,5 +1,6 @@ TARGET = qios +PLUGIN_TYPE = platforms load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -25,6 +26,3 @@ HEADERS = \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7835c88eac..49ada385bb 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -1,8 +1,6 @@ TARGET = qiosmain +PLUGIN_TYPE = platforms load(qt_plugin) OBJECTIVE_SOURCES = qtmain.mm - -target.path += $$[QT_INSTALL_PLUGINS]/platforms -INSTALLS += target -- cgit v1.2.3 From 9d2e623451d4a4d695bc41e750a3218608c2546c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 12 Nov 2012 15:20:06 +0100 Subject: iOS: insert Digia license headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove Nokia. Change-Id: Iec7095ef4e3099453b6103814e826039b377ecce Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosintegration.mm | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.h | 48 ++++++++++----------- src/plugins/platforms/ios/qiosscreen.mm | 48 ++++++++++----------- .../platforms/ios/qiossoftwareinputhandler.h | 50 +++++++++++----------- 6 files changed, 144 insertions(+), 146 deletions(-) diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm index 3701ac7e28..a93b6037ad 100644 --- a/src/plugins/platforms/ios/plugin.mm +++ b/src/plugins/platforms/ios/plugin.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 11c17aced9..d5f79857f7 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index fed278bffe..a417021cbd 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 8d67b1ecdf..f17f1c1d70 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index effd19070a..efeacb8cb6 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -1,38 +1,38 @@ /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/plugins/platforms/ios/qiossoftwareinputhandler.h index 99e8fac61b..5dad6b8d86 100644 --- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h +++ b/src/plugins/platforms/ios/qiossoftwareinputhandler.h @@ -1,40 +1,38 @@ - - /**************************************************************************** ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** ** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ -- cgit v1.2.3 From b3eccb0c15a3d4c9bee236c82c9a155c8752b66c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 13 Nov 2012 17:15:19 +0100 Subject: iOS: add QIOSOrientationListener MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QIOSScreen will use this to listen for orientation changes from UIDevice. Change-Id: I5a30f3808f8b9b885303608ce2fc1316c962898b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + .../platforms/ios/qiosorientationlistener.h | 65 +++++++++++++ .../platforms/ios/qiosorientationlistener.mm | 108 +++++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h create mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 222d8c8445..ab49115ed3 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,6 +14,7 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ + qiosorientationlistener.mm \ qioscontext.mm HEADERS = \ @@ -23,6 +24,7 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ + qiosorientationlistener.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h new file mode 100644 index 0000000000..c7b481a03a --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSORIENTATIONLISTENER_H +#define QIOSORIENTATIONLISTENER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QIOSScreen; +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); + +QT_END_NAMESPACE + +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; + Qt::ScreenOrientation m_orientation; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; + +@end + +#endif + diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm new file mode 100644 index 0000000000..626e43129b --- /dev/null +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosorientationlistener.h" +#include "qiosscreen.h" +#include + +QT_BEGIN_NAMESPACE + +Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +QT_END_NAMESPACE + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); + if (qtOrientation != -1) { + m_orientation = qtOrientation; + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); + } +} + +@end + -- cgit v1.2.3 From 92252bcb93b2e8ba8cefeadf8cc0330c8ff1c47b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:06:22 +0100 Subject: iOS: let QIOSScreen start/stop listening for device orientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the qpa docs, we only need to listen for device orientation if orientationUpdateMask is non-zero Change-Id: Id5e828cdff9a08794c8a029e11763cc037e1b959 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 7 +++++++ src/plugins/platforms/ios/qiosscreen.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index f17f1c1d70..ed21e54f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,6 +45,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -52,6 +53,7 @@ class QIOSScreen : public QPlatformScreen { public: QIOSScreen(unsigned int screenIndex); + ~QIOSScreen(); enum ScreenIndex { MainScreen = 0 }; @@ -61,6 +63,10 @@ public: QImage::Format format() const; QSizeF physicalSize() const; + Qt::ScreenOrientation nativeOrientation() const; + Qt::ScreenOrientation orientation() const; + void setOrientationUpdateMask(Qt::ScreenOrientations mask); + UIScreen *uiScreen() const; private: @@ -68,6 +74,7 @@ private: QRect m_geometry; int m_depth; QSizeF m_physicalSize; + QIOSOrientationListener *m_orientationListener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index efeacb8cb6..00deaa2fc0 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -41,6 +41,7 @@ #include "qiosscreen.h" #include "qioswindow.h" +#include #include @@ -68,6 +69,7 @@ static QString deviceModelIdentifier() QIOSScreen::QIOSScreen(unsigned int screenIndex) : QPlatformScreen() , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(screenIndex, [[UIScreen screens] count] - 1)]) + , m_orientationListener(0) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -97,6 +99,11 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) [pool release]; } +QIOSScreen::~QIOSScreen() +{ + [m_orientationListener release]; +} + QRect QIOSScreen::geometry() const { return m_geometry; @@ -123,6 +130,26 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +Qt::ScreenOrientation QIOSScreen::nativeOrientation() const +{ + return Qt::PortraitOrientation; +} + +Qt::ScreenOrientation QIOSScreen::orientation() const +{ + return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); +} + +void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) +{ + if (m_orientationListener && mask == Qt::PrimaryOrientation) { + [m_orientationListener release]; + m_orientationListener = 0; + } else if (!m_orientationListener) { + m_orientationListener = [[QIOSOrientationListener alloc] initWithQIOSScreen:this]; + } +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; -- cgit v1.2.3 From 72f66a8ee57ad3865d25e0157179d042a474cfff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 14:02:04 +0100 Subject: iOS: add function convertToUIOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6145121d49eb3f5bab3f2a1ba57c779ec0b01023 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosorientationlistener.h | 1 + .../platforms/ios/qiosorientationlistener.mm | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h index c7b481a03a..9d2e902ce1 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ b/src/plugins/platforms/ios/qiosorientationlistener.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QIOSScreen; Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm index 626e43129b..264b77f14f 100644 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ b/src/plugins/platforms/ios/qiosorientationlistener.mm @@ -69,6 +69,28 @@ Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrienta return qtOrientation; } +UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + QT_END_NAMESPACE @implementation QIOSOrientationListener -- cgit v1.2.3 From fa731cddd16aed426f7c73bf4807475f0b087d4c Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 09:24:41 +0100 Subject: iOS: add QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need our own viewcontroller to better control which orientations iOS can enter, and also ito be able to stop auto-rotation. We stop auto-rotation to happend by default, since this is how Qt wants it (it is seen as the responsibility of the application). Change-Id: Id07a96e355396752fffd28984af528aeb0b7c3e3 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 + src/plugins/platforms/ios/qiosviewcontroller.h | 46 +++++++++++++++++++ src/plugins/platforms/ios/qiosviewcontroller.mm | 60 +++++++++++++++++++++++++ src/plugins/platforms/ios/qtmain.mm | 3 +- src/plugins/platforms/ios/qtmain.pro | 5 ++- 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.h create mode 100644 src/plugins/platforms/ios/qiosviewcontroller.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index ab49115ed3..12c5c6db01 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -15,6 +15,7 @@ OBJECTIVE_SOURCES = \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ + qiosviewcontroller.mm \ qioscontext.mm HEADERS = \ @@ -25,6 +26,7 @@ HEADERS = \ qiosbackingstore.h \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ + qiosviewcontroller.h \ qioscontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h new file mode 100644 index 0000000000..d5a61cb3f4 --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import + +@interface QIOSViewController : UIViewController +@end + diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm new file mode 100644 index 0000000000..5381b3a21e --- /dev/null +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#import "qiosviewcontroller.h" + +@implementation QIOSViewController + +- (BOOL)shouldAutorotate +{ + return NO; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + // We need to tell iOS that we support all orientations in order to set + // status bar orientation when application content orientation changes. + // But we return 'NO' above when asked if we 'shouldAutorotate': + return UIInterfaceOrientationMaskAll; +} + +@end + diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 9b4ce9918e..61756edc93 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" int main(int argc, char *argv[]) { @@ -58,7 +59,7 @@ extern int qt_main(int argc, char *argv[]); if (!self.window) { // If not, we create one ourselves self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - UIViewController *controller = [[UIViewController alloc] init]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; self.window.rootViewController = controller; controller.view = [[UIView alloc] init]; diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 49ada385bb..7c4c4ab398 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,4 +3,7 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) -OBJECTIVE_SOURCES = qtmain.mm +OBJECTIVE_SOURCES = qtmain.mm \ + qiosviewcontroller.mm + +HEADERS = qiosviewcontroller.h -- cgit v1.2.3 From 575d28a6fd62c83c82de5dfc0c34013948c0c9bd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 15 Nov 2012 13:28:59 +0100 Subject: iOS: handle content orientation feedback from application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2bfb4ee4840086dcd3ec85c2ee7e8769e76d2700 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4e1970d4d4..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5701ac8aa2..e220312d15 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,6 +43,7 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" +#include "qiosorientationlistener.h" #import @@ -248,6 +249,14 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) +{ + // Keep the status bar in sync with content orientation. This will ensure + // that the task bar (and associated gestures) are aligned correctly: + UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 55f0bce0945a2f2b28e2454fbc03b1efd61819e4 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 16 Nov 2012 11:14:34 +0100 Subject: iOS: implement requestWindowOrientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The application is normally supposed to rotate the content on its own, but can call requestWindowOrientation to ask the window manager to do it instead. This way of integrating orientation with the OS is fragile, because: 1. In some cases, you cannot stop the OS from rotating at all (tablets). 2. It would be more safe to inform the window manager up-front which orientations it could rotate into, rather that relying on a function you call call to force this later on. 3. When the QML application starts, its a bit late to inform the platform plugin that it supports e.g landscape. If the OS is in landscape already, the plugin must still assume that the app operates in portrait (doing rotating on its own) until requestWindowOrientation is called. This might cause the app to first start up in portrait, just to rotate into landscape. On iOS, it seems like we can handle the first two cases. The third need some more investigation. We should anyway investigate if we need some adjustment to the Qt API. Change-Id: I50638b78d469ab70820a787de86a2f1981470786 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.h | 8 +++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 26 ++++++++++++++++++++++--- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 17 ++++++++++++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index d5a61cb3f4..780ec7adab 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,13 @@ ****************************************************************************/ #import +#import -@interface QIOSViewController : UIViewController +@interface QIOSViewController : UIViewController { +@public + bool m_shouldAutorotate; +} + +-(bool)rotateToDeviceOrientation; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 5381b3a21e..8b1a085cc5 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,12 +43,32 @@ @implementation QIOSViewController -- (BOOL)shouldAutorotate +-(id)init { - return NO; + self = [super init]; + if (self) { + m_shouldAutorotate = NO; + } + return self; } -- (NSUInteger)supportedInterfaceOrientations +-(bool)rotateToDeviceOrientation +{ + if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { + m_shouldAutorotate = YES; + [UIViewController attemptRotationToDeviceOrientation]; + m_shouldAutorotate = NO; + return true; + } + return false; +} + +-(BOOL)shouldAutorotate +{ + return m_shouldAutorotate; +} + +-(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..e4c3a6a17c 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,6 +87,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e220312d15..c1f14f22ef 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -44,6 +44,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosorientationlistener.h" +#include "qiosviewcontroller.h" #import @@ -257,6 +258,22 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } +Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) +{ + if (!m_view.window) + return Qt::PortraitOrientation; + UIViewController *viewController = m_view.window.rootViewController; + if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { + return convertToQtOrientation(viewController.interfaceOrientation); + } else { + QIOSViewController *qiosViewController = static_cast(viewController); + if ([qiosViewController rotateToDeviceOrientation]) + return orientation; + else + return convertToQtOrientation(viewController.interfaceOrientation); + } +} + GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 7f7d75201271bc1b87a8607a78c04aeab1ad3513 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 19 Nov 2012 13:58:11 +0100 Subject: iOS: use 'self' rather than 'super' pointer in initWithQIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we use super, our own initWithFrame override will never be called. Change-Id: I606beb653239cdfc46f41db4ec0791dfa5d4edea Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c1f14f22ef..4e10c19ecc 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -72,7 +72,7 @@ static QRect fromCGRect(const CGRect &rect) -(id)initWithQIOSWindow:(QIOSWindow *)window { - if (self = [super initWithFrame:toCGRect(window->geometry())]) + if (self = [self initWithFrame:toCGRect(window->geometry())]) m_qioswindow = window; return self; -- cgit v1.2.3 From ad4cf5068cd39b9ca16bdd9705d0a3ef61783d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 16 Nov 2012 07:36:49 +0100 Subject: iOS: Don't recreate paint device on beginPaint() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This causes painting errors. Use one lazily-created device that is used for the lifetime of the backing store. Change-Id: Ib36b6f1d6c9f958304dc8403cf17e5d71136469a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 71f14fdd91..6cefc03377 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -60,6 +60,7 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window) QIOSBackingStore::~QIOSBackingStore() { delete m_context; + delete m_device; } void QIOSBackingStore::beginPaint(const QRegion &) @@ -68,7 +69,8 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - m_device = new QOpenGLPaintDevice(window()->size()); + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() @@ -86,8 +88,6 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin void QIOSBackingStore::endPaint() { - delete m_device; - // Calling makeDone() on the context here would be an option, // but is not needed, and would actually add some overhead. } -- cgit v1.2.3 From 5d878cae1d090b9c7d5730a85667e569e67c17d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 14:13:40 +0100 Subject: iOS: Remove requestWindowOrientation from QIOSWindow The API is scheduled to be removed in qtbase in time for Qt 5.0. Change-Id: Ie34d6cb79fcd81b0ce02892529e3e7184ddfa096 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.h | 7 +------ src/plugins/platforms/ios/qiosviewcontroller.mm | 22 +--------------------- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 16 ---------------- 4 files changed, 2 insertions(+), 44 deletions(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 780ec7adab..605f0f5b4c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -42,11 +42,6 @@ #import #import -@interface QIOSViewController : UIViewController { -@public - bool m_shouldAutorotate; -} - --(bool)rotateToDeviceOrientation; +@interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8b1a085cc5..a807dc2132 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,29 +43,9 @@ @implementation QIOSViewController --(id)init -{ - self = [super init]; - if (self) { - m_shouldAutorotate = NO; - } - return self; -} - --(bool)rotateToDeviceOrientation -{ - if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) { - m_shouldAutorotate = YES; - [UIViewController attemptRotationToDeviceOrientation]; - m_shouldAutorotate = NO; - return true; - } - return false; -} - -(BOOL)shouldAutorotate { - return m_shouldAutorotate; + return NO; } -(NSUInteger)supportedInterfaceOrientations diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e4c3a6a17c..b20c1c4fc5 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,7 +87,6 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); - Qt::ScreenOrientation requestWindowOrientation(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4e10c19ecc..0b2b5fcfd7 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -258,22 +258,6 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -Qt::ScreenOrientation QIOSWindow::requestWindowOrientation(Qt::ScreenOrientation orientation) -{ - if (!m_view.window) - return Qt::PortraitOrientation; - UIViewController *viewController = m_view.window.rootViewController; - if (!viewController || [viewController isKindOfClass:[QIOSViewController class]] == false) { - return convertToQtOrientation(viewController.interfaceOrientation); - } else { - QIOSViewController *qiosViewController = static_cast(viewController); - if ([qiosViewController rotateToDeviceOrientation]) - return orientation; - else - return convertToQtOrientation(viewController.interfaceOrientation); - } -} - GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { static GLuint framebuffer = 0; -- cgit v1.2.3 From 599c7a5ab91f44cb9ed5f12f65d58ff9d543c930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 15:50:20 +0100 Subject: iOS: Set initial window state on window creation When showing a QWindow the window state is set first, and then the window is made visible. The latter is the step that creates the platform window, so we need to pick up the already set window state in our constructor and respect that. Change-Id: I54fe6c4ebcd3c9504614d2d48bd21f0d76adf3b7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 0b2b5fcfd7..daeb86fb62 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -202,6 +202,8 @@ QIOSWindow::QIOSWindow(QWindow *window) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + + setWindowState(window->windowState()); } QIOSWindow::~QIOSWindow() -- cgit v1.2.3 From 189503933a9e59da22d6415e588a44c87d67c2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2012 16:42:56 +0100 Subject: iOS: Enable the ShowIsFullScreen style-hint so that show() implies fullscreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may need to qualify this setting for UC2, so that the user may still create windows as sub-controls of a regular iOS user interface, but for UC1 it makes sense. Change-Id: I1a7019f901fabed8b5b9cbb18a929913780e6595 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index d5f79857f7..363d267716 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -60,6 +60,8 @@ public: QPlatformFontDatabase *fontDatabase() const; + QVariant styleHint(StyleHint hint) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index a417021cbd..b37e803455 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -106,6 +106,16 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QVariant QIOSIntegration::styleHint(StyleHint hint) const +{ + switch (hint) { + case ShowIsFullScreen: + return true; + default: + return QPlatformIntegration::styleHint(hint); + } +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); -- cgit v1.2.3 From 3a59fc4c97a3658b9712fa214778008bbf914cf9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 13:34:51 +0100 Subject: iOS: when in fullscreen, dont respond to geometry changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to be in fullscreen, we should not respond to geometry changes. Instead we should bookkeep the requested geometry and set it when/if the window enters Qt::WindowNoState later. Change-Id: Ieaf4756b2a966212c8e1738af9df175a58786a75 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 34 ++++++++++++++------------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b20c1c4fc5..df632e672e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,7 +83,6 @@ public: ~QIOSWindow(); void setGeometry(const QRect &rect); - void updateGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index daeb86fb62..c91c0b2f35 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,13 +109,11 @@ static QRect fromCGRect(const CGRect &rect) // the position of our QWindow (and platform window) will only get updated // when the size is also changed. - if (CGAffineTransformIsIdentity(self.transform)) { - // Reflect the new size (and possibly also position) in the QWindow - m_qioswindow->updateGeometry(fromCGRect(self.frame)); - } else { - qWarning() << "QIOSPlatformWindow's UIView has transform set, ignoring geometry updates"; - } + if (!CGAffineTransformIsIdentity(self.transform)) + qWarning() << m_qioswindow->window() + << "is backed by a UIView that has a transform set. This is not supported."; + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); [super layoutSubviews]; } @@ -218,22 +216,17 @@ void QIOSWindow::setGeometry(const QRect &rect) return; } + // If the window is in fullscreen, just bookkeep the requested + // geometry in case the window goes into Qt::WindowNoState later: + QPlatformWindow::setGeometry(rect); + if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) + return; + // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. + // Changing the size of the view will end up in a call to -[EAGLView layoutSubviews] + // which will update QWindowSystemInterface with the new size. m_view.frame = toCGRect(rect); - - updateGeometry(rect); -} - -void QIOSWindow::updateGeometry(const QRect &rect) -{ - // The baseclass implementation will store the geometry, and allows use to - // re-use the baseclass geometry() implementation, which just returns rect. - QPlatformWindow::setGeometry(rect); - - // We inform Qt about new geometry, which will trigger resize and - // expose events for the application. - QWindowSystemInterface::handleGeometryChange(window(), rect); } void QIOSWindow::setWindowState(Qt::WindowState state) @@ -245,9 +238,10 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: case Qt::WindowFullScreen: - setGeometry(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); break; default: + m_view.frame = toCGRect(geometry()); break; } } -- cgit v1.2.3 From 2d4e96352a0f52351e0fa69273b064a66d460c04 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:15:21 +0100 Subject: iOS: one 'transform' warning per window is sufficient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The layoutSubviews function will be called when the geometry changes, and we will catch the transform issue there for both UC1 and UC2 Change-Id: I29578bbc5b3091c86fbe69c7095ff280a64be458 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c91c0b2f35..7f03e0d46a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -211,11 +211,6 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setGeometry(const QRect &rect) { - if (!CGAffineTransformIsIdentity(m_view.transform)) { - qWarning() << "Setting the geometry of a QWindow with a transform set on the UIView is not supported"; - return; - } - // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: QPlatformWindow::setGeometry(rect); -- cgit v1.2.3 From 0d9a50380c2d3ecc33f632f9f0e158c3a8cd2099 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 15:28:13 +0100 Subject: iOS: when in fullscreen, autoresize the view when the device rotates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tell the view that backs QWindow to autoresize itself when the superview (view of the root view controller) changes size. This will typically happen when the device changes orientation. Change-Id: Ib7c4dff9112d57f60012d3f0837677e09088bcaf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7f03e0d46a..2b97695a10 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -234,9 +234,11 @@ void QIOSWindow::setWindowState(Qt::WindowState state) case Qt::WindowMaximized: case Qt::WindowFullScreen: m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; default: m_view.frame = toCGRect(geometry()); + m_view.autoresizingMask = UIViewAutoresizingNone; break; } } -- cgit v1.2.3 From b1cfa62ff45cc4b5c035fc5dbe49461e9fe6052a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 7 Dec 2012 16:22:48 +0100 Subject: iOS: let fullscreen geometry take orientation into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since UIScreen is orientation agnostic, we need to look at the view of the top level view controller instead to determine available geometry. Change-Id: I3789ab7972a9970e46fbc8af81f2b7199e5ca5d1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2b97695a10..266000d2de 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -232,10 +232,13 @@ void QIOSWindow::setWindowState(Qt::WindowState state) switch (state) { case Qt::WindowMaximized: - case Qt::WindowFullScreen: - m_view.frame = toCGRect(QRect(QPoint(0, 0), window()->screen()->availableSize())); + case Qt::WindowFullScreen: { + // Since UIScreen does not take orientation into account when + // reporting geometry, we need to look at the top view instead: + CGSize fullscreenSize = m_view.window.rootViewController.view.bounds.size; + m_view.frame = CGRectMake(0, 0, fullscreenSize.width, fullscreenSize.height); m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - break; + break; } default: m_view.frame = toCGRect(geometry()); m_view.autoresizingMask = UIViewAutoresizingNone; -- cgit v1.2.3 From a1c9f565521f971adbb1e6aad6b82d194f1a1905 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 10 Dec 2012 10:18:59 +0100 Subject: iOS: update QPlatformWindow::geometry() when UIView changes size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that QWindow::geometry needs to be updated manually by the platform plugin, and not indirectly trough QWindowSystemInterface::handleGeometryChange as first assumed. We now always report the _actual_ geometry of the UIView (which also takes the status bar into account) to QWindow, and remember the _requested_ geometry of the window to use whenever the state of the window changes. Change-Id: Iea940173d26fb6af701234379cae914215dae984 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index df632e672e..2a762d2bdc 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -93,6 +93,7 @@ public: private: EAGLView *m_view; + QRect m_requestedGeometry; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 266000d2de..b209bbc159 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -113,7 +113,9 @@ static QRect fromCGRect(const CGRect &rect) qWarning() << m_qioswindow->window() << "is backed by a UIView that has a transform set. This is not supported."; - QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), fromCGRect(self.frame)); + QRect geometry = fromCGRect(self.frame); + m_qioswindow->QPlatformWindow::setGeometry(geometry); + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); [super layoutSubviews]; } @@ -197,6 +199,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_requestedGeometry(QPlatformWindow::geometry()) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -213,7 +216,7 @@ void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: - QPlatformWindow::setGeometry(rect); + m_requestedGeometry = rect; if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) return; @@ -240,7 +243,7 @@ void QIOSWindow::setWindowState(Qt::WindowState state) m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; } default: - m_view.frame = toCGRect(geometry()); + m_view.frame = toCGRect(m_requestedGeometry); m_view.autoresizingMask = UIViewAutoresizingNone; break; } -- cgit v1.2.3 From 8dde67fcd33fc35fe95262bd7acb6f7b5143fead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 16:40:40 +0100 Subject: iOS: Create QIOSBackingStore paint device lazily in paintDevice() Instead of constructor. Change-Id: I98cddd3f39add3e6f787c858b4d629325cc0f852 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6cefc03377..dfa41f0003 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,13 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); - if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { + if (!m_device) + m_device = new QOpenGLPaintDevice(window()->size()); + return m_device; } -- cgit v1.2.3 From d059866eb43a7415dd786a2bcba14f729d938675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:11:15 +0100 Subject: iOS: Keep QIOSBackingStore's paint device size in sync with the window Treating the paint-device as a thing wrapper around the OpenGL paint engine failed when the window was resized, as the paint engine would clip the drawing to the old size. We need to update the size in beginPaint. QBackingStore resize still behaves like before, and we emit a warning if the user tries to resize the backing-store to some other size than the window size, as that's not a supported use-case for our iOS backing store. Change-Id: I1a0eeb65fa9db8b5538dc69963d6fc84be6e63f1 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosbackingstore.mm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index dfa41f0003..6bae08ce2b 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -69,12 +69,14 @@ void QIOSBackingStore::beginPaint(const QRegion &) window()->setSurfaceType(QSurface::OpenGLSurface); m_context->makeCurrent(window()); + + static_cast(paintDevice())->setSize(window()->size()); } QPaintDevice *QIOSBackingStore::paintDevice() { if (!m_device) - m_device = new QOpenGLPaintDevice(window()->size()); + m_device = new QOpenGLPaintDevice; return m_device; } @@ -95,12 +97,16 @@ void QIOSBackingStore::endPaint() void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) { - Q_UNUSED(size); Q_UNUSED(staticContents); - // We don't need to resize the QOpenGLPaintDevice, as it's just a thin wrapper - // around the OpenGL paint-engine, and the real geometry is handled by the - // context and window. + // Resizing the backing store would in our case mean resizing the QWindow, + // as we cheat and use an QOpenGLPaintDevice that we target at the window. + // That's probably not what the user intended, so we ignore resizes of the + // backing store and always keep the paint device's size in sync with the + // window size in beginPaint(). + + if (size != window()->size()) + qWarning() << "QIOSBackingStore needs to have the same size as its window"; } QT_END_NAMESPACE -- cgit v1.2.3 From 21965187096f8bde7866b05459444793e1a6c1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 17:49:53 +0100 Subject: iOS: Update GL render buffers when the accociated window is resized We keep track of the with and height of the FBO's buffers, and update their storage if the window size has changed since last time. Change-Id: I97788b69e7067a5b5b9f28e8498cf1bc5d2cf6ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 2 + src/plugins/platforms/ios/qioscontext.mm | 16 +++---- src/plugins/platforms/ios/qioswindow.h | 9 ++++ src/plugins/platforms/ios/qioswindow.mm | 82 ++++++++++++++++++-------------- 4 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 102aaaa387..b45917832c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -62,6 +62,8 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; + GLuint defaultColorRenderbuffer(QPlatformSurface *) const; + QFunctionPointer getProcAddress(const QByteArray &procName); EAGLContext *nativeContext() const; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 8beb588b03..68db28212b 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -88,7 +88,8 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - return true; + // Ensures render buffers are set up and match the size of the window + return defaultColorRenderbuffer(surface) != 0; } void QIOSContext::doneCurrent() @@ -101,13 +102,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); [EAGLContext setCurrentContext:m_eaglContext]; - - GLint renderbuffer; - glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &renderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - + glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } @@ -116,6 +111,11 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const return static_cast(surface)->framebufferObject(*const_cast(this)); } +GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +{ + return static_cast(surface)->colorRenderbuffer(*const_cast(this)); +} + QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) { return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2a762d2bdc..4c55249046 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -88,12 +88,21 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); GLuint framebufferObject(const QIOSContext &context) const; + GLuint colorRenderbuffer(const QIOSContext &context) const; EAGLView *nativeView() const { return m_view; } private: EAGLView *m_view; QRect m_requestedGeometry; + + mutable struct GLData { + GLuint framebufferObject; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + } m_glData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b209bbc159..90734e58e8 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -116,6 +116,10 @@ static QRect fromCGRect(const CGRect &rect) QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); + + // If we have a new size here we need to resize the FBO's corresponding buffers, + // but we defer that to when the application calls makeCurrent. + [super layoutSubviews]; } @@ -200,6 +204,7 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_glData() { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; @@ -209,6 +214,13 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { + if (m_glData.framebufferObject) + glDeleteFramebuffers(1, &m_glData.framebufferObject); + if (m_glData.colorRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); + if (m_glData.depthRenderbuffer) + glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view release]; } @@ -259,56 +271,56 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const { - static GLuint framebuffer = 0; + if (!m_glData.framebufferObject) { + [EAGLContext setCurrentContext:context.nativeContext()]; - // FIXME: Cache context and recreate framebuffer if window - // is used with a different context then last time. + glGenFramebuffers(1, &m_glData.framebufferObject); + glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - if (!framebuffer) { - EAGLContext* eaglContext = context.nativeContext(); + glGenRenderbuffers(1, &m_glData.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [EAGLContext setCurrentContext:eaglContext]; + QSurfaceFormat requestedFormat = context.format(); + if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &m_glData.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - // Create the framebuffer and bind it - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + if (requestedFormat.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); + } + } - GLint width; - GLint height; + return m_glData.framebufferObject; +} - // Create a color renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s color attachment point. - GLuint colorRenderbuffer; - glGenRenderbuffers(1, &colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); - [eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); +GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +{ + if (!m_glData.colorRenderbuffer || + m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - // Create a depth or depth/stencil renderbuffer, allocate storage for it, - // and attach it to the framebuffer’s depth attachment point. - GLuint depthRenderbuffer; - glGenRenderbuffers(1, &depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); + [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); + + if (m_glData.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (requestedFormat.stencilBufferSize() > 0) { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); - } else { - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); + if (context.format().stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } - return framebuffer; + return m_glData.colorRenderbuffer; } QT_END_NAMESPACE -- cgit v1.2.3 From 31a76b978b3f1c08787e3f88987e3a396d5eec45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 19:27:30 +0100 Subject: iOS: Enable auto-rotation if no orientation update-mask has been set This is an intermediate heuristic until we have a proper API in Qt to deal with auto-rotation and orientation locking. Change-Id: I433992fa1c18d1670987f79e405a4501b6e5d365 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a807dc2132..3121597dba 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -41,18 +41,27 @@ #import "qiosviewcontroller.h" +#include +#include + @implementation QIOSViewController -(BOOL)shouldAutorotate { - return NO; + // For now we assume that if the application doesn't listen to orientation + // updates it means it would like to enable auto-rotation, and vice versa. + if (QGuiApplication *guiApp = qobject_cast(qApp)) + return !guiApp->primaryScreen()->orientationUpdateMask(); + else + return NO; + + // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. - // But we return 'NO' above when asked if we 'shouldAutorotate': return UIInterfaceOrientationMaskAll; } -- cgit v1.2.3 From 509697adc30f858ee3483c2b74e292c60b75ba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2012 20:00:27 +0100 Subject: iOS: Remove unnecessary const-trickery when passing QIOSContext to the window Change-Id: I56b3873342c1572ea6a651027e8f1a684cbe2a5a Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 68db28212b..00629a84ab 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -108,12 +108,12 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*const_cast(this)); + return static_cast(surface)->framebufferObject(*this); } GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const { - return static_cast(surface)->colorRenderbuffer(*const_cast(this)); + return static_cast(surface)->colorRenderbuffer(*this); } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) -- cgit v1.2.3 From d07bd1b22f6da2fcf961618b59f10f59d0a95d16 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:07:05 +0100 Subject: iOS: remove the view from the view hierarchy upon destruction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to remove the view that backs QWindow when the window is destroyed. Otherwise the view will still be visible on screen, but now with a dangling QWindow pointer. This fixes a crash that happens when closing dialogs. Change-Id: I9053c83c6db80a39f4f71a63993cc7ae73fc4196 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 90734e58e8..871a046c71 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -221,6 +221,7 @@ QIOSWindow::~QIOSWindow() if (m_glData.depthRenderbuffer) glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); + [m_view removeFromSuperview]; [m_view release]; } -- cgit v1.2.3 From 60294e0aa381419b897317e3eec208d98ca8b4aa Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 12:01:17 +0100 Subject: iOS: implement in QIOSWindow::setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QWindow is told to show/hide, we need to show/hide the backing UIView as well, otherwise the window will still be visible on screen. Change-Id: I806fdd8bb4afacbbc1c9c7381ba0a31195ee04ac Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4c55249046..3a05901ae7 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,7 @@ public: void setWindowState(Qt::WindowState state); void handleContentOrientationChange(Qt::ScreenOrientation orientation); + void setVisible(bool visible); GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 871a046c71..a2901efd1d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -225,6 +225,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +void QIOSWindow::setVisible(bool visible) +{ + QPlatformWindow::setVisible(visible); + [m_view setHidden:!visible]; +} + void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested -- cgit v1.2.3 From c558c5c1b82256fc8c8e9e6f947eda6164ea59e8 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 11 Dec 2012 15:12:40 +0100 Subject: iOS: add class QIOSInputContext (to handle keyboard) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will add an initial implementation of the QPlatformInputContext for dealing with the keyboard. Change-Id: I29c1cfbbebb8456977b8a1db0e966973cd2c24a5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosinputcontext.h | 69 +++++++++++++ src/plugins/platforms/ios/qiosinputcontext.mm | 134 ++++++++++++++++++++++++++ src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 7 ++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosinputcontext.h create mode 100644 src/plugins/platforms/ios/qiosinputcontext.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 12c5c6db01..d4fe25ef08 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -16,7 +16,8 @@ OBJECTIVE_SOURCES = \ qiosapplicationdelegate.mm \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ - qioscontext.mm + qioscontext.mm \ + qiosinputcontext.mm HEADERS = \ qiosintegration.h \ @@ -27,6 +28,7 @@ HEADERS = \ qiosapplicationdelegate.h \ qiosorientationlistener.h \ qiosviewcontroller.h \ - qioscontext.h + qioscontext.h \ + qiosinputcontext.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h new file mode 100644 index 0000000000..22782d183c --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSINPUTCONTEXT_H +#define QIOSINPUTCONTEXT_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +@class QIOSKeyboardListener; + +class QIOSInputContext : public QPlatformInputContext +{ +public: + QIOSInputContext(); + ~QIOSInputContext(); + + void showInputPanel(); + void hideInputPanel(); + bool isInputPanelVisible() const; + +private: + QIOSKeyboardListener *m_keyboardListener; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm new file mode 100644 index 0000000000..7937337e4a --- /dev/null +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosinputcontext.h" +#include "qioswindow.h" +#include + +@interface QIOSKeyboardListener : NSObject { +@public + QIOSInputContext *m_context; + BOOL m_keyboardVisible; +} +@end + +@implementation QIOSKeyboardListener + +- (id)initWithQIOSInputContext:(QIOSInputContext *)context +{ + self = [super init]; + if (self) { + m_context = context; + m_keyboardVisible = NO; + // After the keyboard became undockable (iOS5), UIKeyboardWillShow/UIKeyboardWillHide + // no longer works for all cases. So listen to keyboard frame changes instead: + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardDidChangeFrame:) + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardDidChangeFrameNotification" object:nil]; + [super dealloc]; +} + +- (void) keyboardDidChangeFrame:(NSNotification *)notification +{ + CGRect frame; + [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); + if (m_keyboardVisible != visible) { + m_keyboardVisible = visible; + m_context->emitInputPanelVisibleChanged(); + } +} + +@end + +QIOSInputContext::QIOSInputContext() + : QPlatformInputContext(), + m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) +{ +} + +QIOSInputContext::~QIOSInputContext() +{ + [m_keyboardListener release]; +} + +void QIOSInputContext::showInputPanel() +{ + if (isInputPanelVisible()) + return; + + // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder + // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first + // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt + // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible + // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of + // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() becomeFirstResponder]; + } +} + +void QIOSInputContext::hideInputPanel() +{ + if (!isInputPanelVisible()) + return; + + if (QWindow *window = QGuiApplication::focusWindow()) { + QIOSWindow *qiosWindow = static_cast(window->handle()); + [qiosWindow->nativeView() resignFirstResponder]; + } +} + +bool QIOSInputContext::isInputPanelVisible() const +{ + return m_keyboardListener->m_keyboardVisible; +} diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 363d267716..9e6dadc5a1 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -59,6 +59,7 @@ public: QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; QPlatformFontDatabase *fontDatabase() const; + QPlatformInputContext *inputContext() const; QVariant styleHint(StyleHint hint) const; @@ -69,6 +70,7 @@ public: private: QPlatformFontDatabase *m_fontDatabase; + QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; }; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index b37e803455..9d603da150 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -45,6 +45,7 @@ #include "qiosscreen.h" #include "qioseventdispatcher.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include @@ -54,6 +55,7 @@ QT_BEGIN_NAMESPACE QIOSIntegration::QIOSIntegration() : m_fontDatabase(new QCoreTextFontDatabase) + , m_inputContext(new QIOSInputContext) , m_screen(new QIOSScreen(QIOSScreen::MainScreen)) { if (![UIApplication sharedApplication]) { @@ -106,6 +108,11 @@ QPlatformFontDatabase * QIOSIntegration::fontDatabase() const return m_fontDatabase; } +QPlatformInputContext *QIOSIntegration::inputContext() const +{ + return m_inputContext; +} + QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { -- cgit v1.2.3 From 72c1ada86f8aed0109936542b66ab66981ec39ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 12 Dec 2012 15:23:21 +0100 Subject: iOS: Make fusion style the default style on iOS, not the windows style Change-Id: I81b6049ff666bf23ac58d60e10d7c3d8713a19ea Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/plugin.pro | 6 ++- src/plugins/platforms/ios/qiosintegration.h | 3 ++ src/plugins/platforms/ios/qiosintegration.mm | 14 ++++++ src/plugins/platforms/ios/qiostheme.h | 62 +++++++++++++++++++++++++ src/plugins/platforms/ios/qiostheme.mm | 69 ++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/ios/qiostheme.h create mode 100644 src/plugins/platforms/ios/qiostheme.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index d4fe25ef08..1be24d920d 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ - qiosinputcontext.mm + qiosinputcontext.mm \ + qiostheme.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ - qiosinputcontext.h + qiosinputcontext.h \ + qiostheme.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 9e6dadc5a1..5ba97bff6e 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -63,6 +63,9 @@ public: QVariant styleHint(StyleHint hint) const; + QStringList themeNames() const; + QPlatformTheme *createPlatformTheme(const QString &name) const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformNativeInterface *nativeInterface() const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 9d603da150..8008c5c0b0 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -46,6 +46,7 @@ #include "qioseventdispatcher.h" #include "qioscontext.h" #include "qiosinputcontext.h" +#include "qiostheme.h" #include @@ -123,6 +124,19 @@ QVariant QIOSIntegration::styleHint(StyleHint hint) const } } +QStringList QIOSIntegration::themeNames() const +{ + return QStringList(QLatin1String(QIOSTheme::name)); +} + +QPlatformTheme *QIOSIntegration::createPlatformTheme(const QString &name) const +{ + if (name == QLatin1String(QIOSTheme::name)) + return new QIOSTheme; + + return QPlatformIntegration::createPlatformTheme(name); +} + QPlatformNativeInterface *QIOSIntegration::nativeInterface() const { return const_cast(this); diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h new file mode 100644 index 0000000000..d21d8804fa --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSTHEME_H +#define QIOSTHEME_H + +#include + +QT_BEGIN_NAMESPACE + +class QIOSTheme : public QPlatformTheme +{ +public: + QIOSTheme(); + ~QIOSTheme(); + + QVariant themeHint(ThemeHint hint) const; + + static const char *name; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm new file mode 100644 index 0000000000..6e54b9cb3b --- /dev/null +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiostheme.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +const char *QIOSTheme::name = "ios"; + +QIOSTheme::QIOSTheme() +{ +} + +QIOSTheme::~QIOSTheme() +{ +} + +QVariant QIOSTheme::themeHint(ThemeHint hint) const +{ + switch (hint) { + case QPlatformTheme::StyleNames: + return QStringList(QStringLiteral("fusion")); + default: + return QPlatformTheme::themeHint(hint); + } +} + +QT_END_NAMESPACE -- cgit v1.2.3 From 70b21ec3c12c655354676778e087182f20aadbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2012 15:20:30 +0100 Subject: iOS: Make default system font Helvetica Without a platform theme implementatin we were relying on QCoreTextFontDatabase::defaultFont() to return the system font. This didn't work because it reported the system font that iOS reports, '.Helvetica Neue UI', which is a private font that does not get added to our font database. The result was that we picked the first font in the list of known fonts -- in this case 'Academy Engraved LET'. We now implement QIOSTheme::font(), which takes precedence over the font database's default font, and hard-code the system font to 'Helvetica', since Qt does not yet have the concept of private system fonts. Change-Id: I901cf9c2b662ea2795212376b84b8391be2efbbe Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiostheme.h | 2 ++ src/plugins/platforms/ios/qiostheme.mm | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h index d21d8804fa..5ccbcac710 100644 --- a/src/plugins/platforms/ios/qiostheme.h +++ b/src/plugins/platforms/ios/qiostheme.h @@ -54,6 +54,8 @@ public: QVariant themeHint(ThemeHint hint) const; + const QFont *font(Font type = SystemFont) const; + static const char *name; }; diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm index 6e54b9cb3b..f98781f8a7 100644 --- a/src/plugins/platforms/ios/qiostheme.mm +++ b/src/plugins/platforms/ios/qiostheme.mm @@ -44,6 +44,11 @@ #include #include +#include + +#include +#include + QT_BEGIN_NAMESPACE const char *QIOSTheme::name = "ios"; @@ -66,4 +71,26 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const } } +const QFont *QIOSTheme::font(Font type) const +{ + static QHash fonts; + if (fonts.isEmpty()) { + // The real system font on iOS is '.Helvetica Neue UI', as returned by both [UIFont systemFontOfSize] + // and CTFontCreateUIFontForLanguage(kCTFontSystemFontType, ...), but this font is not included when + // populating the available fonts in QCoreTextFontDatabase::populateFontDatabase(), since the font + // is internal to iOS and not supposed to be used by applications. We could potentially add this + // font to the font-database, but it would then show up when enumerating user fonts from Qt + // applications since we don't have a flag in Qt to mark a font as a private system font. + // For now we hard-code the font to Helvetica, which should be very close to the actual + // system font. + QLatin1String systemFontFamilyName("Helvetica"); + fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize])); + fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize])); + fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize])); + fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize])); + } + + return fonts.value(type, 0); +} + QT_END_NAMESPACE -- cgit v1.2.3 From d5d3f5ea8e6620e1ae06488a9e35a36550367726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Feb 2013 13:49:03 +0100 Subject: iOS: let QIOSScreen change geometry according to interface rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt expects the screen to change geometry when the "desktop" rotates. On iOS, we interpret this as when the root view controller changes orientation, since after all, this is the surface we place QWindows on top of. Change-Id: Ia00e68c8f9f0a65aefcc60518ee544fb260d4595 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 3 +++ src/plugins/platforms/ios/qiosscreen.mm | 32 +++++++++++++++++++++---- src/plugins/platforms/ios/qiosviewcontroller.h | 1 - src/plugins/platforms/ios/qiosviewcontroller.mm | 12 ++++++++++ src/plugins/platforms/ios/qtmain.pro | 2 ++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index ed21e54f4a..e05a6cd6a1 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -69,9 +69,12 @@ public: UIScreen *uiScreen() const; + void setPrimaryOrientation(Qt::ScreenOrientation orientation); + private: UIScreen *m_uiScreen; QRect m_geometry; + QRect m_availableGeometry; int m_depth; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 00deaa2fc0..f4cade2e6d 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -88,11 +88,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) unscaledDpi = 132; }; - // UIScreen does not report different bounds for different orientations. We - // match this behavior by staying with a fixed QScreen geometry. CGRect bounds = [m_uiScreen bounds]; m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; @@ -111,8 +112,7 @@ QRect QIOSScreen::geometry() const QRect QIOSScreen::availableGeometry() const { - CGRect frame = m_uiScreen.applicationFrame; - return QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + return m_availableGeometry; } int QIOSScreen::depth() const @@ -150,6 +150,30 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) } } +void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) +{ + // Note that UIScreen never changes orientation, but QScreen should. To work around + // this, we let QIOSViewController call us whenever interface orientation changes, and + // use that as primary orientation. After all, the viewcontrollers geometry is what we + // place QWindows on top of. A problem with this approach is that QIOSViewController is + // not in use in a mixed environment, which results in no change to primary orientation. + // We see that as acceptable since Qt should most likely not interfere with orientation + // for that case anyway. + bool portrait = screen()->isPortrait(orientation); + if (portrait && m_geometry.width() < m_geometry.height()) + return; + + // Switching portrait/landscape means swapping width/height (and adjusting x/y): + CGRect frame = m_uiScreen.applicationFrame; + m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) + : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); + m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); + m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); +} + UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 605f0f5b4c..d5a61cb3f4 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,7 +40,6 @@ ****************************************************************************/ #import -#import @interface QIOSViewController : UIViewController @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 3121597dba..fe9e02666f 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -43,6 +43,7 @@ #include #include +#include "qiosscreen.h" @implementation QIOSViewController @@ -65,5 +66,16 @@ return UIInterfaceOrientationMaskAll; } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +{ + Q_UNUSED(fromInterfaceOrientation); + Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + if (orientation == -1) + return; + + QIOSScreen *qiosScreen = static_cast(QGuiApplication::primaryScreen()->handle()); + qiosScreen->setPrimaryOrientation(orientation); +} + @end diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 7c4c4ab398..5c290b6c00 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -3,6 +3,8 @@ TARGET = qiosmain PLUGIN_TYPE = platforms load(qt_plugin) +QT += gui-private + OBJECTIVE_SOURCES = qtmain.mm \ qiosviewcontroller.mm -- cgit v1.2.3 From 70774d021a4ddb6437646ab09bde0928e30c8a90 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 10:59:45 +0100 Subject: iOS: refactor QIOSOrientationListener into QIOSScreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up a bit. The orientation conversion functions belongs to QIOSScreen more than QIOSOrientationListener. And rename them in the same go to follow toQRect/fromQRect standard. The orientation listener itself is tightly coupled to QIOSScreen, and does not make much sense on its own, so move it into QIOSScreen to follow the same patteren already implemented for QIOSInputContext. Change-Id: I8b6b4d08a42349b4232749d59d46748297083536 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 2 - .../platforms/ios/qiosorientationlistener.h | 66 ----------- .../platforms/ios/qiosorientationlistener.mm | 130 --------------------- src/plugins/platforms/ios/qiosscreen.h | 6 +- src/plugins/platforms/ios/qiosscreen.mm | 90 +++++++++++++- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 3 +- 7 files changed, 96 insertions(+), 203 deletions(-) delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.h delete mode 100644 src/plugins/platforms/ios/qiosorientationlistener.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index 1be24d920d..a51ac39e03 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -14,7 +14,6 @@ OBJECTIVE_SOURCES = \ qioseventdispatcher.mm \ qiosbackingstore.mm \ qiosapplicationdelegate.mm \ - qiosorientationlistener.mm \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ @@ -27,7 +26,6 @@ HEADERS = \ qioseventdispatcher.h \ qiosbackingstore.h \ qiosapplicationdelegate.h \ - qiosorientationlistener.h \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ diff --git a/src/plugins/platforms/ios/qiosorientationlistener.h b/src/plugins/platforms/ios/qiosorientationlistener.h deleted file mode 100644 index 9d2e902ce1..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QIOSORIENTATIONLISTENER_H -#define QIOSORIENTATIONLISTENER_H - -#include -#include - -QT_BEGIN_NAMESPACE - -class QIOSScreen; -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation); - -QT_END_NAMESPACE - -@interface QIOSOrientationListener : NSObject { - @public - QIOSScreen *m_screen; - Qt::ScreenOrientation m_orientation; -} -- (id) initWithQIOSScreen:(QIOSScreen *)screen; - -@end - -#endif - diff --git a/src/plugins/platforms/ios/qiosorientationlistener.mm b/src/plugins/platforms/ios/qiosorientationlistener.mm deleted file mode 100644 index 264b77f14f..0000000000 --- a/src/plugins/platforms/ios/qiosorientationlistener.mm +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qiosorientationlistener.h" -#include "qiosscreen.h" -#include - -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation convertToQtOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation convertToUIOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - -QT_END_NAMESPACE - -@implementation QIOSOrientationListener - -- (id) initWithQIOSScreen:(QIOSScreen *)screen -{ - self = [super init]; - if (self) { - m_screen = screen; - m_orientation = convertToQtOrientation([UIDevice currentDevice].orientation); - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(orientationChanged:) - name:@"UIDeviceOrientationDidChangeNotification" object:nil]; - } - return self; -} - -- (void) dealloc -{ - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [super dealloc]; -} - -- (void) orientationChanged:(NSNotification *)notification -{ - Q_UNUSED(notification); - Qt::ScreenOrientation qtOrientation = convertToQtOrientation([UIDevice currentDevice].orientation); - if (qtOrientation != -1) { - m_orientation = qtOrientation; - QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); - } -} - -@end - diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index e05a6cd6a1..17a5c3149a 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -45,10 +45,14 @@ #include #include -#include + +@class QIOSOrientationListener; QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f4cade2e6d..02d719eaf1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -45,8 +45,96 @@ #include +@interface QIOSOrientationListener : NSObject { + @public + QIOSScreen *m_screen; +} +- (id) initWithQIOSScreen:(QIOSScreen *)screen; +@end + +@implementation QIOSOrientationListener + +- (id) initWithQIOSScreen:(QIOSScreen *)screen +{ + self = [super init]; + if (self) { + m_screen = screen; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + } + return self; +} + +- (void) dealloc +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIDeviceOrientationDidChangeNotification" object:nil]; + [super dealloc]; +} + +- (void) orientationChanged:(NSNotification *)notification +{ + Q_UNUSED(notification); + Qt::ScreenOrientation orientation = toQtScreenOrientation([UIDevice currentDevice].orientation); + if (orientation != -1) + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), orientation); +} + +@end + QT_BEGIN_NAMESPACE +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + /*! Returns the model identifier of the device. @@ -137,7 +225,7 @@ Qt::ScreenOrientation QIOSScreen::nativeOrientation() const Qt::ScreenOrientation QIOSScreen::orientation() const { - return m_orientationListener ? m_orientationListener->m_orientation : nativeOrientation(); + return toQtScreenOrientation([UIDevice currentDevice].orientation); } void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index fe9e02666f..8c280d11d9 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -69,7 +69,7 @@ - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = convertToQtOrientation(self.interfaceOrientation); + Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); if (orientation == -1) return; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index a2901efd1d..cc016da106 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -43,7 +43,6 @@ #include "qioscontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" -#include "qiosorientationlistener.h" #include "qiosviewcontroller.h" #import @@ -272,7 +271,7 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio { // Keep the status bar in sync with content orientation. This will ensure // that the task bar (and associated gestures) are aligned correctly: - UIDeviceOrientation uiOrientation = convertToUIOrientation(orientation); + UIDeviceOrientation uiOrientation = fromQtScreenOrientation(orientation); [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -- cgit v1.2.3 From d665ba2a9454dbd2ed9f4384e04c31d232b0c5eb Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 17 Dec 2012 13:39:59 +0100 Subject: iOS: let QIOSScreen use correct orientation at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When QScreen is created, we need to check if the application is already in landscape. Change-Id: I653c622154a5c23ec93e89ec3e80fefb6b1f1bdd Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 02d719eaf1..a2fd10bdd4 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -42,6 +42,7 @@ #include "qiosscreen.h" #include "qioswindow.h" #include +#include "qiosapplicationdelegate.h" #include @@ -185,6 +186,12 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; + if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + // When in a non-mixed environment, let QScreen follow the current interface orientation: + UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; + setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + } + [pool release]; } -- cgit v1.2.3 From a593de41edfac04f3e3c6dd5bb024254e7e6ff4e Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 14 Dec 2012 17:25:56 +0100 Subject: iOS: Retina display support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scale the OpenGL paint device size and physical dpi by the device pixel ratio. Change-Id: I8b576f23129aafc47371795151c548663e94ad52 Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglpaintdevice.cpp | 14 ++++++++++++-- src/gui/opengl/qopenglpaintdevice.h | 1 + src/plugins/platforms/ios/qiosbackingstore.mm | 10 ++++++++-- src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 21 ++++++++++++++++++--- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index 0b3d9dc46d..d55d6a91bf 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -116,6 +116,7 @@ public: qreal dpmx; qreal dpmy; + qreal devicePixelRatio; bool flipped; @@ -178,6 +179,7 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz) , ctx(QOpenGLContext::currentContext()) , dpmx(qt_defaultDpiX() * 100. / 2.54) , dpmy(qt_defaultDpiY() * 100. / 2.54) + , devicePixelRatio(1.0) , flipped(false) , engine(0) { @@ -248,6 +250,14 @@ void QOpenGLPaintDevice::setSize(const QSize &size) d_ptr->size = size; } +/*! + Sets the device pixel ratio for the paint device to \a devicePixelRatio. +*/ +void QOpenGLPaintDevice::setDevicePixelRatio(qreal devicePixelRatio) +{ + d_ptr->devicePixelRatio = devicePixelRatio; +} + /*! \reimp */ @@ -272,9 +282,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const case PdmDpiY: return qRound(d_ptr->dpmy * 0.0254); case PdmPhysicalDpiX: - return qRound(d_ptr->dpmx * 0.0254); + return qRound(d_ptr->dpmx * 0.0254 * d_ptr->devicePixelRatio); case PdmPhysicalDpiY: - return qRound(d_ptr->dpmy * 0.0254); + return qRound(d_ptr->dpmy * 0.0254 * d_ptr->devicePixelRatio); default: qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric); return 0; diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index 731000f131..5868a5740a 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -68,6 +68,7 @@ public: QOpenGLContext *context() const; QSize size() const; void setSize(const QSize &size); + void setDevicePixelRatio(qreal devicePixelRatio); qreal dotsPerMeterX() const; qreal dotsPerMeterY() const; diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 6bae08ce2b..5ee048cb2f 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -71,12 +71,18 @@ void QIOSBackingStore::beginPaint(const QRegion &) m_context->makeCurrent(window()); static_cast(paintDevice())->setSize(window()->size()); + QIOSWindow *iosWindow = static_cast(window()->handle()); + static_cast(paintDevice())->setSize(window()->size() * iosWindow->devicePixelRatio()); } QPaintDevice *QIOSBackingStore::paintDevice() { - if (!m_device) - m_device = new QOpenGLPaintDevice; + if (!m_device) { + QIOSWindow *iosWindow = static_cast(window()->handle()); + QOpenGLPaintDevice *openGLDevice = new QOpenGLPaintDevice(window()->size() * iosWindow->devicePixelRatio()); + openGLDevice->setDevicePixelRatio(iosWindow->devicePixelRatio()); + m_device = openGLDevice; + } return m_device; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 3a05901ae7..cb2854d60e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -90,6 +90,7 @@ public: GLuint framebufferObject(const QIOSContext &context) const; GLuint colorRenderbuffer(const QIOSContext &context) const; + qreal devicePixelRatio() const; EAGLView *nativeView() const { return m_view; } @@ -104,6 +105,7 @@ private: GLint renderbufferWidth; GLint renderbufferHeight; } m_glData; + qreal m_devicePixelRatio; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index cc016da106..e3da694bac 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -126,8 +126,7 @@ static QRect fromCGRect(const CGRect &rect) { UITouch *touch = [touches anyObject]; CGPoint locationInView = [touch locationInView:self]; - CGFloat scaleFactor = [self contentScaleFactor]; - QPoint p(locationInView.x * scaleFactor, locationInView.y * scaleFactor); + QPoint p(locationInView.x , locationInView.y); // TODO handle global touch point? for status bar? QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); @@ -204,11 +203,21 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) , m_glData() + , m_devicePixelRatio(1.0) { if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); + + // Retina support: get screen scale factor and set it in the content view. + // This will make framebufferObject() create a 2x frame buffer on retina + // displays. Also set m_devicePixelRatio which is used for scaling the + // paint device. + if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { + m_devicePixelRatio = [[UIScreen mainScreen] scale]; + [m_view setContentScaleFactor : m_devicePixelRatio]; + } } QIOSWindow::~QIOSWindow() @@ -304,7 +313,8 @@ GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() || m_glData.renderbufferHeight != geometry().height()) { + m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || + m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; @@ -329,4 +339,9 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const return m_glData.colorRenderbuffer; } +qreal QIOSWindow::devicePixelRatio() const +{ + return m_devicePixelRatio; +} + QT_END_NAMESPACE -- cgit v1.2.3 From 54448b2f9fb7501e9d4a8e2c8b75acb9de8f7ae0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 12 Dec 2012 11:16:13 +0100 Subject: iOS: remove warning from unused function in QIOSEventDispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From the documentation for QAbstractEventDispatcher::flush(), this function does only make sense for X11. Change-Id: I7f445b67b283f60c9a30ac00837beb44e8205d8b Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioseventdispatcher.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 9d455370c0..f6f60387d4 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -313,7 +313,7 @@ void QIOSEventDispatcher::interrupt() void QIOSEventDispatcher::flush() { - qDebug() << __FUNCTION__ << "not implemented"; + // X11 only. } QT_END_NAMESPACE -- cgit v1.2.3 From 5abe9aa435c316b845f4cf5f6a930eefd449f4e1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 10:15:39 +0100 Subject: iOS: refactor general convenience functions into new file 'qiosglobal' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some functions are needed across several files and classes. Lets place them in a common file for all to use. Change-Id: I5f9b578f948d66d10e57a835b80b5c493e07fb4c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/plugin.pro | 6 +- src/plugins/platforms/ios/qiosglobal.h | 59 ++++++++++++++ src/plugins/platforms/ios/qiosglobal.mm | 104 ++++++++++++++++++++++++ src/plugins/platforms/ios/qiosscreen.h | 3 - src/plugins/platforms/ios/qiosscreen.mm | 49 +---------- src/plugins/platforms/ios/qiosviewcontroller.mm | 1 + src/plugins/platforms/ios/qioswindow.mm | 11 +-- 7 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 src/plugins/platforms/ios/qiosglobal.h create mode 100644 src/plugins/platforms/ios/qiosglobal.mm diff --git a/src/plugins/platforms/ios/plugin.pro b/src/plugins/platforms/ios/plugin.pro index a51ac39e03..591a0a67ed 100644 --- a/src/plugins/platforms/ios/plugin.pro +++ b/src/plugins/platforms/ios/plugin.pro @@ -17,7 +17,8 @@ OBJECTIVE_SOURCES = \ qiosviewcontroller.mm \ qioscontext.mm \ qiosinputcontext.mm \ - qiostheme.mm + qiostheme.mm \ + qiosglobal.mm HEADERS = \ qiosintegration.h \ @@ -29,6 +30,7 @@ HEADERS = \ qiosviewcontroller.h \ qioscontext.h \ qiosinputcontext.h \ - qiostheme.h + qiostheme.h \ + qiosglobal.h #HEADERS = qiossoftwareinputhandler.h diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h new file mode 100644 index 0000000000..cf4c89cfad --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIOSGLOBAL_H +#define QIOSGLOBAL_H + +#import +#import +#import +#import "qiosscreen.h" + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect); +QRect fromCGRect(const CGRect &rect); +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); + +QT_END_NAMESPACE + +#endif // QIOSGLOBAL_H diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm new file mode 100644 index 0000000000..30138acc1b --- /dev/null +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qiosglobal.h" +#include + +QT_BEGIN_NAMESPACE + +CGRect toCGRect(const QRect &rect) +{ + return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); +} + +QRect fromCGRect(const CGRect &rect) +{ + return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + +Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) +{ + Qt::ScreenOrientation qtOrientation; + switch (uiDeviceOrientation) { + case UIDeviceOrientationPortraitUpsideDown: + qtOrientation = Qt::InvertedPortraitOrientation; + break; + case UIDeviceOrientationLandscapeLeft: + qtOrientation = Qt::InvertedLandscapeOrientation; + break; + case UIDeviceOrientationLandscapeRight: + qtOrientation = Qt::LandscapeOrientation; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + qtOrientation = static_cast(-1); // not supported ATM. + break; + default: + qtOrientation = Qt::PortraitOrientation; + break; + } + return qtOrientation; +} + +UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) +{ + UIDeviceOrientation uiOrientation; + switch (qtOrientation) { + case Qt::LandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeRight; + break; + case Qt::InvertedLandscapeOrientation: + uiOrientation = UIDeviceOrientationLandscapeLeft; + break; + case Qt::InvertedPortraitOrientation: + uiOrientation = UIDeviceOrientationPortraitUpsideDown; + break; + case Qt::PrimaryOrientation: + case Qt::PortraitOrientation: + default: + uiOrientation = UIDeviceOrientationPortrait; + break; + } + return uiOrientation; +} + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 17a5c3149a..762c60e6da 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -50,9 +50,6 @@ QT_BEGIN_NAMESPACE -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); - class QIOSScreen : public QPlatformScreen { public: diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a2fd10bdd4..87ddc63f4a 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosscreen.h" #include "qioswindow.h" #include @@ -88,54 +89,6 @@ @end -QT_BEGIN_NAMESPACE - -Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) -{ - Qt::ScreenOrientation qtOrientation; - switch (uiDeviceOrientation) { - case UIDeviceOrientationPortraitUpsideDown: - qtOrientation = Qt::InvertedPortraitOrientation; - break; - case UIDeviceOrientationLandscapeLeft: - qtOrientation = Qt::InvertedLandscapeOrientation; - break; - case UIDeviceOrientationLandscapeRight: - qtOrientation = Qt::LandscapeOrientation; - break; - case UIDeviceOrientationFaceUp: - case UIDeviceOrientationFaceDown: - qtOrientation = static_cast(-1); // not supported ATM. - break; - default: - qtOrientation = Qt::PortraitOrientation; - break; - } - return qtOrientation; -} - -UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) -{ - UIDeviceOrientation uiOrientation; - switch (qtOrientation) { - case Qt::LandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeRight; - break; - case Qt::InvertedLandscapeOrientation: - uiOrientation = UIDeviceOrientationLandscapeLeft; - break; - case Qt::InvertedPortraitOrientation: - uiOrientation = UIDeviceOrientationPortraitUpsideDown; - break; - case Qt::PrimaryOrientation: - case Qt::PortraitOrientation: - default: - uiOrientation = UIDeviceOrientationPortrait; - break; - } - return uiOrientation; -} - /*! Returns the model identifier of the device. diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 8c280d11d9..6950288912 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -44,6 +44,7 @@ #include #include #include "qiosscreen.h" +#include "qiosglobal.h" @implementation QIOSViewController diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e3da694bac..9b10ba4e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" #include "qiosscreen.h" @@ -52,16 +53,6 @@ #include -static CGRect toCGRect(const QRect &rect) -{ - return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); -} - -static QRect fromCGRect(const CGRect &rect) -{ - return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); -} - @implementation EAGLView + (Class)layerClass -- cgit v1.2.3 From b960424195634c00673d499e4719ccb4f8704ad0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:50:50 +0100 Subject: iOS: add global function 'isQtApplication' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several places in the code we need to check if the plugin is running as a cross-platform Qt application or inside a native app. So we refactor this function to qiosglobal so we can access it from everywhere. Change-Id: I78db0dcde71b7d281868ce304867c8f876caef2a Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 13 +++++++++++++ src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cf4c89cfad..7a23a2a485 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE +bool isQtApplication(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 30138acc1b..a8a89a1637 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -40,10 +40,23 @@ ****************************************************************************/ #include "qiosglobal.h" +#include "qiosapplicationdelegate.h" #include QT_BEGIN_NAMESPACE +bool isQtApplication() +{ + // Returns true if the plugin is in full control of the whole application. This means + // that we control the application delegate and the top view controller, and can take + // actions that impacts all parts of the application. The opposite means that we are + // embedded inside a native iOS application, and should be more focused on playing along + // with native UIControls, and less inclined to change structures that lies outside the + // scope of our QWindows/UIViews. + static bool isQt = ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]); + return isQt; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 87ddc63f4a..fdf2f31ea1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -139,7 +139,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) const qreal millimetersPerInch = 25.4; m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) { + if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9b10ba4e1c..af184e2e7b 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -196,7 +196,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_glData() , m_devicePixelRatio(1.0) { - if ([[UIApplication sharedApplication].delegate isKindOfClass:[QIOSApplicationDelegate class]]) + if (isQtApplication()) [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From 31796ca8abb8878165c7099145b08abfdf8bf1e3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 09:50:28 +0100 Subject: iOS: report changes to keyboard rect back to Qt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QInputContext expects us to report whenever the input panel changes geometry. This patch implements this. Change-Id: I9162f0d48da6925274a7489c9bcb6adab9afae82 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 1 + src/plugins/platforms/ios/qiosglobal.mm | 9 +++++++++ src/plugins/platforms/ios/qiosinputcontext.h | 1 + src/plugins/platforms/ios/qiosinputcontext.mm | 15 +++++++++++++-- src/plugins/platforms/ios/qiosscreen.mm | 4 +--- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 7a23a2a485..849d9bce37 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,7 @@ CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); +QRect fromPortraitToPrimary(const QRect &rect); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index a8a89a1637..f9b4b14a19 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -113,5 +113,14 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } +QRect fromPortraitToPrimary(const QRect &rect) +{ + // UIScreen is always in portrait. Use this function to convert CGRects + // aligned with UIScreen into whatever is the current orientation of QScreen. + QScreen *screen = QGuiApplication::primaryScreen(); + return screen->isPortrait(screen->primaryOrientation()) ? rect + : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 22782d183c..ceed5ffaf2 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -56,6 +56,7 @@ public: QIOSInputContext(); ~QIOSInputContext(); + QRectF keyboardRect() const; void showInputPanel(); void hideInputPanel(); bool isInputPanelVisible() const; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 7937337e4a..89d210cb54 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qiosglobal.h" #include "qiosinputcontext.h" #include "qioswindow.h" #include @@ -47,6 +48,7 @@ @public QIOSInputContext *m_context; BOOL m_keyboardVisible; + QRectF m_keyboardRect; } @end @@ -80,6 +82,10 @@ { CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_context->emitKeyboardRectChanged(); + BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); if (m_keyboardVisible != visible) { m_keyboardVisible = visible; @@ -90,8 +96,8 @@ @end QIOSInputContext::QIOSInputContext() - : QPlatformInputContext(), - m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + : QPlatformInputContext() + , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) { } @@ -100,6 +106,11 @@ QIOSInputContext::~QIOSInputContext() [m_keyboardListener release]; } +QRectF QIOSInputContext::keyboardRect() const +{ + return m_keyboardListener->m_keyboardRect; +} + void QIOSInputContext::showInputPanel() { if (isInputPanelVisible()) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index fdf2f31ea1..a0403a0d69 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -212,11 +212,9 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) return; // Switching portrait/landscape means swapping width/height (and adjusting x/y): - CGRect frame = m_uiScreen.applicationFrame; - m_availableGeometry = portrait ? QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) - : QRect(frame.origin.y, m_geometry.width() - frame.size.width - frame.origin.x, frame.size.height, frame.size.width); m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From 5b452a502214a927c54b7cc6e4fb81a7c2141267 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 12:58:43 +0100 Subject: iOS: update primary orientation when the rotation starts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to update primary orientation when the rotation starts, and not when it ends, so that we are in sync with the resize that happens to the backingstore upon layoutSubviews. Change-Id: I466a2d135e6c15550c6207c9659871629d748b73 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 6950288912..a441258f4e 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -67,10 +67,10 @@ return UIInterfaceOrientationMaskAll; } -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - Q_UNUSED(fromInterfaceOrientation); - Qt::ScreenOrientation orientation = toQtScreenOrientation(self.interfaceOrientation); + Q_UNUSED(duration); + Qt::ScreenOrientation orientation = toQtScreenOrientation(toInterfaceOrientation); if (orientation == -1) return; -- cgit v1.2.3 From cbdd73d25d4c4aa6436591b259dec10aa4f74b0d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 18 Dec 2012 13:52:13 +0100 Subject: iOS: bugfix portraitToPrimary global function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QScreen geometry and orientation is updated a bit after we change geometry in QPlatformScreen, which this time was enough to break availableGeometry. Since this function is for internal use, we let it be based on internal data. Change-Id: I7701b0a6043839c89c01e87242decb8a739d00f1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index f9b4b14a19..69547fb2a1 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -117,9 +117,9 @@ QRect fromPortraitToPrimary(const QRect &rect) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QScreen *screen = QGuiApplication::primaryScreen(); - return screen->isPortrait(screen->primaryOrientation()) ? rect - : QRect(rect.y(), screen->geometry().width() - rect.width() - rect.x(), rect.height(), rect.width()); + QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + return geometry.width() < geometry.height() ? rect + : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } QT_END_NAMESPACE -- cgit v1.2.3 From ac0f6d1a349748ff82e1710c33e91e6b3f179a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 18 Dec 2012 09:28:07 +0100 Subject: iOS: Fix build for modules that load(configure) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit configure.prf checks if MAKEFILE_GENERATOR is set to something it can work with. ios/default_pre.prf unsets MAKEFILE_GENERATOR. This breaks QtMultimedia at least. Add special case for iOS to configure.prf and set QMAKE_MAKE to "make". Change-Id: Ie8feaeefe4a932d735a0cd4c09e869ca1341aae5 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- mkspecs/features/configure.prf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf index 39144e7216..b4569df6d5 100644 --- a/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -7,6 +7,9 @@ equals(MAKEFILE_GENERATOR, UNIX) { QMAKE_MAKE = mingw32-make } else:if(equals(MAKEFILE_GENERATOR, MSVC.NET)|equals(MAKEFILE_GENERATOR, MSBUILD)) { QMAKE_MAKE = nmake +} else:ios { + # iOS unsets MAKEFILE_GENERATOR in its default_pre.prf + QMAKE_MAKE = make } else { error("Configure tests are not supported with the $$MAKEFILE_GENERATOR Makefile generator.") } -- cgit v1.2.3 From 2dea9fdc3a04ccc9759427c6450e88cb78003381 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 09:15:27 +0100 Subject: iOS: add convenience function to get to the root QIOSViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that we need to access our view controller from many places, and the syntax to do so is tricky to remember. So lets just add it to our global functions, with the added bonus of a using a little cache. Note: many of these functions could be made inline, but since one concern of the plugin will be the end size of the app, I prefer to trade size for speed at this point. We can always change this later. Change-Id: I578ea9ae8218d23d635b7728a930763ca53c4eaa Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 ++++ src/plugins/platforms/ios/qiosglobal.mm | 8 ++++++++ src/plugins/platforms/ios/qiosscreen.mm | 4 ++-- src/plugins/platforms/ios/qioswindow.mm | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 849d9bce37..86377e7c64 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -47,9 +47,13 @@ #import #import "qiosscreen.h" +@class QIOSViewController; + QT_BEGIN_NAMESPACE bool isQtApplication(); +QIOSViewController *rootViewController(); + CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 69547fb2a1..cf69d8fdef 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -41,6 +41,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include QT_BEGIN_NAMESPACE @@ -57,6 +58,13 @@ bool isQtApplication() return isQt; } +QIOSViewController *rootViewController() +{ + static QIOSViewController *c = isQtApplication() ? + static_cast([UIApplication sharedApplication].delegate.window.rootViewController) : nil; + return c; +} + CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index a0403a0d69..5905f1630e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -44,6 +44,7 @@ #include "qioswindow.h" #include #include "qiosapplicationdelegate.h" +#include "qiosviewcontroller.h" #include @@ -141,8 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: - UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; - setPrimaryOrientation(toQtScreenOrientation(controller.interfaceOrientation)); + setPrimaryOrientation(toQtScreenOrientation(rootViewController().interfaceOrientation)); } [pool release]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index af184e2e7b..71816f7d94 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -197,7 +197,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_devicePixelRatio(1.0) { if (isQtApplication()) - [[UIApplication sharedApplication].delegate.window.rootViewController.view addSubview:m_view]; + [rootViewController().view addSubview:m_view]; setWindowState(window->windowState()); -- cgit v1.2.3 From bbb8db9bdb503f4f2c558e5f081c201c09d33d77 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:46:22 +0100 Subject: iOS: make EAGLView private in QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not the biggest gain, but since all the members of EAGLView are declared private, we might as well move the whole interface into the source file. We can then make the members public without caring about interface readability. We will make use of this in a following patch. Change-Id: I144fb5748573ca6faf257d72597907b5c17b1e05 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 29 ++--------------------------- src/plugins/platforms/ios/qioswindow.mm | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index cb2854d60e..d0df791cf0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,31 +49,6 @@ class QIOSContext; class QIOSWindow; -@interface EAGLView : UIView -{ - UITextAutocapitalizationType autocapitalizationType; - UITextAutocorrectionType autocorrectionType; - BOOL enablesReturnKeyAutomatically; - UIKeyboardAppearance keyboardAppearance; - UIKeyboardType keyboardType; - UIReturnKeyType returnKeyType; - BOOL secureTextEntry; - QIOSWindow *m_qioswindow; -} - -- (id)initWithQIOSWindow:(QIOSWindow *)qioswindow; -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; - -@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; -@property(nonatomic) UITextAutocorrectionType autocorrectionType; -@property(nonatomic) BOOL enablesReturnKeyAutomatically; -@property(nonatomic) UIKeyboardAppearance keyboardAppearance; -@property(nonatomic) UIKeyboardType keyboardType; -@property(nonatomic) UIReturnKeyType returnKeyType; -@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; - -@end - QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow @@ -92,10 +67,10 @@ public: GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; - EAGLView *nativeView() const { return m_view; } + UIView *nativeView() const { return m_view; } private: - EAGLView *m_view; + UIView *m_view; QRect m_requestedGeometry; mutable struct GLData { diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 71816f7d94..220f30c485 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -53,6 +53,29 @@ #include +@interface EAGLView : UIView +{ +@public + UITextAutocapitalizationType autocapitalizationType; + UITextAutocorrectionType autocorrectionType; + BOOL enablesReturnKeyAutomatically; + UIKeyboardAppearance keyboardAppearance; + UIKeyboardType keyboardType; + UIReturnKeyType returnKeyType; + BOOL secureTextEntry; + QIOSWindow *m_qioswindow; +} + +@property(nonatomic) UITextAutocapitalizationType autocapitalizationType; +@property(nonatomic) UITextAutocorrectionType autocorrectionType; +@property(nonatomic) BOOL enablesReturnKeyAutomatically; +@property(nonatomic) UIKeyboardAppearance keyboardAppearance; +@property(nonatomic) UIKeyboardType keyboardType; +@property(nonatomic) UIReturnKeyType returnKeyType; +@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; + +@end + @implementation EAGLView + (Class)layerClass @@ -186,7 +209,6 @@ @end - QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 646b1fd2b65f42327ff81b92ead96c634bec6468 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 10:23:54 +0100 Subject: iOS: add UIView category to get the QWindow it represents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding a simple way to get the QWindow pointer from any UIView makes writing code where you only have UIView pointers a bit easier. Perhaps we should also investigate if it is worthwhile to make this category public to the application, to further enhance working in a mixed environment. Change-Id: Ic263003dc7683a8d976024cbbbc2558e8472a790 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 4 ++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index d0df791cf0..63099682f1 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -49,6 +49,10 @@ class QIOSContext; class QIOSWindow; +@interface UIView (QIOS) +@property(readonly) QWindow *qwindow; +@end + QT_BEGIN_NAMESPACE class QIOSWindow : public QPlatformWindow diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 220f30c485..d79c1de461 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -209,6 +209,17 @@ @end +@implementation UIView (QIOS) + +- (QWindow *)qwindow +{ + if ([self isKindOfClass:[EAGLView class]]) + return static_cast(self)->m_qioswindow->window(); + return nil; +} + +@end + QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) -- cgit v1.2.3 From 1ff571142d5c06e91a1698d635ab092bbcf393cf Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:05:27 +0100 Subject: iOS: activate next window when active window hides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the OS does not handle window management for us, we need to handle this ourselves. So when a QWindow is closed or hidden, we transfer activation to the top-most visible window. This will fix application unresponsive after closing a dialog. Change-Id: I83f836ebafa71edca5ab5ae3a2bdba7cd1decbc1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d79c1de461..53da97e12d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -260,7 +260,21 @@ QIOSWindow::~QIOSWindow() void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); - [m_view setHidden:!visible]; + m_view.hidden = !visible; + + if (isQtApplication() && !visible) { + // Activate top-most visible QWindow: + NSArray *subviews = rootViewController().view.subviews; + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = [subviews objectAtIndex:i]; + if (!view.hidden) { + if (QWindow *window = view.qwindow) { + QWindowSystemInterface::handleWindowActivated(window); + break; + } + } + } + } } void QIOSWindow::setGeometry(const QRect &rect) -- cgit v1.2.3 From 9acae5ce0bfe94bde2711986ccebadf12e9a8a7a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 11:19:37 +0100 Subject: iOS: clean-up header includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Try to keep qiosglobal.h free from unnecessary includes, since its typically included from many different locations. Change-Id: I6638bcaef1189b3eee3dbd5f744c15f8f7858d71 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +--- src/plugins/platforms/ios/qiosglobal.mm | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 86377e7c64..3fe426c901 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -43,9 +43,7 @@ #define QIOSGLOBAL_H #import -#import -#import -#import "qiosscreen.h" +#include @class QIOSViewController; diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index cf69d8fdef..712968d216 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -42,7 +42,7 @@ #include "qiosglobal.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" -#include +#include "qiosscreen.h" QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 25ce3a021ba3007ec0d2f059c5ec7fa259bdae83 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 19 Dec 2012 12:06:10 +0100 Subject: iOS: make QWindow views hidden by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt will tell us when the window should be visible. Showing all windows by default makes e.g the desktop widget visible as well, which causes problems with activation of windows. Change-Id: Ibf2283bc5f009df7ff23126f4dd04ec898141720 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 53da97e12d..4b4871dd64 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -109,6 +109,9 @@ keyboardType = UIKeyboardTypeDefault; returnKeyType = UIReturnKeyDone; secureTextEntry = NO; + + if (isQtApplication()) + self.hidden = YES; } return self; -- cgit v1.2.3 From e30659aaf500a2186dfe67f29ce57bea5bf86b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Dec 2012 15:06:55 +0100 Subject: iOS: Fix style nitpicks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I670567f1793b5548393a3b315650bf34a0a3880e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioswindow.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4b4871dd64..9c814ac924 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -243,7 +243,7 @@ QIOSWindow::QIOSWindow(QWindow *window) // paint device. if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { m_devicePixelRatio = [[UIScreen mainScreen] scale]; - [m_view setContentScaleFactor : m_devicePixelRatio]; + [m_view setContentScaleFactor: m_devicePixelRatio]; } } @@ -355,7 +355,7 @@ GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const { if (!m_glData.colorRenderbuffer || m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() *m_devicePixelRatio) { + m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; -- cgit v1.2.3 From b05c20b4f33b35c8b3428caf2ee59675d858d5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:44:13 +0100 Subject: iOS: Don't check for existing window in QIOSMainWrapperApplicationDelegate The delegate is only used when we control the application, so we know that there isn't any window yet. Change-Id: Ibd774cb4fd8ceaab6a181769d2792b569f490495 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 61756edc93..7cc96f54b1 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,20 +55,16 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // We may have a window already from a NIB or storyboard - if (!self.window) { - // If not, we create one ourselves - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + QIOSViewController *controller = [[QIOSViewController alloc] init]; + self.window.rootViewController = controller; + controller.view = [[UIView alloc] init]; - // Aid debugging during development - self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; + // Aid debugging during development + self.window.backgroundColor = [UIColor cyanColor]; + self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; - [self.window makeKeyAndVisible]; - } + [self.window makeKeyAndVisible]; // We schedule the main-redirection for the next eventloop pass so that we // can return from this function and let UIApplicationMain finish its job. -- cgit v1.2.3 From 78fec3372ad819cc93b9cfb5bd3df2da6d792cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 21:55:10 +0100 Subject: iOS: Auto-release the UIWindow and root view-controller They are retained properties. Change-Id: Id1808d93fe30950fc05e41375f00183e098bff0b Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 7cc96f54b1..04151cd720 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -55,10 +55,9 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; - QIOSViewController *controller = [[QIOSViewController alloc] init]; - self.window.rootViewController = controller; - controller.view = [[UIView alloc] init]; + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From 8a854ea804c500c2f0425784fd6a24b843016077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:27:27 +0100 Subject: iOS: Don't init our own base view for the root viewcontroller This is handled automatically by the default implementation. Change-Id: Ia9bd0143490e6f2507ede03f3654a2b0b00e3e3d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 04151cd720..00bb581535 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -57,7 +57,6 @@ extern int qt_main(int argc, char *argv[]); { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - self.window.rootViewController.view = [[UIView alloc] init]; // Aid debugging during development self.window.backgroundColor = [UIColor cyanColor]; -- cgit v1.2.3 From c77d3d78e448f519c1770c863bb0fccc6c9b7263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:31:43 +0100 Subject: iOS: Move debug background color setting and guard for release builds Change-Id: Ie9131c3dfe16045805b37bf8af9381f4f9929da6 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 8 ++++++++ src/plugins/platforms/ios/qtmain.mm | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a441258f4e..c85058743c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -48,6 +48,14 @@ @implementation QIOSViewController +- (void)viewDidLoad +{ +#ifdef QT_DEBUG + if (!self.nibName) + self.view.backgroundColor = [UIColor magentaColor]; +#endif +} + -(BOOL)shouldAutorotate { // For now we assume that if the application doesn't listen to orientation diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 00bb581535..10c83f4b18 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -58,9 +58,9 @@ extern int qt_main(int argc, char *argv[]); self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; - // Aid debugging during development +#ifdef QT_DEBUG self.window.backgroundColor = [UIColor cyanColor]; - self.window.rootViewController.view.backgroundColor = [UIColor magentaColor]; +#endif [self.window makeKeyAndVisible]; -- cgit v1.2.3 From 157d690b8c190f341f1fa4cb6aff4c044456e99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 22:56:42 +0100 Subject: iOS: Don't build qiosviewcontroller.mm into qtmain plugin It's already built as part of the iOS platform plugin. Change-Id: I5a97e8723b566b9ef15aafce374be35f01e6cf08 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qtmain.pro | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qtmain.pro b/src/plugins/platforms/ios/qtmain.pro index 5c290b6c00..cbcb272217 100644 --- a/src/plugins/platforms/ios/qtmain.pro +++ b/src/plugins/platforms/ios/qtmain.pro @@ -5,7 +5,4 @@ load(qt_plugin) QT += gui-private -OBJECTIVE_SOURCES = qtmain.mm \ - qiosviewcontroller.mm - -HEADERS = qiosviewcontroller.h +OBJECTIVE_SOURCES = qtmain.mm -- cgit v1.2.3 From 847ac6008ca02a9acb1f4bd2159c6e4cfa332961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Dec 2012 00:21:25 +0100 Subject: iOS: Move handling of FBOs to QIOSContext instead of QIOSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lifetime of an FBO is tied to its context, so letting each window manage its own FBO failed when the window tried to delete the FBO at destruction time without the proper context being current, or even available anymore. We solve this by moving all handling of FBOs to the context itself, which is fine as we're exposing the necessary bits from the window to allocate storage based on its layer. Change-Id: I8c7c96cf63d6b667527c816f10ac2f4ff6a05e0c Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 21 +++++-- src/plugins/platforms/ios/qioscontext.mm | 100 +++++++++++++++++++++++++++---- src/plugins/platforms/ios/qioswindow.h | 11 +--- src/plugins/platforms/ios/qioswindow.mm | 65 ++------------------ 4 files changed, 113 insertions(+), 84 deletions(-) diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index b45917832c..082ec4794c 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -48,8 +48,10 @@ QT_BEGIN_NAMESPACE -class QIOSContext : public QPlatformOpenGLContext +class QIOSContext : public QObject, public QPlatformOpenGLContext { + Q_OBJECT + public: QIOSContext(QOpenGLContext *context); ~QIOSContext(); @@ -62,15 +64,26 @@ public: void doneCurrent(); GLuint defaultFramebufferObject(QPlatformSurface *) const; - GLuint defaultColorRenderbuffer(QPlatformSurface *) const; - QFunctionPointer getProcAddress(const QByteArray &procName); - EAGLContext *nativeContext() const; +private Q_SLOTS: + void windowDestroyed(QObject *object); private: EAGLContext *m_eaglContext; QSurfaceFormat m_format; + + struct FramebufferObject { + GLuint handle; + GLuint colorRenderbuffer; + GLuint depthRenderbuffer; + GLint renderbufferWidth; + GLint renderbufferHeight; + }; + + static void deleteBuffers(const FramebufferObject &framebufferObject); + + mutable QHash m_framebufferObjects; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 00629a84ab..dc431b57dd 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -70,12 +70,25 @@ QIOSContext::QIOSContext(QOpenGLContext *context) QIOSContext::~QIOSContext() { - if ([EAGLContext currentContext] == m_eaglContext) - doneCurrent(); + [EAGLContext setCurrentContext:m_eaglContext]; + + foreach (const FramebufferObject &framebufferObject, m_framebufferObjects) + deleteBuffers(framebufferObject); + [EAGLContext setCurrentContext:nil]; [m_eaglContext release]; } +void QIOSContext::deleteBuffers(const FramebufferObject &framebufferObject) +{ + if (framebufferObject.handle) + glDeleteFramebuffers(1, &framebufferObject.handle); + if (framebufferObject.colorRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.colorRenderbuffer); + if (framebufferObject.depthRenderbuffer) + glDeleteRenderbuffers(1, &framebufferObject.depthRenderbuffer); +} + QSurfaceFormat QIOSContext::format() const { return m_format; @@ -88,8 +101,7 @@ bool QIOSContext::makeCurrent(QPlatformSurface *surface) [EAGLContext setCurrentContext:m_eaglContext]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface)); - // Ensures render buffers are set up and match the size of the window - return defaultColorRenderbuffer(surface) != 0; + return true; } void QIOSContext::doneCurrent() @@ -100,20 +112,86 @@ void QIOSContext::doneCurrent() void QIOSContext::swapBuffers(QPlatformSurface *surface) { Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + Q_ASSERT(m_framebufferObjects.contains(window)); [EAGLContext setCurrentContext:m_eaglContext]; - glBindRenderbuffer(GL_RENDERBUFFER, defaultColorRenderbuffer(surface)); + glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer); [m_eaglContext presentRenderbuffer:GL_RENDERBUFFER]; } GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { - return static_cast(surface)->framebufferObject(*this); + Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window); + QWindow *window = static_cast(surface->surface()); + + FramebufferObject &framebufferObject = m_framebufferObjects[window]; + + // Set up an FBO for the window if it hasn't been created yet + if (!framebufferObject.handle) { + [EAGLContext setCurrentContext:m_eaglContext]; + + glGenFramebuffers(1, &framebufferObject.handle); + glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle); + + glGenRenderbuffers(1, &framebufferObject.colorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + framebufferObject.colorRenderbuffer); + + if (m_format.depthBufferSize() > 0 || m_format.stencilBufferSize() > 0) { + glGenRenderbuffers(1, &framebufferObject.depthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + + if (m_format.stencilBufferSize() > 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + framebufferObject.depthRenderbuffer); + } + + connect(window, SIGNAL(destroyed(QObject*)), this, SLOT(windowDestroyed(QObject*))); + } + + // Ensure that the FBO's buffers match the size of the window + QIOSWindow *platformWindow = static_cast(surface); + if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() || + framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { + + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); + CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferObject.renderbufferHeight); + + if (framebufferObject.depthRenderbuffer) { + glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.depthRenderbuffer); + + // FIXME: Support more fine grained control over depth/stencil buffer sizes + if (m_format.stencilBufferSize() > 0) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + else + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, + framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight); + } + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } + + return framebufferObject.handle; } -GLuint QIOSContext::defaultColorRenderbuffer(QPlatformSurface *surface) const +void QIOSContext::windowDestroyed(QObject *object) { - return static_cast(surface)->colorRenderbuffer(*this); + QWindow *window = static_cast(object); + if (m_framebufferObjects.contains(window)) { + deleteBuffers(m_framebufferObjects[window]); + m_framebufferObjects.remove(window); + } } QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) @@ -121,7 +199,5 @@ QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) return reinterpret_cast(dlsym(RTLD_NEXT, functionName.constData())); } -EAGLContext *QIOSContext::nativeContext() const -{ - return m_eaglContext; -} +#include "moc_qioscontext.cpp" + diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 63099682f1..1f36c525ce 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,9 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); - GLuint framebufferObject(const QIOSContext &context) const; - GLuint colorRenderbuffer(const QIOSContext &context) const; qreal devicePixelRatio() const; + int effectiveWidth() const; + int effectiveHeight() const; UIView *nativeView() const { return m_view; } @@ -77,13 +77,6 @@ private: UIView *m_view; QRect m_requestedGeometry; - mutable struct GLData { - GLuint framebufferObject; - GLuint colorRenderbuffer; - GLuint depthRenderbuffer; - GLint renderbufferWidth; - GLint renderbufferHeight; - } m_glData; qreal m_devicePixelRatio; }; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9c814ac924..88debb7c33 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -229,7 +229,6 @@ QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_requestedGeometry(QPlatformWindow::geometry()) - , m_glData() , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -249,13 +248,6 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { - if (m_glData.framebufferObject) - glDeleteFramebuffers(1, &m_glData.framebufferObject); - if (m_glData.colorRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.colorRenderbuffer); - if (m_glData.depthRenderbuffer) - glDeleteRenderbuffers(1, &m_glData.depthRenderbuffer); - [m_view removeFromSuperview]; [m_view release]; } @@ -325,64 +317,19 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio [[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO]; } -GLuint QIOSWindow::framebufferObject(const QIOSContext &context) const +qreal QIOSWindow::devicePixelRatio() const { - if (!m_glData.framebufferObject) { - [EAGLContext setCurrentContext:context.nativeContext()]; - - glGenFramebuffers(1, &m_glData.framebufferObject); - glBindFramebuffer(GL_FRAMEBUFFER, m_glData.framebufferObject); - - glGenRenderbuffers(1, &m_glData.colorRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_glData.colorRenderbuffer); - - QSurfaceFormat requestedFormat = context.format(); - if (requestedFormat.depthBufferSize() > 0 || requestedFormat.stencilBufferSize() > 0) { - glGenRenderbuffers(1, &m_glData.depthRenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - if (requestedFormat.stencilBufferSize() > 0) - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_glData.depthRenderbuffer); - } - } - - return m_glData.framebufferObject; + return m_devicePixelRatio; } -GLuint QIOSWindow::colorRenderbuffer(const QIOSContext &context) const +int QIOSWindow::effectiveWidth() const { - if (!m_glData.colorRenderbuffer || - m_glData.renderbufferWidth != geometry().width() * m_devicePixelRatio || - m_glData.renderbufferHeight != geometry().height() * m_devicePixelRatio) { - - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.colorRenderbuffer); - [context.nativeContext() renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast(m_view.layer)]; - - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_glData.renderbufferWidth); - glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_glData.renderbufferHeight); - - if (m_glData.depthRenderbuffer) { - glBindRenderbuffer(GL_RENDERBUFFER, m_glData.depthRenderbuffer); - - // FIXME: Support more fine grained control over depth/stencil buffer sizes - if (context.format().stencilBufferSize() > 0) - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - else - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_glData.renderbufferWidth, m_glData.renderbufferHeight); - } - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); - } - - return m_glData.colorRenderbuffer; + return geometry().width() * m_devicePixelRatio; } -qreal QIOSWindow::devicePixelRatio() const +int QIOSWindow::effectiveHeight() const { - return m_devicePixelRatio; + return geometry().height() * m_devicePixelRatio; } QT_END_NAMESPACE -- cgit v1.2.3 From 16e8eca3621b89730f13e07c258fb8a4ae68a1ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 11:03:59 +0100 Subject: iOS: transfer focus to the window touched MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since our QWindows are UIViews rather than UIWindows, we need to implement window activation manually. This patch will ensure that the window touched by the user also gets keyboard focus. Change-Id: I9390c5c8e50a4b066cd1320a2a044e02f2a9f75d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 88debb7c33..c7c27c08ce 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -151,6 +151,11 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + // Transfer focus to the touched window: + QWindow *window = m_qioswindow->window(); + if (window != QGuiApplication::focusWindow()) + QWindowSystemInterface::handleWindowActivated(window); + [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } -- cgit v1.2.3 From 7150e8f51f44b6299728c5bdfb8cb5b54b8d1141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Jan 2013 15:41:33 +0100 Subject: iOS: Use 72 DPI for font size conversion This matches how UIKit behaves Change-Id: I13fd2578cac84e57b6be29c42ddee414b7ee9cb9 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 762c60e6da..bbc3eb7432 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -63,6 +63,7 @@ public: int depth() const; QImage::Format format() const; QSizeF physicalSize() const; + QDpi logicalDpi() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5905f1630e..f3585407ce 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -178,6 +178,11 @@ QSizeF QIOSScreen::physicalSize() const return m_physicalSize; } +QDpi QIOSScreen::logicalDpi() const +{ + return QDpi(72, 72); +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 355f064ec97cf61c7041a6d32f198a6bde800e6e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 2 Jan 2013 12:53:43 +0100 Subject: iOS: implement QPlatformWindow::raise() and lower() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probably not going to be the most used functions on iOS, but implemented to support old widget apps out of the box. The implementation stacks both staysOnTop and popup windows on the same level for simplicity, since iOS does not have a concept of z-ordering UIViews (UILayer has z-order, but layers belong in a different hierarchy, and cannot be used in this respect). Change-Id: Idd68e5ceea7d4eaeb3066486c47400930cebb1b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 5 +++++ src/plugins/platforms/ios/qioswindow.mm | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 1f36c525ce..e7b04c53eb 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -67,6 +67,9 @@ public: void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); + void raise() { raiseOrLower(true); } + void lower() { raiseOrLower(false); } + qreal devicePixelRatio() const; int effectiveWidth() const; int effectiveHeight() const; @@ -78,6 +81,8 @@ private: QRect m_requestedGeometry; qreal m_devicePixelRatio; + + void raiseOrLower(bool raise); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c7c27c08ce..5bb5048b0a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,8 +153,10 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) + if (window != QGuiApplication::focusWindow()) { + m_qioswindow->raise(); QWindowSystemInterface::handleWindowActivated(window); + } [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -314,6 +316,34 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::raiseOrLower(bool raise) +{ + // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure + // that window flags (staysOnTop, popup) are respected. This function assumes that all + // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at + // the same level: + if (!isQtApplication()) + return; + + NSArray *subviews = m_view.superview.subviews; + if (subviews.count == 1) + return; + + const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; + bool thisWindowIsTop = topFlag & window()->flags(); + + for (int i = int(subviews.count) - 1; i >= 0; --i) { + UIView *view = static_cast([subviews objectAtIndex:i]); + bool otherWindowIsTop = topFlag & view.qwindow->flags(); + if ((raise && (thisWindowIsTop || !otherWindowIsTop)) + || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + [m_view.superview insertSubview:m_view aboveSubview:view]; + return; + } + } + [m_view.superview insertSubview:m_view atIndex:0]; +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From e83bed82c1b58cde1f9a49ad4e4b86d8a13304f1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 13:22:01 +0100 Subject: iOS: raise windows that becomes visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a QWindow becomes visible, it should move to front and be active. Change-Id: Icab12c6031c0cc8d791e4f8cc49b9c2d5c73100d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5bb5048b0a..488962ab66 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -264,7 +264,15 @@ void QIOSWindow::setVisible(bool visible) QPlatformWindow::setVisible(visible); m_view.hidden = !visible; - if (isQtApplication() && !visible) { + if (!isQtApplication()) + return; + + // Since iOS doesn't do window management the way a Qt application + // expects, we need to raise and activate windows ourselves: + if (visible) { + raise(); + QWindowSystemInterface::handleWindowActivated(window()); + } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { -- cgit v1.2.3 From 73e879660376a40fd21ded84020f2e527f22cd13 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 15 Jan 2013 14:30:20 +0100 Subject: iOS: implement QPlatformWindow::requestActivateWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window. Change-Id: Ib97321ed7ec8da90e924ff8155a95896c12160c9 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index e7b04c53eb..01c1978a56 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -69,6 +69,7 @@ public: void raise() { raiseOrLower(true); } void lower() { raiseOrLower(false); } + void requestActivateWindow(); qreal devicePixelRatio() const; int effectiveWidth() const; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 488962ab66..59f82fb64e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,10 +153,8 @@ { // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); - if (window != QGuiApplication::focusWindow()) { - m_qioswindow->raise(); - QWindowSystemInterface::handleWindowActivated(window); - } + if (window != QGuiApplication::focusWindow()) + m_qioswindow->requestActivateWindow(); [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; } @@ -270,8 +268,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { - raise(); - QWindowSystemInterface::handleWindowActivated(window()); + requestActivateWindow(); } else { // Activate top-most visible QWindow: NSArray *subviews = rootViewController().view.subviews; @@ -279,7 +276,7 @@ void QIOSWindow::setVisible(bool visible) UIView *view = [subviews objectAtIndex:i]; if (!view.hidden) { if (QWindow *window = view.qwindow) { - QWindowSystemInterface::handleWindowActivated(window); + static_cast(window->handle())->requestActivateWindow(); break; } } @@ -324,6 +321,15 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::requestActivateWindow() +{ + // Note that several windows can be active at the same time if they exist in the same + // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). + // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + raise(); + QPlatformWindow::requestActivateWindow(); +} + void QIOSWindow::raiseOrLower(bool raise) { // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure -- cgit v1.2.3 From 0a9a4e826fc0a3909481f40d77708a86be55a345 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 16 Jan 2013 10:42:31 +0100 Subject: iOS: let first responder follow the view of the focus window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This to ensure that the keyboard does not close prematurly. This can happen if the user opens up the keyboard while typing inside one window, then switch window, continue typing while the other window gets deleted. Change-Id: I5cfb1673ccbe4d5aaa14167b7aa53451031089a1 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 +++ src/plugins/platforms/ios/qiosinputcontext.mm | 33 ++++++++++++--------------- src/plugins/platforms/ios/qioswindow.mm | 5 ++++ 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index ceed5ffaf2..176ad05733 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -61,8 +61,11 @@ public: void hideInputPanel(); bool isInputPanelVisible() const; + void focusViewChanged(UIView *view); + private: QIOSKeyboardListener *m_keyboardListener; + UIView *m_focusView; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 89d210cb54..c0ff3b2531 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -98,12 +98,14 @@ QIOSInputContext::QIOSInputContext() : QPlatformInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) + , m_focusView(0) { } QIOSInputContext::~QIOSInputContext() { [m_keyboardListener release]; + [m_focusView release]; } QRectF QIOSInputContext::keyboardRect() const @@ -113,33 +115,28 @@ QRectF QIOSInputContext::keyboardRect() const void QIOSInputContext::showInputPanel() { - if (isInputPanelVisible()) - return; - // Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder // to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first - // responder. Rather than searching for it from the top, we assume that the view backing the focus window in Qt - // is the best candidate as long as there exist no first responder from before (which the isInputPanelVisible - // test on top should catch). Note that Qt will forward keyevents to whichever QObject that needs it, regardless of - // which UIView the input actually came from. So in this respect, we're undermining iOS' responder chain. - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() becomeFirstResponder]; - } + // responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use. + // Note that Qt will forward keyevents to whichever QObject that needs it, regardless of which UIView the input + // actually came from. So in this respect, we're undermining iOS' responder chain. + [m_focusView becomeFirstResponder]; } void QIOSInputContext::hideInputPanel() { - if (!isInputPanelVisible()) - return; - - if (QWindow *window = QGuiApplication::focusWindow()) { - QIOSWindow *qiosWindow = static_cast(window->handle()); - [qiosWindow->nativeView() resignFirstResponder]; - } + [m_focusView resignFirstResponder]; } bool QIOSInputContext::isInputPanelVisible() const { return m_keyboardListener->m_keyboardVisible; } + +void QIOSInputContext::focusViewChanged(UIView *view) +{ + if ([m_focusView isFirstResponder]) + [view becomeFirstResponder]; + [m_focusView release]; + m_focusView = [view retain]; +} diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 59f82fb64e..c5d9cbe323 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -42,9 +42,12 @@ #include "qiosglobal.h" #include "qioswindow.h" #include "qioscontext.h" +#include "qiosinputcontext.h" #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include +#include #import @@ -327,6 +330,8 @@ void QIOSWindow::requestActivateWindow() // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: raise(); + QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); + static_cast(context)->focusViewChanged(m_view); QPlatformWindow::requestActivateWindow(); } -- cgit v1.2.3 From f2c52d65608d238ad35ca91099a8751e0c37ef52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 22 Jan 2013 12:00:19 +0100 Subject: iOS: Implement touch events. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Track touch events during the standard [Began -> Moved -> Ended] event sequence based on the UITouch pointer which stays constant. Enable multiTouch on Qt's UIView. Mouse events should now be automatically created from (unhanded) touch events by QGuiApplication. Reviewed by: Ada Sørvig (fingerpaint app approved) Change-Id: I2aeb48c962c697d8b8337f8ceab062070c2a4240 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 3 + src/plugins/platforms/ios/qiosintegration.mm | 11 +++ src/plugins/platforms/ios/qioswindow.h | 9 +++ src/plugins/platforms/ios/qioswindow.mm | 106 ++++++++++++++++++++++++--- 4 files changed, 118 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 5ba97bff6e..054933ea44 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -71,10 +72,12 @@ public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); + QTouchDevice *touchDevice(); private: QPlatformFontDatabase *m_fontDatabase; QPlatformInputContext *m_inputContext; QPlatformScreen *m_screen; + QTouchDevice *m_touchDevice; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 8008c5c0b0..cbe2717c34 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -72,10 +72,16 @@ QIOSIntegration::QIOSIntegration() } screenAdded(m_screen); + + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); } QIOSIntegration::~QIOSIntegration() { + delete m_touchDevice; } QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const @@ -157,4 +163,9 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind return 0; } +QTouchDevice *QIOSIntegration::touchDevice() +{ + return m_touchDevice; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 01c1978a56..b3a94a8d0e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -43,6 +43,7 @@ #define QIOSWINDOW_H #include +#include #import @@ -77,8 +78,16 @@ public: UIView *nativeView() const { return m_view; } + QList &touchPoints() { return m_touchPoints; } + QHash &activeTouches() { return m_activeTouches; } + int &touchId() { return m_touchId; } + private: UIView *m_view; + QList m_touchPoints; + QHash m_activeTouches; + int m_touchId; + QRect m_requestedGeometry; qreal m_devicePixelRatio; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index c5d9cbe323..91e75bc660 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -46,6 +46,7 @@ #include "qiosscreen.h" #include "qiosapplicationdelegate.h" #include "qiosviewcontroller.h" +#include "qiosintegration.h" #include #include @@ -115,6 +116,8 @@ if (isQtApplication()) self.hidden = YES; + + self.multipleTouchEnabled = YES; } return self; @@ -142,39 +145,119 @@ [super layoutSubviews]; } -- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons +/* + Touch handling: + + UIKit generates [Began -> Moved -> Ended] event sequences for + each touch point. The iOS plugin tracks each individual + touch and assigns it an id for use by Qt. The id counter is + incremented on each began and decrement as follows: + 1) by one when the most recent touch ends. + 2) to zero when all touches ends. + + The TouchPoint list is reused between events. +*/ +- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { - UITouch *touch = [touches anyObject]; - CGPoint locationInView = [touch locationInView:self]; - QPoint p(locationInView.x , locationInView.y); + QList &touchPoints = m_qioswindow->touchPoints(); + QHash &activeTouches = m_qioswindow->activeTouches(); + + // Mark all touch points as stationary + for (QList::iterator it = touchPoints.begin(); it != touchPoints.end(); ++it) + it->state = Qt::TouchPointStationary; + + // Update changed touch points with the new state + for (UITouch *touch in touches) { + const int touchId = activeTouches.value(touch); + QWindowSystemInterface::TouchPoint &touchPoint = touchPoints[touchId]; + touchPoint.state = state; + if (state == Qt::TouchPointPressed) + touchPoint.pressure = 1.0; + else if (state == Qt::TouchPointReleased) + touchPoint.pressure = 0.0; + + // Set position + CGPoint location = [touch locationInView:self]; + touchPoint.area = QRectF(location.x, location.y, 0, 0); + QSize viewSize = fromCGRect(self.frame).size(); + touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + } +} - // TODO handle global touch point? for status bar? - QWindowSystemInterface::handleMouseEvent(m_qioswindow->window(), (ulong)(event.timestamp*1000), p, p, buttons); +- (void) sendTouchEventWithTimestamp:(ulong)timeStamp +{ + // Send touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp, + iosIntegration->touchDevice(), m_qioswindow->touchPoints()); + QWindowSystemInterface::flushWindowSystemEvents(); } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - // Transfer focus to the touched window: QWindow *window = m_qioswindow->window(); + + // Transfer focus to the touched window: if (window != QGuiApplication::focusWindow()) m_qioswindow->requestActivateWindow(); - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + // Track Cocoa touch id to Qt touch id. The UITouch pointer is constant + // for the touch duration. + QHash &activeTouches = m_qioswindow->activeTouches(); + QList &touchPoints = m_qioswindow->touchPoints(); + for (UITouch *touch in touches) + activeTouches.insert(touch, m_qioswindow->touchId()++); + + // Create new touch points if needed. + int newTouchPointsNeeded = m_qioswindow->touchId() - touchPoints.count(); + for (int i = 0; i < newTouchPointsNeeded; ++i) { + QWindowSystemInterface::TouchPoint touchPoint; + touchPoint.id = touchPoints.count(); // id is the index in the touchPoints list. + touchPoints.append(touchPoint); + } + + [self updateTouchList:touches withState:Qt::TouchPointPressed]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton]; + [self updateTouchList:touches withState:Qt::TouchPointMoved]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + [self updateTouchList:touches withState:Qt::TouchPointReleased]; + [self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)]; + + // Remove ended touch points from the active set (event processing has completed at this point) + QHash &activeTouches = m_qioswindow->activeTouches(); + for (UITouch *touch in touches) { + int id = activeTouches.take(touch); + + // If this touch is the most recent touch we can reuse its id + if (id == m_qioswindow->touchId() - 1) + --m_qioswindow->touchId(); + } + + // Reset the touch id when there are no more active touches + if (activeTouches.isEmpty()) + m_qioswindow->touchId() = 0; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton]; + Q_UNUSED(touches) // ### can a subset of the active touches be cancelled? + + // Clear current touch points + m_qioswindow->activeTouches().clear(); + m_qioswindow->touchId() = 0; + + // Send cancel touch event synchronously + QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(event.timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::flushWindowSystemEvents(); } @synthesize autocapitalizationType; @@ -236,6 +319,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) , m_devicePixelRatio(1.0) { -- cgit v1.2.3 From 38e6d5a91588bfe823ff6bcb19bd356965d328f7 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:49:34 +0100 Subject: iOS: add QIOSWindow::windowLevel() to simplify window stacking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When adding modal windows into the mix, raiseOrLower became even more messy to write. So do it the usual way instead, and add a windowLevel variable to each QIOSWindow that we can sort on. The code becomes more readable, and we can handle more window types correctly. Change-Id: I348352473a7d8cf9909c17c1b074b2fe3fab9819 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 3 ++- src/plugins/platforms/ios/qioswindow.mm | 42 +++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b3a94a8d0e..2d7c4c9103 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -89,10 +89,11 @@ private: int m_touchId; QRect m_requestedGeometry; - + int m_windowLevel; qreal m_devicePixelRatio; void raiseOrLower(bool raise); + void updateWindowLevel(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 91e75bc660..4aa6b8a24e 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -321,6 +321,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) , m_touchId(0) , m_requestedGeometry(QPlatformWindow::geometry()) + , m_windowLevel(0) , m_devicePixelRatio(1.0) { if (isQtApplication()) @@ -355,6 +356,7 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: if (visible) { + updateWindowLevel(); requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -421,10 +423,8 @@ void QIOSWindow::requestActivateWindow() void QIOSWindow::raiseOrLower(bool raise) { - // Re-insert m_view at the correct index among its sibling views (QWindows), and ensure - // that window flags (staysOnTop, popup) are respected. This function assumes that all - // sibling views are sorted correctly. Note: We sort popup and staysOnTop windows at - // the same level: + // Re-insert m_view at the correct index among its sibling views + // (QWindows) according to their current m_windowLevel: if (!isQtApplication()) return; @@ -432,14 +432,12 @@ void QIOSWindow::raiseOrLower(bool raise) if (subviews.count == 1) return; - const Qt::WindowFlags topFlag = (Qt::Popup | Qt::WindowStaysOnTopHint) & ~Qt::Dialog; - bool thisWindowIsTop = topFlag & window()->flags(); - for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = static_cast([subviews objectAtIndex:i]); - bool otherWindowIsTop = topFlag & view.qwindow->flags(); - if ((raise && (thisWindowIsTop || !otherWindowIsTop)) - || (!raise && (thisWindowIsTop && !otherWindowIsTop))) { + if (view.hidden || view == m_view) + continue; + int level = static_cast(view.qwindow->handle())->m_windowLevel; + if (m_windowLevel > level || (raise && m_windowLevel == level)) { [m_view.superview insertSubview:m_view aboveSubview:view]; return; } @@ -447,6 +445,30 @@ void QIOSWindow::raiseOrLower(bool raise) [m_view.superview insertSubview:m_view atIndex:0]; } +void QIOSWindow::updateWindowLevel() +{ + Qt::WindowType type = static_cast(int(window()->flags() & Qt::WindowType_Mask)); + + if (type == Qt::ToolTip) + m_windowLevel = 120; + else if (window()->flags() & Qt::WindowStaysOnTopHint) + m_windowLevel = 100; + else if (window()->isModal()) + m_windowLevel = 30; + else if (type & Qt::Popup & ~Qt::Window) + m_windowLevel = 20; + else if (type == Qt::Tool) + m_windowLevel = 10; + else + m_windowLevel = 0; + + // A window should be in at least the same m_windowLevel as its parent: + QWindow *transientParent = window()->transientParent(); + QIOSWindow *transientParentWindow = transientParent ? static_cast(transientParent->handle()) : 0; + if (transientParentWindow) + m_windowLevel = qMax(transientParentWindow->m_windowLevel, m_windowLevel); +} + void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation) { // Keep the status bar in sync with content orientation. This will ensure -- cgit v1.2.3 From 58415530aacc5ef92f0076f7dff04d4f5074c4da Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 25 Jan 2013 11:00:54 +0100 Subject: iOS: avoid activating modally blocked windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the user cannot activate a window that is modally shaddowed. Change-Id: Ib92be319d017460bbc1ef63ad7556cb4758dfa6c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 2d7c4c9103..31fd8d3185 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -94,6 +94,7 @@ private: void raiseOrLower(bool raise); void updateWindowLevel(); + bool blockedByModal(); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 4aa6b8a24e..9bc2541715 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -345,6 +345,12 @@ QIOSWindow::~QIOSWindow() [m_view release]; } +bool QIOSWindow::blockedByModal() +{ + QWindow *modalWindow = QGuiApplication::modalWindow(); + return modalWindow && modalWindow != window(); +} + void QIOSWindow::setVisible(bool visible) { QPlatformWindow::setVisible(visible); @@ -355,8 +361,16 @@ void QIOSWindow::setVisible(bool visible) // Since iOS doesn't do window management the way a Qt application // expects, we need to raise and activate windows ourselves: - if (visible) { + if (visible) updateWindowLevel(); + + if (blockedByModal()) { + if (visible) + raise(); + return; + } + + if (visible) { requestActivateWindow(); } else { // Activate top-most visible QWindow: @@ -415,6 +429,9 @@ void QIOSWindow::requestActivateWindow() // Note that several windows can be active at the same time if they exist in the same // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: + if (blockedByModal()) + return; + raise(); QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); -- cgit v1.2.3 From 60685407c208466c67830744808b8a902bd2377b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 30 Jan 2013 20:31:06 +0100 Subject: iOS: Enable retina resolution for styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QStyle code uses the global qApp->devicePixelRatio(), which queries the screen, not the window. Implement QIOSScreen::devicePixelRatio(). Change-Id: I0091e5793f8d07ab7a46b6de443edd9457dcff85 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index bbc3eb7432..40c7a3ccf7 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -64,6 +64,7 @@ public: QImage::Format format() const; QSizeF physicalSize() const; QDpi logicalDpi() const; + qreal devicePixelRatio() const; Qt::ScreenOrientation nativeOrientation() const; Qt::ScreenOrientation orientation() const; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index f3585407ce..5cee5a3362 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -183,6 +183,11 @@ QDpi QIOSScreen::logicalDpi() const return QDpi(72, 72); } +qreal QIOSScreen::devicePixelRatio() const +{ + return [m_uiScreen scale]; +} + Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { return Qt::PortraitOrientation; -- cgit v1.2.3 From 5ac2a3f045c47bed634b269fc298921ddb699704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Feb 2013 13:34:46 +0100 Subject: iOS: Silence warning about 'long long' being a C++11 extension At some point we want to build with C++11 support, but for now we silence the warning. Change-Id: I40deb0925d459eaf06e324dddc0a2e9893c57615 Reviewed-by: Richard Moe Gustavsen --- mkspecs/common/ios/clang.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index 9b092d3fa4..41499a4ee8 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -10,7 +10,7 @@ QMAKE_IOS_CFLAGS += -fvisibility=hidden -fpascal-strings -fmessage-length=0 QMAKE_IOS_CFLAGS += -Wno-trigraphs -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -Wno-sign-conversion QMAKE_IOS_CXXFLAGS += -fvisibility-inlines-hidden -QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi -Wc++0x-extensions +QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi # Based on the following information, http://clang.llvm.org/doxygen/ObjCRuntime_8h_source.html, # we can conclude that it's safe to always pass the following flags @@ -21,9 +21,12 @@ QMAKE_IOS_OBJ_CFLAGS += -fobjc-nonfragile-abi -fobjc-legacy-dispatch # Clang 3.1 (and above) flags QMAKE_IOS_CFLAGS += -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-implicit-atomic-properties -Wformat -Wno-missing-braces -Wno-unused-function -Wno-unused-label -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-sign-compare -Wpointer-sign -Wno-newline-eof -Wdeprecated-declarations -Winvalid-offsetof -Wno-conversion -QMAKE_IOS_CXXFLAGS += -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wc++11-extensions +QMAKE_IOS_CXXFLAGS += -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors QMAKE_IOS_OBJ_CFLAGS += -Wno-deprecated-implementations -Wprotocol -Wno-selector -Wno-strict-selector-match -Wno-undeclared-selector +# We do not yet build with C++11 support, so warn about extensions unless they are used all over Qt +QMAKE_IOS_CXXFLAGS += -Wc++11-extensions -Wc++0x-extensions -Wno-c++11-long-long + # Warn about unsupported (later than 4.5) Xcode versions !lessThan(QMAKE_IOS_XCODE_VERSION, "4.6"): warning("The version of Xcode installed on this system is not recognised - custom compiler settings may be necessary") -- cgit v1.2.3 From 15bdf85f28b56abc31449891935783bb74772ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Feb 2013 14:10:31 +0100 Subject: iOS: Bump max Xcode version to 4.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to figure out where to draw the line when it comes to warning about unknown compiler (Clang), Xcode, or SDK versions, but for now building with Xcode 4.6 should not be an issue. We'll have to revisit this and test with the full set of compiler/Xcode/SDKs we support before the final release. Change-Id: Iac3ec3a25c0f7618b2c3714657d147f17f834d97 Reviewed-by: Morten Johan Sørvig --- mkspecs/common/ios/clang.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/ios/clang.conf b/mkspecs/common/ios/clang.conf index 41499a4ee8..7513a0a315 100644 --- a/mkspecs/common/ios/clang.conf +++ b/mkspecs/common/ios/clang.conf @@ -28,7 +28,7 @@ QMAKE_IOS_OBJ_CFLAGS += -Wno-deprecated-implementations -Wprotocol -Wno-selector QMAKE_IOS_CXXFLAGS += -Wc++11-extensions -Wc++0x-extensions -Wno-c++11-long-long # Warn about unsupported (later than 4.5) Xcode versions -!lessThan(QMAKE_IOS_XCODE_VERSION, "4.6"): warning("The version of Xcode installed on this system is not recognised - custom compiler settings may be necessary") +!lessThan(QMAKE_IOS_XCODE_VERSION, "4.7"): warning("The version of Xcode installed on this system is not recognised - custom compiler settings may be necessary") # Set build flags QMAKE_CFLAGS += $$QMAKE_IOS_CFLAGS -- cgit v1.2.3 From 4993d3ed6bff681889faec3711fffa2400b7a601 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 Feb 2013 11:34:14 +0100 Subject: iOS: implement QIOSWindow::winId() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3dd7accae43bcf7d4d6dfd8b272ab65d67bd935c Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioscontext.mm | 3 ++- src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qioswindow.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index dc431b57dd..d3966964e0 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -160,7 +160,8 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) { glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer); - CAEAGLLayer *layer = static_cast(platformWindow->nativeView().layer); + UIView *view = reinterpret_cast(platformWindow->winId()); + CAEAGLLayer *layer = static_cast(view.layer); [m_eaglContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferObject.renderbufferWidth); diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index cbe2717c34..c5fef243ce 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -158,7 +158,7 @@ void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWind QIOSWindow *platformWindow = static_cast(window->handle()); if (lowerCaseResource == "uiview") - return platformWindow->nativeView(); + return reinterpret_cast(platformWindow->winId()); return 0; } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 31fd8d3185..7a0224dab0 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -76,7 +76,7 @@ public: int effectiveWidth() const; int effectiveHeight() const; - UIView *nativeView() const { return m_view; } + WId winId() const { return WId(m_view); }; QList &touchPoints() { return m_touchPoints; } QHash &activeTouches() { return m_activeTouches; } -- cgit v1.2.3 From 029029fa97b8f11b2384040f12dc1ca6b31e03a6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 4 Feb 2013 12:42:59 +0100 Subject: iOS: QIOSWindow::setParent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1a413d898d10b55a4d0653eae719f5bd909a01ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 7a0224dab0..cefb6f9388 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -65,6 +65,7 @@ public: void setGeometry(const QRect &rect); void setWindowState(Qt::WindowState state); + void setParent(const QPlatformWindow *window); void handleContentOrientationChange(Qt::ScreenOrientation orientation); void setVisible(bool visible); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9bc2541715..e95f392655 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -324,9 +324,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_windowLevel(0) , m_devicePixelRatio(1.0) { - if (isQtApplication()) - [rootViewController().view addSubview:m_view]; - + setParent(parent()); setWindowState(window->windowState()); // Retina support: get screen scale factor and set it in the content view. @@ -424,6 +422,16 @@ void QIOSWindow::setWindowState(Qt::WindowState state) } } +void QIOSWindow::setParent(const QPlatformWindow *parentWindow) +{ + if (parentWindow) { + UIView *parentView = reinterpret_cast(parentWindow->winId()); + [parentView addSubview:m_view]; + } else if (isQtApplication()) { + [rootViewController().view addSubview:m_view]; + } +} + void QIOSWindow::requestActivateWindow() { // Note that several windows can be active at the same time if they exist in the same -- cgit v1.2.3 From 3eeb388b429242da8bfd9b9dc70660980f62090a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 8 Feb 2013 13:36:24 +0100 Subject: iOS: Skip flushing child windows in QIOSBackingStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We skip flushing raster-based child windows, to avoid the extra cost of copying from the parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it will become visible when flushing the parent. The only case we end up not supporting is if the child window overlaps a sibling window that's draws using a separate QOpenGLContext. Change-Id: Ib10414f4494747e5fe67f84b06575fe16ffddf96 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 5ee048cb2f..566ff3a672 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -92,6 +92,13 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin Q_UNUSED(region); Q_UNUSED(offset); + if (window != this->window()) { + // We skip flushing raster-based child windows, to avoid the extra cost of copying from the + // parent FBO into the child FBO. Since the child is already drawn inside the parent FBO, it + // will become visible when flushing the parent. The only case we end up not supporting is if + // the child window overlaps a sibling window that's draws using a separate QOpenGLContext. + return; + } m_context->swapBuffers(window); } -- cgit v1.2.3 From 11d50be6dd8bbfe695408ccd011cbf63f1b4324a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 13:09:08 +0100 Subject: iOS: Set touch point position in screen coords. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously the position was set in window coordinates, which would break for non-fullscreen windows. Change-Id: Iefa2f590c6d62b09fc3e7fe60a882c1acd33e029 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 2 ++ src/plugins/platforms/ios/qiosglobal.mm | 10 ++++++++++ src/plugins/platforms/ios/qioswindow.mm | 11 +++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 3fe426c901..cd265c0603 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -54,6 +54,8 @@ QIOSViewController *rootViewController(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); +CGPoint toCGPoint(const QPoint &point); +QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); QRect fromPortraitToPrimary(const QRect &rect); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 712968d216..4657b73a10 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -75,6 +75,16 @@ QRect fromCGRect(const CGRect &rect) return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } +CGPoint toCGPoint(const QPoint &point) +{ + return CGPointMake(point.x(), point.y()); +} + +QPoint fromCGPoint(const CGPoint &point) +{ + return QPoint(point.x, point.y); +} + Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) { Qt::ScreenOrientation qtOrientation; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e95f392655..e4fb5e2e1c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -177,10 +177,13 @@ touchPoint.pressure = 0.0; // Set position - CGPoint location = [touch locationInView:self]; - touchPoint.area = QRectF(location.x, location.y, 0, 0); - QSize viewSize = fromCGRect(self.frame).size(); - touchPoint.normalPosition = QPointF(location.x / viewSize.width(), location.y / viewSize.height()); + QRect viewGeometry = fromCGRect(self.frame); + QPoint touchViewLocation = fromCGPoint([touch locationInView:self]); + QPoint touchScreenLocation = touchViewLocation + viewGeometry.topLeft(); + touchPoint.area = QRectF(touchScreenLocation , QSize(0, 0)); + + CGSize fullscreenSize = self.window.rootViewController.view.bounds.size; + touchPoint.normalPosition = QPointF(touchScreenLocation.x() / fullscreenSize.width, touchScreenLocation.y() / fullscreenSize.height); } } -- cgit v1.2.3 From c75bc5b532479e8dbe6b7f07dcc5f9fcc915f5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 14:08:09 +0100 Subject: iOS: Don't crash on landscape mode startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fromPortraitToPrimary is called from the QIOSScreen constructor. This is probably to early to call QGuiApplication functions. Change-Id: I882304fd641df13dc530491990245ba9ad495377 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 4 +++- src/plugins/platforms/ios/qiosglobal.mm | 4 ++-- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- src/plugins/platforms/ios/qiosscreen.mm | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index cd265c0603..3be9f8bb21 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE +class QPlatformScreen; + bool isQtApplication(); QIOSViewController *rootViewController(); @@ -58,7 +60,7 @@ CGPoint toCGPoint(const QPoint &point); QPoint fromCGPoint(const CGPoint &point); Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); -QRect fromPortraitToPrimary(const QRect &rect); +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 4657b73a10..5860078372 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -131,11 +131,11 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation) return uiOrientation; } -QRect fromPortraitToPrimary(const QRect &rect) +QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen) { // UIScreen is always in portrait. Use this function to convert CGRects // aligned with UIScreen into whatever is the current orientation of QScreen. - QRect geometry = QGuiApplication::primaryScreen()->handle()->geometry(); + QRect geometry = screen->geometry(); return geometry.width() < geometry.height() ? rect : QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width()); } diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index c0ff3b2531..1d3ab12de9 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -83,7 +83,7 @@ CGRect frame; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; - m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame)); + m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle()); m_context->emitKeyboardRectChanged(); BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 5cee5a3362..3265ed8e37 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -224,7 +224,7 @@ void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) // Switching portrait/landscape means swapping width/height (and adjusting x/y): m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); - m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame)); + m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame), this); QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -- cgit v1.2.3 From fecc1554080aa58167b8cc7018b2ccd037d05cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 14 Feb 2013 19:45:48 +0100 Subject: iOS: Enable autorotate on startup. The qobject_cast to QGuiAppplication will always fail at startup since QGuiApplication is not ready yet. Return YES in that case. Allowed orientations can then be controlled by setting "Supported Interface Orientations" in Xcode or the Info.plist file. Change-Id: Ifd86bbcedabc716e63563bbb7cb0c1c6833fd6c7 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index c85058743c..c52bfd7345 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -63,7 +63,7 @@ if (QGuiApplication *guiApp = qobject_cast(qApp)) return !guiApp->primaryScreen()->orientationUpdateMask(); else - return NO; + return YES; // Startup case: QGuiApplication is not ready yet. // FIXME: Investigate a proper Qt API for auto-rotation and orientation locking } -- cgit v1.2.3 From 0c1ae5f8660941fed55c468487635c9a74846f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Feb 2013 08:07:04 +0100 Subject: iOS: Add potentially undefined version defines to qsystemdetection.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unless we're building on the 6.1 SDK some of the version defines will not be defined in Availability.h, so we define them ourselves so that Qt can still use them. Change-Id: Ibb45e9f8f4e888fc57e35286bf15d2fee2c1a217 Reviewed-by: Morten Johan Sørvig --- src/corelib/global/qsystemdetection.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 86c724ebb5..6062dc7b7b 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -208,6 +208,22 @@ # define MAC_OS_X_VERSION_10_8 1080 # endif # +# if !defined(__IPHONE_4_3) +# define __IPHONE_4_3 40300 +# endif +# if !defined(__IPHONE_5_0) +# define __IPHONE_5_0 50000 +# endif +# if !defined(__IPHONE_5_1) +# define __IPHONE_5_1 50100 +# endif +# if !defined(__IPHONE_6_0) +# define __IPHONE_6_0 60000 +# endif +# if !defined(__IPHONE_6_1) +# define __IPHONE_6_1 60100 +# endif +# # if (__MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_8) # warning "This version of Mac OS X is unsupported" # endif -- cgit v1.2.3 From aa5528b050472d1d1097e2665fb346232cbfa7e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 15 Feb 2013 11:25:39 +0100 Subject: iOS: Implement socket notifiers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create the QCFSocketNotifier class in platform support which contains shared socket notifier support for the Cocoa and iOS plugins. Remove the old code from the Cocoa plugin. The Cocoa code had one QCocoaEventDispatcher-specific call: maybeCancelWaitForMoreEvents. Create a forwarding function that is passed to QCFSocketNotifier. Change-Id: Ibf9bd4745ba4f577a55f13d0cc00f5ae04447405 Reviewed-by: Tor Arne Vestbø Reviewed-by: Richard Moe Gustavsen --- .../cfsocketnotifier/cfsocketnotifier.pri | 4 + .../cfsocketnotifier/qcfsocketnotifier.cpp | 255 +++++++++++++++++++++ .../cfsocketnotifier/qcfsocketnotifier_p.h | 90 ++++++++ src/platformsupport/platformsupport.pro | 1 + .../platforms/cocoa/qcocoaeventdispatcher.h | 12 +- .../platforms/cocoa/qcocoaeventdispatcher.mm | 193 +--------------- src/plugins/platforms/ios/qioseventdispatcher.h | 3 + src/plugins/platforms/ios/qioseventdispatcher.mm | 10 +- 8 files changed, 374 insertions(+), 194 deletions(-) create mode 100644 src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri create mode 100644 src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp create mode 100644 src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h diff --git a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri new file mode 100644 index 0000000000..9a19d3c278 --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri @@ -0,0 +1,4 @@ +mac { + HEADERS += $$PWD/qcfsocketnotifier_p.h + SOURCES += $$PWD/qcfsocketnotifier.cpp +} diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp new file mode 100644 index 0000000000..5dcd6a4ffd --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcfsocketnotifier_p.h" +#include +#include +#include + + +/************************************************************************** + Socket Notifiers + *************************************************************************/ +void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef, + const void *, void *info) +{ + + QCFSocketNotifier *cfSocketNotifier = static_cast(info); + int nativeSocket = CFSocketGetNative(s); + MacSocketInfo *socketInfo = cfSocketNotifier->macSockets.value(nativeSocket); + QEvent notifierEvent(QEvent::SockAct); + + // There is a race condition that happen where we disable the notifier and + // the kernel still has a notification to pass on. We then get this + // notification after we've successfully disabled the CFSocket, but our Qt + // notifier is now gone. The upshot is we have to check the notifier + // every time. + if (callbackType == kCFSocketReadCallBack) { + if (socketInfo->readNotifier) + QGuiApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); + } else if (callbackType == kCFSocketWriteCallBack) { + if (socketInfo->writeNotifier) + QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); + } + + if (cfSocketNotifier->maybeCancelWaitForMoreEvents) + cfSocketNotifier->maybeCancelWaitForMoreEvents(cfSocketNotifier->eventDispatcher); +} + +/* + Adds a loop source for the given socket to the current run loop. +*/ +CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket) +{ + CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); + if (!loopSource) + return 0; + + CFRunLoopAddSource(CFRunLoopGetMain(), loopSource, kCFRunLoopCommonModes); + return loopSource; +} + +/* + Removes the loop source for the given socket from the current run loop. +*/ +void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) +{ + Q_ASSERT(runloop); + CFRunLoopRemoveSource(CFRunLoopGetMain(), runloop, kCFRunLoopCommonModes); + CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); + CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); + CFRunLoopSourceInvalidate(runloop); +} + +QCFSocketNotifier::QCFSocketNotifier() +:eventDispatcher(0) +{ + +} + +QCFSocketNotifier::~QCFSocketNotifier() +{ + +} + +void QCFSocketNotifier::setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher) +{ + eventDispatcher = hostEventDispacher; +} + +void QCFSocketNotifier::setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack) +{ + maybeCancelWaitForMoreEvents = callBack; +} + +void QCFSocketNotifier::registerSocketNotifier(QSocketNotifier *notifier) +{ + Q_ASSERT(notifier); + int nativeSocket = notifier->socket(); + int type = notifier->type(); +#ifndef QT_NO_DEBUG + if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { + qWarning("QSocketNotifier: Internal error"); + return; + } else if (notifier->thread() != eventDispatcher->thread() + || eventDispatcher->thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); + return; + } +#endif + + if (type == QSocketNotifier::Exception) { + qWarning("QSocketNotifier::Exception is not supported on iOS"); + return; + } + + // Check if we have a CFSocket for the native socket, create one if not. + MacSocketInfo *socketInfo = macSockets.value(nativeSocket); + if (!socketInfo) { + socketInfo = new MacSocketInfo(); + + // Create CFSocket, specify that we want both read and write callbacks (the callbacks + // are enabled/disabled later on). + const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; + CFSocketContext context = {0, this, 0, 0, 0}; + socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); + if (CFSocketIsValid(socketInfo->socket) == false) { + qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); + return; + } + + CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); + flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write + flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation + CFSocketSetSocketFlags(socketInfo->socket, flags); + + // Add CFSocket to runloop. + if (!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { + qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + return; + } + + // Disable both callback types by default. This must be done after + // we add the CFSocket to the runloop, or else these calls will have + // no effect. + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + + macSockets.insert(nativeSocket, socketInfo); + } + + // Increment read/write counters and select enable callbacks if necessary. + if (type == QSocketNotifier::Read) { + Q_ASSERT(socketInfo->readNotifier == 0); + socketInfo->readNotifier = notifier; + CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + } else if (type == QSocketNotifier::Write) { + Q_ASSERT(socketInfo->writeNotifier == 0); + socketInfo->writeNotifier = notifier; + CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + } +} + +void QCFSocketNotifier::unregisterSocketNotifier(QSocketNotifier *notifier) +{ + Q_ASSERT(notifier); + int nativeSocket = notifier->socket(); + int type = notifier->type(); +#ifndef QT_NO_DEBUG + if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { + qWarning("QSocketNotifier: Internal error"); + return; + } else if (notifier->thread() != eventDispatcher->thread() || eventDispatcher->thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); + return; + } +#endif + + if (type == QSocketNotifier::Exception) { + qWarning("QSocketNotifier::Exception is not supported on iOS"); + return; + } + MacSocketInfo *socketInfo = macSockets.value(nativeSocket); + if (!socketInfo) { + qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); + return; + } + + // Decrement read/write counters and disable callbacks if necessary. + if (type == QSocketNotifier::Read) { + Q_ASSERT(notifier == socketInfo->readNotifier); + socketInfo->readNotifier = 0; + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); + } else if (type == QSocketNotifier::Write) { + Q_ASSERT(notifier == socketInfo->writeNotifier); + socketInfo->writeNotifier = 0; + CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); + } + + // Remove CFSocket from runloop if this was the last QSocketNotifier. + if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) { + if (CFSocketIsValid(socketInfo->socket)) + qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); + CFRunLoopSourceInvalidate(socketInfo->runloop); + CFRelease(socketInfo->runloop); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + delete socketInfo; + macSockets.remove(nativeSocket); + } +} + +void QCFSocketNotifier::removeSocketNotifiers() +{ + // Remove CFSockets from the runloop. + for (MacSocketHash::ConstIterator it = macSockets.constBegin(); it != macSockets.constEnd(); ++it) { + MacSocketInfo *socketInfo = (*it); + if (CFSocketIsValid(socketInfo->socket)) { + qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); + CFRunLoopSourceInvalidate(socketInfo->runloop); + CFRelease(socketInfo->runloop); + CFSocketInvalidate(socketInfo->socket); + CFRelease(socketInfo->socket); + } + } +} diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h new file mode 100644 index 0000000000..cd1eb8e4ca --- /dev/null +++ b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCFSOCKETNOTIFIER_P_H +#define QCFSOCKETNOTIFIER_P_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +struct MacSocketInfo { + MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {} + CFSocketRef socket; + CFRunLoopSourceRef runloop; + QObject *readNotifier; + QObject *writeNotifier; +}; +typedef QHash MacSocketHash; + +typedef void (*MaybeCancelWaitForMoreEventsFn)(QAbstractEventDispatcher *hostEventDispacher); + +// The CoreFoundationSocketNotifier class implements socket notifiers support using +// CFSocket for event dispatchers running on top of the Core Foundation run loop system. +// (currently Mac and iOS) +// +// The principal functions are registerSocketNotifier() and unregisterSocketNotifier(). +// +// setHostEventDispatcher() should be called at startup. +// removeSocketNotifiers() should be called at shutdown. +// +class QCFSocketNotifier +{ +public: + QCFSocketNotifier(); + ~QCFSocketNotifier(); + void setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher); + void setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack); + void registerSocketNotifier(QSocketNotifier *notifier); + void unregisterSocketNotifier(QSocketNotifier *notifier); + void removeSocketNotifiers(); + + MacSocketHash macSockets; + QAbstractEventDispatcher *eventDispatcher; + MaybeCancelWaitForMoreEventsFn maybeCancelWaitForMoreEvents; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 469c76ffae..8e0f396993 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -9,6 +9,7 @@ load(qt_module) DEFINES += QT_NO_CAST_FROM_ASCII PRECOMPILED_HEADER = ../corelib/global/qt_pch.h +include(cfsocketnotifier/cfsocketnotifier.pri) include(cglconvenience/cglconvenience.pri) include(dnd/dnd.pri) include(eglconvenience/eglconvenience.pri) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index f63ac0d205..93476ee1b4 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -93,6 +93,7 @@ #include #include #include +#include #include @@ -132,16 +133,9 @@ public: void wakeUp(); void interrupt(); void flush(); -}; -struct MacSocketInfo { - MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {} - CFSocketRef socket; - CFRunLoopSourceRef runloop; - QObject *readNotifier; - QObject *writeNotifier; + friend void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher); }; -typedef QHash MacSocketHash; class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate { @@ -183,7 +177,7 @@ public: void maybeCancelWaitForMoreEvents(); void ensureNSAppInitialized(); - MacSocketHash macSockets; + QCFSocketNotifier cfSocketNotifier; QList queuedUserInputEvents; // NSEvent * CFRunLoopSourceRef postedEventsSource; CFRunLoopObserverRef waitingObserver; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 987600c6b4..ed4f8cd1fb 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -270,58 +270,6 @@ QCocoaEventDispatcher::registeredTimers(QObject *object) const return d->timerInfoList.registeredTimers(object); } -/************************************************************************** - Socket Notifiers - *************************************************************************/ -void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef, - const void *, void *info) { - QCocoaEventDispatcherPrivate *const eventDispatcher - = static_cast(info); - int nativeSocket = CFSocketGetNative(s); - MacSocketInfo *socketInfo = eventDispatcher->macSockets.value(nativeSocket); - QEvent notifierEvent(QEvent::SockAct); - - // There is a race condition that happen where we disable the notifier and - // the kernel still has a notification to pass on. We then get this - // notification after we've successfully disabled the CFSocket, but our Qt - // notifier is now gone. The upshot is we have to check the notifier - // everytime. - if (callbackType == kCFSocketReadCallBack) { - if (socketInfo->readNotifier) - QGuiApplication::sendEvent(socketInfo->readNotifier, ¬ifierEvent); - } else if (callbackType == kCFSocketWriteCallBack) { - if (socketInfo->writeNotifier) - QGuiApplication::sendEvent(socketInfo->writeNotifier, ¬ifierEvent); - } - - eventDispatcher->maybeCancelWaitForMoreEvents(); -} - -/* - Adds a loop source for the given socket to the current run loop. -*/ -CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket) -{ - CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0); - if (!loopSource) - return 0; - - CFRunLoopAddSource(mainRunLoop(), loopSource, kCFRunLoopCommonModes); - return loopSource; -} - -/* - Removes the loop source for the given socket from the current run loop. -*/ -void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop) -{ - Q_ASSERT(runloop); - CFRunLoopRemoveSource(mainRunLoop(), runloop, kCFRunLoopCommonModes); - CFSocketDisableCallBacks(socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack); - CFRunLoopSourceInvalidate(runloop); -} - /* Register a QSocketNotifier with the mac event system by creating a CFSocket with with a read/write callback. @@ -331,130 +279,14 @@ void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSource */ void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() - || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - - // Check if we have a CFSocket for the native socket, create one if not. - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - socketInfo = new MacSocketInfo(); - - // Create CFSocket, specify that we want both read and write callbacks (the callbacks - // are enabled/disabled later on). - const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack; - CFSocketContext context = {0, d, 0, 0, 0}; - socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context); - if (CFSocketIsValid(socketInfo->socket) == false) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket"); - return; - } - - CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket); - flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write - flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation - CFSocketSetSocketFlags(socketInfo->socket, flags); - - // Add CFSocket to runloop. - if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) { - qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop"); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - return; - } - - // Disable both callback types by default. This must be done after - // we add the CFSocket to the runloop, or else these calls will have - // no effect. - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - - d->macSockets.insert(nativeSocket, socketInfo); - } - - // Increment read/write counters and select enable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(socketInfo->readNotifier == 0); - socketInfo->readNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(socketInfo->writeNotifier == 0); - socketInfo->writeNotifier = notifier; - CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } + d->cfSocketNotifier.registerSocketNotifier(notifier); } -/* - Unregister QSocketNotifer. The CFSocket correspoding to this notifier is - removed from the runloop of this is the last notifier that users - that CFSocket. -*/ void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - Q_ASSERT(notifier); - int nativeSocket = notifier->socket(); - int type = notifier->type(); -#ifndef QT_NO_DEBUG - if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) { - qWarning("QSocketNotifier: Internal error"); - return; - } else if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); - return; - } -#endif - Q_D(QCocoaEventDispatcher); - - if (type == QSocketNotifier::Exception) { - qWarning("QSocketNotifier::Exception is not supported on Mac OS X"); - return; - } - MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket); - if (!socketInfo) { - qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier"); - return; - } - - // Decrement read/write counters and disable callbacks if necessary. - if (type == QSocketNotifier::Read) { - Q_ASSERT(notifier == socketInfo->readNotifier); - socketInfo->readNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack); - } else if (type == QSocketNotifier::Write) { - Q_ASSERT(notifier == socketInfo->writeNotifier); - socketInfo->writeNotifier = 0; - CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack); - } - - // Remove CFSocket from runloop if this was the last QSocketNotifier. - if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) { - if (CFSocketIsValid(socketInfo->socket)) - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - delete socketInfo; - d->macSockets.remove(nativeSocket); - } + d->cfSocketNotifier.unregisterSocketNotifier(notifier); } bool QCocoaEventDispatcher::hasPendingEvents() @@ -940,11 +772,19 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate() { } +void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher) +{ + static_cast(eventDispatcher)->d_func()->maybeCancelWaitForMoreEvents(); +} + QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent) : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent) { Q_D(QCocoaEventDispatcher); + d->cfSocketNotifier.setHostEventDispatcher(this); + d->cfSocketNotifier.setMaybeCancelWaitForMoreEventsCallback(qt_mac_maybeCancelWaitForMoreEventsForwarder); + // keep our sources running when modal loops are running CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode); @@ -1127,17 +967,8 @@ QCocoaEventDispatcher::~QCocoaEventDispatcher() [nsevent release]; } - // Remove CFSockets from the runloop. - for (MacSocketHash::ConstIterator it = d->macSockets.constBegin(); it != d->macSockets.constEnd(); ++it) { - MacSocketInfo *socketInfo = (*it); - if (CFSocketIsValid(socketInfo->socket)) { - qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop); - CFRunLoopSourceInvalidate(socketInfo->runloop); - CFRelease(socketInfo->runloop); - CFSocketInvalidate(socketInfo->socket); - CFRelease(socketInfo->socket); - } - } + d->cfSocketNotifier.removeSocketNotifiers(); + CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes); CFRelease(d->postedEventsSource); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index 88d5127855..53a75618ce 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -78,6 +78,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE @@ -116,6 +117,8 @@ private: QTimerInfoList m_timerInfoList; CFRunLoopTimerRef m_runLoopTimerRef; + QCFSocketNotifier m_cfSocketNotifier; + void processPostedEvents(); void maybeStartCFRunLoopTimer(); void maybeStopCFRunLoopTimer(); diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index f6f60387d4..e9bf039047 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -155,6 +155,8 @@ QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent) , m_interrupted(false) , m_runLoopTimerRef(0) { + m_cfSocketNotifier.setHostEventDispatcher(this); + CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); CFRunLoopSourceContext context; bzero(&context, sizeof(CFRunLoopSourceContext)); @@ -184,6 +186,8 @@ QIOSEventDispatcher::~QIOSEventDispatcher() maybeStopCFRunLoopTimer(); CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes); CFRelease(m_blockingTimerRunLoopSource); + + m_cfSocketNotifier.removeSocketNotifiers(); } bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) @@ -215,14 +219,12 @@ bool QIOSEventDispatcher::hasPendingEvents() void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.registerSocketNotifier(notifier); } void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier) { - qDebug() << __FUNCTION__ << "not implemented"; - Q_UNUSED(notifier); + m_cfSocketNotifier.unregisterSocketNotifier(notifier); } void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj) -- cgit v1.2.3 From 76e4b6d2f24f7f88250db34fb03838a30fc43eec Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:41:12 +0100 Subject: iOS: Add QIOSIntegration::hasCapability function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the missing override, and report that we support OpenGL (and multiple windows). Change-Id: If95138cab9099b547d12d3dfed008bd63b6d2acf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.h | 2 ++ src/plugins/platforms/ios/qiosintegration.mm | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 054933ea44..329a0a3d9b 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -54,6 +54,8 @@ public: QIOSIntegration(); ~QIOSIntegration(); + bool hasCapability(Capability cap) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index c5fef243ce..adb33da344 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -84,6 +84,18 @@ QIOSIntegration::~QIOSIntegration() delete m_touchDevice; } +bool QIOSIntegration::hasCapability(Capability cap) const +{ + switch (cap) { + case OpenGL: + return true; + case MultipleWindows: + return true; + default: + return QPlatformIntegration::hasCapability(cap); + } +} + QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { qDebug() << __FUNCTION__ << "Creating platform window"; -- cgit v1.2.3 From 75a7dc7a574e0c949214feecc711e385f38060e9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 14:59:30 +0100 Subject: iOS: Remove debug output noise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This debug information is not needed anymore, and only causes noise when trying to debug other stuff. Change-Id: I076826e251b84a3883e63aa7669f6e1bb55a0d1f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index adb33da344..c7541c3e38 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -98,14 +98,12 @@ bool QIOSIntegration::hasCapability(Capability cap) const QPlatformWindow *QIOSIntegration::createPlatformWindow(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform window"; return new QIOSWindow(window); } // Used when the QWindow's surface type is set by the client to QSurface::RasterSurface QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *window) const { - qDebug() << __FUNCTION__ << "Creating platform backingstore"; return new QIOSBackingStore(window); } @@ -113,7 +111,6 @@ QPlatformBackingStore *QIOSIntegration::createPlatformBackingStore(QWindow *wind QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); - qDebug() << __FUNCTION__ << "Creating platform opengl context"; return new QIOSContext(context); } -- cgit v1.2.3 From 9b05f675e311d1962f0670193cf4df75a07f4999 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 21 Feb 2013 13:44:01 +0100 Subject: QFusionStyle: Fix crash on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First of all, the ifdef section was meant for osx, and not ios. Second, a platform theme does not necessarily need to override the palette function, which will return 0 by default. Change-Id: I5a28f4ee1020c9253d0803c9d962c6a058e5358c Reviewed-by: Tor Arne Vestbø Reviewed-by: J-P Nurmi Reviewed-by: Jens Bache-Wiig --- src/widgets/styles/qfusionstyle_p_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h index d3f2ff5f40..58595fe889 100644 --- a/src/widgets/styles/qfusionstyle_p_p.h +++ b/src/widgets/styles/qfusionstyle_p_p.h @@ -88,9 +88,9 @@ public: // On mac we want a standard blue color used when the system palette is used bool isMacSystemPalette(const QPalette &pal) const { Q_UNUSED(pal); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && !defined(Q_OS_IOS) const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); - if (themePalette->color(QPalette::Normal, QPalette::Highlight) == + if (themePalette && themePalette->color(QPalette::Normal, QPalette::Highlight) == pal.color(QPalette::Normal, QPalette::Highlight) && themePalette->color(QPalette::Normal, QPalette::HighlightedText) == pal.color(QPalette::Normal, QPalette::HighlightedText)) -- cgit v1.2.3