mirror of https://github.com/qt/qtbase.git
Merge "Merge branch 'ios' into dev" into refs/staging/dev
This commit is contained in:
commit
0520631b2b
|
@ -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
|
||||
|
@ -4026,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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,17 +3,23 @@
|
|||
#
|
||||
|
||||
MAKEFILE_GENERATOR = UNIX
|
||||
CONFIG += ios reduce_exports incremental global_init_link_order lib_version_first plugin_no_soname
|
||||
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 =
|
||||
|
||||
# But to iOS
|
||||
QMAKE_IOS_DEPLOYMENT_TARGET = 4.3
|
||||
|
||||
# Add iOS common folder to include path
|
||||
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
|
||||
|
||||
# Universal target (iPhone and iPad)
|
||||
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
#
|
||||
# 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 =
|
||||
|
||||
###########################################################################
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# Samsung S5PC100, Apple A4, A5, A5X
|
||||
equals(QMAKE_IOS_TARGET_ARCH, "armv7") {
|
||||
# iOS CPU architecture (armv7)
|
||||
QMAKE_IOS_ARM_ARCH = __ARM_ARCH_7__
|
||||
|
||||
# Thumb2 instructions
|
||||
QMAKE_IOS_ARM_FLAGS = -mthumb
|
||||
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
|
||||
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.")
|
||||
}
|
||||
}
|
||||
# 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 =
|
||||
}
|
|
@ -3,39 +3,32 @@
|
|||
#
|
||||
# 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
|
||||
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
|
||||
QMAKE_IOS_CXXFLAGS += -fvisibility-inlines-hidden
|
||||
QMAKE_IOS_OBJ_CFLAGS += -Wno-arc-abi
|
||||
|
||||
# Device or simulator specific flags
|
||||
*simulator* {
|
||||
QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks
|
||||
QMAKE_IOS_OBJ_CFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
|
||||
}
|
||||
# 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
|
||||
|
||||
# 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
|
||||
# But these only apply to non-ARM targets
|
||||
!contains(QT_ARCH, arm): QMAKE_IOS_CFLAGS += -fexceptions -fasm-blocks
|
||||
|
||||
# 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}")
|
||||
}
|
||||
}
|
||||
# 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
|
||||
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.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
|
||||
|
|
|
@ -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 =
|
|
@ -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 =
|
|
@ -3,63 +3,39 @@
|
|||
#
|
||||
# Depends on:
|
||||
#
|
||||
# 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
|
||||
|
||||
# iOS SDK device type
|
||||
!*simulator*: QMAKE_IOS_DEVICE_TYPE = iPhoneOS
|
||||
else {
|
||||
QMAKE_IOS_DEVICE_TYPE = iPhoneSimulator
|
||||
QT_QPA_DEFAULT_PLATFORM = ios
|
||||
|
||||
# Use simulator SDK version
|
||||
QMAKE_IOS_SDK_VERSION = $$QMAKE_IOS_SIMULATOR_SDK_VERSION
|
||||
QMAKE_IOS_SIMULATOR_SDK_VERSION =
|
||||
}
|
||||
QMAKE_XCODE_TOOLCHAIN_BIN_PATH = $$QMAKE_XCODE_DEVELOPER_PATH/Toolchains/XcodeDefault.xctoolchain/usr/bin
|
||||
|
||||
!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 =
|
||||
QMAKE_XCODE_CODE_SIGN_IDENTITY = "iPhone Developer"
|
||||
|
||||
# iOS platform /Developer path
|
||||
QMAKE_IOS_DEV_PATH = $$QMAKE_IOS_XCODE_PATH/Developer/Platforms/$${QMAKE_IOS_DEVICE_TYPE}.platform/Developer
|
||||
QMAKE_IOS_XCODE_PATH =
|
||||
# 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
|
||||
|
||||
# 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 =
|
||||
# Check that compiler is valid
|
||||
!exists($$QMAKE_CXX): error("The version of Xcode installed on this system does not include the clang compiler")
|
||||
|
||||
# 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
|
||||
QMAKE_INCDIR_OPENGL_ES2 =
|
||||
QMAKE_LIBDIR_OPENGL_ES2 =
|
||||
QMAKE_LIBS_OPENGL_ES2 = -framework OpenGLES
|
||||
|
||||
# No desktop OpenGL
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,184 +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 device SDK
|
||||
# QMAKE_IOS_SIMULATOR_SDK_VERSION - version number of iOS simulator SDK
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
#
|
||||
# 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
|
||||
# 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 for cross-compiling
|
||||
QMAKE_IOS_XCODE_VERSION =
|
||||
|
||||
# iOS SDK version used for cross-compiling for iOS devices
|
||||
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
|
||||
#
|
||||
|
||||
# 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
|
||||
|
||||
###########################################################################
|
||||
|
||||
# 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)
|
||||
|
||||
# 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.")
|
||||
}
|
||||
|
||||
# iOS 4.3 is the preferred version as it is the earliest version that is armv7/gles2 only
|
||||
QMAKE_IPHONEOS_PREFERRED_TARGET = 4.3
|
||||
|
||||
# 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): {
|
||||
# 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) {
|
||||
error("iOS $$QMAKE_IOS_SDK_VERSION SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.")
|
||||
}
|
||||
|
||||
# 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.")
|
||||
}
|
||||
# Building for iOS simulator
|
||||
} 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): {
|
||||
# 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) {
|
||||
error("iOS $$QMAKE_IOS_SIMULATOR_SDK_VERSION simulator SDK not found! Edit mkspecs/common/ios/versions.conf to specify version installed.")
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# 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.")
|
||||
}
|
||||
}
|
||||
|
||||
QMAKE_IPHONEOS_PREFERRED_TARGET =
|
||||
QMAKE_IOS_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 =
|
|
@ -42,8 +42,6 @@
|
|||
#ifndef QPLATFORMDEFS_H
|
||||
#define QPLATFORMDEFS_H
|
||||
|
||||
#define QT_QPA_DEFAULT_PLATFORM_NAME "cocoa"
|
||||
|
||||
// Get Qt defines/settings
|
||||
|
||||
#include "qglobal.h"
|
||||
|
|
|
@ -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.")
|
||||
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
!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
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
|
@ -0,0 +1,4 @@
|
|||
# Unset makefile generator, so we can auto-detect value in default_post
|
||||
unset(MAKEFILE_GENERATOR)
|
||||
|
||||
load(default_pre)
|
|
@ -37,7 +37,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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>@ICON@</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@EXECUTABLE@</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.@BUNDLEIDENTIFIER@</string>
|
||||
<key>NOTE</key>
|
||||
<string>This file was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
|
||||
<plist version="0.9">
|
||||
<dict>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@SHORT_VERSION@</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Created by Qt/QMake</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>@TYPEINFO@</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>@LIBRARY@</string>
|
||||
<key>NOTE</key>
|
||||
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -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)
|
|
@ -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)
|
|
@ -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.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_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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -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/qmake.conf)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -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)
|
|
@ -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"
|
|
@ -46,6 +46,7 @@
|
|||
#include <qregexp.h>
|
||||
#include <qcryptographichash.h>
|
||||
#include <qdebug.h>
|
||||
#include <qstring.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#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", "<absolute>") << ";" << "\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", "<group>") << ";" << "\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", "<Group>") << ";" << "\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<QString, QString> 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<QString, QString>::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", "<group>") << ";" << "\n"
|
||||
<< "\t\t" << "};" << "\n";
|
||||
|
||||
|
@ -451,18 +435,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
|
||||
|
@ -470,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))
|
||||
|
@ -483,10 +465,48 @@ 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)
|
||||
{
|
||||
// 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;
|
||||
|
||||
|
@ -508,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);
|
||||
|
@ -516,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());
|
||||
|
@ -523,15 +545,18 @@ 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";
|
||||
}
|
||||
|
||||
// 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<QString, ProStringList> groups;
|
||||
QList<ProjectBuilderSources> sources;
|
||||
|
@ -545,14 +570,13 @@ 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()))
|
||||
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) {
|
||||
|
@ -572,8 +596,15 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
}
|
||||
}
|
||||
sources.append(ProjectBuilderSources(inputs.at(input).toQString(), true,
|
||||
QString("Sources [") + name + "]", (*it).toQString(), isObj));
|
||||
QString(), (*it).toQString(), isObj));
|
||||
|
||||
if (isObj) {
|
||||
inputs.removeAt(input);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
++input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -618,30 +649,29 @@ 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"
|
||||
<< "\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 +680,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 +700,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", "<Group>") << ";" << "\n"
|
||||
<< "\t\t" << "};" << "\n";
|
||||
}
|
||||
|
@ -775,10 +803,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";
|
||||
|
@ -786,12 +813,13 @@ 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"
|
||||
<< "\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,24 +927,25 @@ 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("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";
|
||||
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);
|
||||
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);
|
||||
|
@ -955,10 +984,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";
|
||||
|
@ -967,42 +995,24 @@ 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"
|
||||
<< "\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", "<Group>") << ";" << "\n"
|
||||
<< "\t\t" << "};" << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
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"
|
||||
<< "\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("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";
|
||||
}
|
||||
|
@ -1024,78 +1034,96 @@ 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("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);
|
||||
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\t" << "settings = {\n"
|
||||
<< "\t\t\t" << "}" << ";" << "\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;
|
||||
}
|
||||
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"
|
||||
<< "\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("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\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"
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
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("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\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n"
|
||||
<< "\t\t" << "};" << "\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("path", ProStringList()) << ";" << "\n"
|
||||
<< "\t\t\t" << writeSettings("refType", "4", SettingsNoQuote) << ";" << "\n"
|
||||
<< "\t\t\t" << writeSettings("name", "Bundle Resources") << ";" << "\n"
|
||||
<< "\t\t\t" << writeSettings("sourceTree", "<Group>") << ";" << "\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", "<Group>") << ";" << "\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 +1138,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 +1172,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 +1181,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", "<Group>") << ";" << "\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", "<Group>") << ";" << "\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";
|
||||
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";
|
||||
else
|
||||
t << "\t\t\t" << writeSettings("productType", "com.apple.product-type.tool") << ";" << "\n";
|
||||
} else {
|
||||
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.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 << "<?xml version="
|
||||
<< "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n"
|
||||
<< "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/"
|
||||
<< "Library/DTDs/PropertyList.dtd\\\">" << "\n"
|
||||
<< "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n"
|
||||
<< "\t\t\t\t" << "<dict>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>English</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>" << var("ICON").section(Option::dir_sep, -1) << "</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>6.0</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>APPL</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>"
|
||||
<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") :
|
||||
project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << "</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<string>0.1</string>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n"
|
||||
<< "\t\t\t\t\t" << "<true/>" << "\n"
|
||||
<< "\t\t\t\t" << "</dict>" << "\n"
|
||||
<< "\t\t\t\t" << "</plist>";
|
||||
}
|
||||
t << "\";" << "\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 +1231,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", "<<ProjectDirectory>>") << ";" << "\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<QString, QString> settings;
|
||||
|
@ -1379,6 +1266,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 +1276,104 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
<< "\t\t\t" << "buildSettings = {" << "\n";
|
||||
for (QMap<QString, QString>::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());
|
||||
}
|
||||
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"));
|
||||
}
|
||||
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";
|
||||
|
||||
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()));
|
||||
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 +1424,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<QString, QString>::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 +1431,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"
|
||||
|
@ -1511,6 +1479,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
|||
writingUnixMakefileGenerator = false;
|
||||
}
|
||||
}
|
||||
|
||||
qmake_setpwd(input_dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1724,10 +1695,9 @@ ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where)
|
|||
|
||||
QString ProjectBuilderMakefileGenerator::sourceTreeForFile(const QString &where)
|
||||
{
|
||||
QString ret = "<absolute>";
|
||||
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("<absolute>");
|
||||
}
|
||||
|
||||
QString
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 <TargetConditionals.h>
|
||||
# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
# define Q_OS_IOS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -202,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
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include "qglobal.h"
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
|
|
@ -18,9 +18,7 @@ testcocoon {
|
|||
load(testcocoon)
|
||||
}
|
||||
|
||||
mac {
|
||||
LIBS_PRIVATE += -framework Cocoa
|
||||
}
|
||||
mac:!ios: LIBS_PRIVATE += -framework Cocoa
|
||||
|
||||
CONFIG += simd
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
mac {
|
||||
HEADERS += $$PWD/qcfsocketnotifier_p.h
|
||||
SOURCES += $$PWD/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 <QtGui/qguiapplication.h>
|
||||
#include <QtCore/qsocketnotifier.h>
|
||||
#include <QtCore/qthread.h>
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Socket Notifiers
|
||||
*************************************************************************/
|
||||
void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
|
||||
const void *, void *info)
|
||||
{
|
||||
|
||||
QCFSocketNotifier *cfSocketNotifier = static_cast<QCFSocketNotifier *>(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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <QtCore/qabstracteventdispatcher.h>
|
||||
#include <QtCore/qhash.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct MacSocketInfo {
|
||||
MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0) {}
|
||||
CFSocketRef socket;
|
||||
CFRunLoopSourceRef runloop;
|
||||
QObject *readNotifier;
|
||||
QObject *writeNotifier;
|
||||
};
|
||||
typedef QHash<int, MacSocketInfo *> 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
|
|
@ -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
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qglobal.h"
|
||||
|
||||
#ifndef Q_OS_IOS
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <IOKit/graphics/IOGraphicsLib.h>
|
||||
|
|
|
@ -2,13 +2,14 @@ TARGET = QtPlatformSupport
|
|||
QT = core-private gui-private
|
||||
|
||||
CONFIG += static internal_module
|
||||
mac:LIBS += -lz -framework CoreFoundation -framework Carbon
|
||||
mac:LIBS += -lz
|
||||
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#include <QtGui/qwindowdefs.h>
|
||||
#include <QtCore/private/qabstracteventdispatcher_p.h>
|
||||
#include <QtCore/private/qtimerinfo_unix_p.h>
|
||||
#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
|
@ -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<int, MacSocketInfo *> MacSocketHash;
|
||||
|
||||
class QCocoaEventDispatcherPrivate : public QAbstractEventDispatcherPrivate
|
||||
{
|
||||
|
@ -183,7 +177,7 @@ public:
|
|||
void maybeCancelWaitForMoreEvents();
|
||||
void ensureNSAppInitialized();
|
||||
|
||||
MacSocketHash macSockets;
|
||||
QCFSocketNotifier cfSocketNotifier;
|
||||
QList<void *> queuedUserInputEvents; // NSEvent *
|
||||
CFRunLoopSourceRef postedEventsSource;
|
||||
CFRunLoopObserverRef waitingObserver;
|
||||
|
|
|
@ -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<QCocoaEventDispatcherPrivate *>(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<QCocoaEventDispatcher *>(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);
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"Keys": [ "ios" ]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += plugin.pro qtmain.pro
|
|
@ -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 <qpa/qplatformintegrationplugin.h>
|
||||
#include <qpa/qplatformthemeplugin.h>
|
||||
#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)
|
|
@ -0,0 +1,36 @@
|
|||
TARGET = qios
|
||||
|
||||
PLUGIN_TYPE = platforms
|
||||
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 \
|
||||
qiosviewcontroller.mm \
|
||||
qioscontext.mm \
|
||||
qiosinputcontext.mm \
|
||||
qiostheme.mm \
|
||||
qiosglobal.mm
|
||||
|
||||
HEADERS = \
|
||||
qiosintegration.h \
|
||||
qioswindow.h \
|
||||
qiosscreen.h \
|
||||
qioseventdispatcher.h \
|
||||
qiosbackingstore.h \
|
||||
qiosapplicationdelegate.h \
|
||||
qiosviewcontroller.h \
|
||||
qioscontext.h \
|
||||
qiosinputcontext.h \
|
||||
qiostheme.h \
|
||||
qiosglobal.h
|
||||
|
||||
#HEADERS = qiossoftwareinputhandler.h
|
|
@ -3,7 +3,7 @@
|
|||
** 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.
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
|
@ -39,4 +39,15 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../common/ios/qplatformdefs.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <QtGui/QtGui>
|
||||
|
||||
@interface QIOSApplicationDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@end
|
||||
|
||||
@interface QIOSMainWrapperApplicationDelegate : QIOSApplicationDelegate
|
||||
@end
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qioswindow.h"
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
@implementation QIOSApplicationDelegate
|
||||
|
||||
@synthesize window;
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
Q_UNUSED(application)
|
||||
Q_UNUSED(launchOptions)
|
||||
|
||||
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:.
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[window release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 QIOSBACKINGSTORE_H
|
||||
#define QIOSBACKINGSTORE_H
|
||||
|
||||
#include <qpa/qplatformbackingstore.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
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:
|
||||
QOpenGLContext *m_context;
|
||||
QPaintDevice *m_device;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QIOSBACKINGSTORE_H
|
|
@ -0,0 +1,125 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qiosbackingstore.h"
|
||||
#include "qioswindow.h"
|
||||
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QOpenGLPaintDevice>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
QIOSBackingStore::QIOSBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
, m_context(new QOpenGLContext)
|
||||
, m_device(0)
|
||||
{
|
||||
m_context->setFormat(window->requestedFormat());
|
||||
m_context->setScreen(window->screen());
|
||||
m_context->create();
|
||||
}
|
||||
|
||||
QIOSBackingStore::~QIOSBackingStore()
|
||||
{
|
||||
delete m_context;
|
||||
delete m_device;
|
||||
}
|
||||
|
||||
void QIOSBackingStore::beginPaint(const QRegion &)
|
||||
{
|
||||
// Needed to prevent QOpenGLContext::makeCurrent() from failing
|
||||
window()->setSurfaceType(QSurface::OpenGLSurface);
|
||||
|
||||
m_context->makeCurrent(window());
|
||||
|
||||
static_cast<QOpenGLPaintDevice *>(paintDevice())->setSize(window()->size());
|
||||
QIOSWindow *iosWindow = static_cast<QIOSWindow *>(window()->handle());
|
||||
static_cast<QOpenGLPaintDevice *>(paintDevice())->setSize(window()->size() * iosWindow->devicePixelRatio());
|
||||
}
|
||||
|
||||
QPaintDevice *QIOSBackingStore::paintDevice()
|
||||
{
|
||||
if (!m_device) {
|
||||
QIOSWindow *iosWindow = static_cast<QIOSWindow *>(window()->handle());
|
||||
QOpenGLPaintDevice *openGLDevice = new QOpenGLPaintDevice(window()->size() * iosWindow->devicePixelRatio());
|
||||
openGLDevice->setDevicePixelRatio(iosWindow->devicePixelRatio());
|
||||
m_device = openGLDevice;
|
||||
}
|
||||
|
||||
return m_device;
|
||||
}
|
||||
|
||||
void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void QIOSBackingStore::endPaint()
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
Q_UNUSED(staticContents);
|
||||
|
||||
// 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
|
|
@ -0,0 +1,91 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <qpa/qplatformopenglcontext.h>
|
||||
|
||||
@class EAGLContext;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSContext : public QObject, public QPlatformOpenGLContext
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
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);
|
||||
|
||||
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<QWindow *, FramebufferObject> m_framebufferObjects;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QIOSCONTEXT_H
|
|
@ -0,0 +1,204 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <dlfcn.h>
|
||||
|
||||
#include <QtGui/QOpenGlContext>
|
||||
|
||||
#import <OpenGLES/EAGL.h>
|
||||
#import <QuartzCore/CAEAGLLayer.h>
|
||||
|
||||
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()
|
||||
{
|
||||
[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;
|
||||
}
|
||||
|
||||
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);
|
||||
Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
|
||||
QWindow *window = static_cast<QWindow *>(surface->surface());
|
||||
Q_ASSERT(m_framebufferObjects.contains(window));
|
||||
|
||||
[EAGLContext setCurrentContext:m_eaglContext];
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer);
|
||||
[m_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
|
||||
}
|
||||
|
||||
GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
|
||||
{
|
||||
Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window);
|
||||
QWindow *window = static_cast<QWindow *>(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<QIOSWindow *>(surface);
|
||||
if (framebufferObject.renderbufferWidth != platformWindow->effectiveWidth() ||
|
||||
framebufferObject.renderbufferHeight != platformWindow->effectiveHeight()) {
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
|
||||
UIView *view = reinterpret_cast<UIView *>(platformWindow->winId());
|
||||
CAEAGLLayer *layer = static_cast<CAEAGLLayer *>(view.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;
|
||||
}
|
||||
|
||||
void QIOSContext::windowDestroyed(QObject *object)
|
||||
{
|
||||
QWindow *window = static_cast<QWindow *>(object);
|
||||
if (m_framebufferObjects.contains(window)) {
|
||||
deleteBuffers(m_framebufferObjects[window]);
|
||||
m_framebufferObjects.remove(window);
|
||||
}
|
||||
}
|
||||
|
||||
QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName)
|
||||
{
|
||||
return reinterpret_cast<QFunctionPointer>(dlsym(RTLD_NEXT, functionName.constData()));
|
||||
}
|
||||
|
||||
#include "moc_qioscontext.cpp"
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QtCore/qabstracteventdispatcher.h>
|
||||
#include <QtCore/private/qtimerinfo_unix_p.h>
|
||||
#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
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<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject *object) const;
|
||||
|
||||
int remainingTime(int timerId);
|
||||
|
||||
void wakeUp();
|
||||
void interrupt();
|
||||
void flush();
|
||||
|
||||
private:
|
||||
bool m_interrupted;
|
||||
|
||||
CFRunLoopSourceRef m_postedEventsRunLoopSource;
|
||||
CFRunLoopSourceRef m_blockingTimerRunLoopSource;
|
||||
|
||||
QTimerInfoList m_timerInfoList;
|
||||
CFRunLoopTimerRef m_runLoopTimerRef;
|
||||
|
||||
QCFSocketNotifier m_cfSocketNotifier;
|
||||
|
||||
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
|
||||
|
||||
#endif // QEVENTDISPATCHER_IOS_P_H
|
|
@ -0,0 +1,322 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qioseventdispatcher.h"
|
||||
#import "qiosapplicationdelegate.h"
|
||||
#include <qdebug.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/private/qcoreapplication_p.h>
|
||||
#include <UIKit/UIApplication.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2)
|
||||
{
|
||||
return info1 == info2;
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::postedEventsRunLoopCallback(void *info)
|
||||
{
|
||||
QIOSEventDispatcher *self = static_cast<QIOSEventDispatcher *>(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<QIOSEventDispatcher *>(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<QIOSEventDispatcher *>(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()
|
||||
{
|
||||
QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
|
||||
}
|
||||
|
||||
QIOSEventDispatcher::QIOSEventDispatcher(QObject *parent)
|
||||
: QAbstractEventDispatcher(parent)
|
||||
, m_interrupted(false)
|
||||
, m_runLoopTimerRef(0)
|
||||
{
|
||||
m_cfSocketNotifier.setHostEventDispatcher(this);
|
||||
|
||||
CFRunLoopRef mainRunLoop = CFRunLoopGetMain();
|
||||
CFRunLoopSourceContext context;
|
||||
bzero(&context, sizeof(CFRunLoopSourceContext));
|
||||
context.equal = runLoopSourceEqualCallback;
|
||||
context.info = this;
|
||||
|
||||
// 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_postedEventsRunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(m_postedEventsRunLoopSource);
|
||||
|
||||
qDeleteAll(m_timerInfoList);
|
||||
maybeStopCFRunLoopTimer();
|
||||
CFRunLoopRemoveSource(CFRunLoopGetMain(), m_blockingTimerRunLoopSource, kCFRunLoopCommonModes);
|
||||
CFRelease(m_blockingTimerRunLoopSource);
|
||||
|
||||
m_cfSocketNotifier.removeSocketNotifiers();
|
||||
}
|
||||
|
||||
bool QIOSEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
{
|
||||
m_interrupted = false;
|
||||
bool eventsProcessed = false;
|
||||
|
||||
bool excludeUserEvents = flags & QEventLoop::ExcludeUserInputEvents;
|
||||
bool execFlagSet = (flags & QEventLoop::DialogExec) || (flags & QEventLoop::EventLoopExec);
|
||||
bool useExecMode = execFlagSet && !excludeUserEvents;
|
||||
|
||||
if (useExecMode) {
|
||||
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
|
||||
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]] && !m_interrupted);
|
||||
eventsProcessed = true;
|
||||
} else {
|
||||
if (!(flags & QEventLoop::WaitForMoreEvents))
|
||||
wakeUp();
|
||||
eventsProcessed = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
|
||||
}
|
||||
return eventsProcessed;
|
||||
}
|
||||
|
||||
bool QIOSEventDispatcher::hasPendingEvents()
|
||||
{
|
||||
qDebug() << __FUNCTION__ << "not implemented";
|
||||
return false;
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
|
||||
{
|
||||
m_cfSocketNotifier.registerSocketNotifier(notifier);
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
|
||||
{
|
||||
m_cfSocketNotifier.unregisterSocketNotifier(notifier);
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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<QAbstractEventDispatcher::TimerInfo> QIOSEventDispatcher::registeredTimers(QObject *object) const
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
if (!object) {
|
||||
qWarning("QIOSEventDispatcher:registeredTimers: invalid argument");
|
||||
return QList<TimerInfo>();
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_timerInfoList.registeredTimers(object);
|
||||
}
|
||||
|
||||
int QIOSEventDispatcher::remainingTime(int timerId)
|
||||
{
|
||||
#ifndef QT_NO_DEBUG
|
||||
if (timerId < 1) {
|
||||
qWarning("QIOSEventDispatcher::remainingTime: invalid argument");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_timerInfoList.timerRemainingTime(timerId);
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::wakeUp()
|
||||
{
|
||||
CFRunLoopSourceSignal(m_postedEventsRunLoopSource);
|
||||
CFRunLoopWakeUp(CFRunLoopGetMain());
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::interrupt()
|
||||
{
|
||||
wakeUp();
|
||||
m_interrupted = true;
|
||||
}
|
||||
|
||||
void QIOSEventDispatcher::flush()
|
||||
{
|
||||
// X11 only.
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <UIKit/UIKit.h>
|
||||
#include <QtCore/QtCore>
|
||||
|
||||
@class QIOSViewController;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlatformScreen;
|
||||
|
||||
bool isQtApplication();
|
||||
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, QPlatformScreen *screen);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QIOSGLOBAL_H
|
|
@ -0,0 +1,144 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qiosapplicationdelegate.h"
|
||||
#include "qiosviewcontroller.h"
|
||||
#include "qiosscreen.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QIOSViewController *rootViewController()
|
||||
{
|
||||
static QIOSViewController *c = isQtApplication() ?
|
||||
static_cast<QIOSViewController *>([UIApplication sharedApplication].delegate.window.rootViewController) : nil;
|
||||
return c;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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<Qt::ScreenOrientation>(-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;
|
||||
}
|
||||
|
||||
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 = screen->geometry();
|
||||
return geometry.width() < geometry.height() ? rect
|
||||
: QRect(rect.y(), geometry.width() - rect.width() - rect.x(), rect.height(), rect.width());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
** 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.
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
|
@ -39,4 +39,35 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../common/ios/qplatformdefs.h"
|
||||
#ifndef QIOSINPUTCONTEXT_H
|
||||
#define QIOSINPUTCONTEXT_H
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include <qpa/qplatforminputcontext.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@class QIOSKeyboardListener;
|
||||
|
||||
class QIOSInputContext : public QPlatformInputContext
|
||||
{
|
||||
public:
|
||||
QIOSInputContext();
|
||||
~QIOSInputContext();
|
||||
|
||||
QRectF keyboardRect() const;
|
||||
void showInputPanel();
|
||||
void hideInputPanel();
|
||||
bool isInputPanelVisible() const;
|
||||
|
||||
void focusViewChanged(UIView *view);
|
||||
|
||||
private:
|
||||
QIOSKeyboardListener *m_keyboardListener;
|
||||
UIView *m_focusView;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qiosinputcontext.h"
|
||||
#include "qioswindow.h"
|
||||
#include <QGuiApplication>
|
||||
|
||||
@interface QIOSKeyboardListener : NSObject {
|
||||
@public
|
||||
QIOSInputContext *m_context;
|
||||
BOOL m_keyboardVisible;
|
||||
QRectF m_keyboardRect;
|
||||
}
|
||||
@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];
|
||||
|
||||
m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle());
|
||||
m_context->emitKeyboardRectChanged();
|
||||
|
||||
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])
|
||||
, m_focusView(0)
|
||||
{
|
||||
}
|
||||
|
||||
QIOSInputContext::~QIOSInputContext()
|
||||
{
|
||||
[m_keyboardListener release];
|
||||
[m_focusView release];
|
||||
}
|
||||
|
||||
QRectF QIOSInputContext::keyboardRect() const
|
||||
{
|
||||
return m_keyboardListener->m_keyboardRect;
|
||||
}
|
||||
|
||||
void QIOSInputContext::showInputPanel()
|
||||
{
|
||||
// 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 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()
|
||||
{
|
||||
[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];
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 QPLATFORMINTEGRATION_UIKIT_H
|
||||
#define QPLATFORMINTEGRATION_UIKIT_H
|
||||
|
||||
#include <qpa/qplatformintegration.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
|
||||
{
|
||||
public:
|
||||
QIOSIntegration();
|
||||
~QIOSIntegration();
|
||||
|
||||
bool hasCapability(Capability cap) const;
|
||||
|
||||
QPlatformWindow *createPlatformWindow(QWindow *window) const;
|
||||
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
|
||||
|
||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
|
||||
|
||||
QPlatformFontDatabase *fontDatabase() const;
|
||||
QPlatformInputContext *inputContext() const;
|
||||
|
||||
QVariant styleHint(StyleHint hint) const;
|
||||
|
||||
QStringList themeNames() const;
|
||||
QPlatformTheme *createPlatformTheme(const QString &name) const;
|
||||
|
||||
QAbstractEventDispatcher *guiThreadEventDispatcher() const;
|
||||
QPlatformNativeInterface *nativeInterface() const;
|
||||
|
||||
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
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qiosintegration.h"
|
||||
#include "qioswindow.h"
|
||||
#include "qiosbackingstore.h"
|
||||
#include "qiosscreen.h"
|
||||
#include "qioseventdispatcher.h"
|
||||
#include "qioscontext.h"
|
||||
#include "qiosinputcontext.h"
|
||||
#include "qiostheme.h"
|
||||
|
||||
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QIOSIntegration::QIOSIntegration()
|
||||
: m_fontDatabase(new QCoreTextFontDatabase)
|
||||
, m_inputContext(new QIOSInputContext)
|
||||
, 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
return new QIOSContext(context);
|
||||
}
|
||||
|
||||
QAbstractEventDispatcher *QIOSIntegration::guiThreadEventDispatcher() const
|
||||
{
|
||||
return new QIOSEventDispatcher();
|
||||
}
|
||||
|
||||
QPlatformFontDatabase * QIOSIntegration::fontDatabase() const
|
||||
{
|
||||
return m_fontDatabase;
|
||||
}
|
||||
|
||||
QPlatformInputContext *QIOSIntegration::inputContext() const
|
||||
{
|
||||
return m_inputContext;
|
||||
}
|
||||
|
||||
QVariant QIOSIntegration::styleHint(StyleHint hint) const
|
||||
{
|
||||
switch (hint) {
|
||||
case ShowIsFullScreen:
|
||||
return true;
|
||||
default:
|
||||
return QPlatformIntegration::styleHint(hint);
|
||||
}
|
||||
}
|
||||
|
||||
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<QIOSIntegration *>(this);
|
||||
}
|
||||
|
||||
void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
|
||||
{
|
||||
if (!window || !window->handle())
|
||||
return 0;
|
||||
|
||||
QByteArray lowerCaseResource = resource.toLower();
|
||||
|
||||
QIOSWindow *platformWindow = static_cast<QIOSWindow *>(window->handle());
|
||||
|
||||
if (lowerCaseResource == "uiview")
|
||||
return reinterpret_cast<void *>(platformWindow->winId());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QTouchDevice *QIOSIntegration::touchDevice()
|
||||
{
|
||||
return m_touchDevice;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,88 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 QIOSSCREEN_H
|
||||
#define QIOSSCREEN_H
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include <qpa/qplatformscreen.h>
|
||||
|
||||
@class QIOSOrientationListener;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
QIOSScreen(unsigned int screenIndex);
|
||||
~QIOSScreen();
|
||||
|
||||
enum ScreenIndex { MainScreen = 0 };
|
||||
|
||||
QRect geometry() const;
|
||||
QRect availableGeometry() const;
|
||||
int depth() const;
|
||||
QImage::Format format() const;
|
||||
QSizeF physicalSize() const;
|
||||
QDpi logicalDpi() const;
|
||||
qreal devicePixelRatio() const;
|
||||
|
||||
Qt::ScreenOrientation nativeOrientation() const;
|
||||
Qt::ScreenOrientation orientation() const;
|
||||
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,238 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qiosscreen.h"
|
||||
#include "qioswindow.h"
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include "qiosapplicationdelegate.h"
|
||||
#include "qiosviewcontroller.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
@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
|
||||
|
||||
/*!
|
||||
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)])
|
||||
, m_orientationListener(0)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
QString deviceIdentifier = deviceModelIdentifier();
|
||||
|
||||
if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */
|
||||
|| deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) {
|
||||
m_depth = 18;
|
||||
} else {
|
||||
m_depth = 24;
|
||||
}
|
||||
|
||||
int unscaledDpi = 163; // Regular iPhone DPI
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
|
||||
&& deviceIdentifier != QStringLiteral("iPad2,5") /* iPad Mini */) {
|
||||
unscaledDpi = 132;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
if (isQtApplication()) {
|
||||
// When in a non-mixed environment, let QScreen follow the current interface orientation:
|
||||
setPrimaryOrientation(toQtScreenOrientation(rootViewController().interfaceOrientation));
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
QIOSScreen::~QIOSScreen()
|
||||
{
|
||||
[m_orientationListener release];
|
||||
}
|
||||
|
||||
QRect QIOSScreen::geometry() const
|
||||
{
|
||||
return m_geometry;
|
||||
}
|
||||
|
||||
QRect QIOSScreen::availableGeometry() const
|
||||
{
|
||||
return m_availableGeometry;
|
||||
}
|
||||
|
||||
int QIOSScreen::depth() const
|
||||
{
|
||||
return m_depth;
|
||||
}
|
||||
|
||||
QImage::Format QIOSScreen::format() const
|
||||
{
|
||||
return QImage::Format_ARGB32_Premultiplied;
|
||||
}
|
||||
|
||||
QSizeF QIOSScreen::physicalSize() const
|
||||
{
|
||||
return m_physicalSize;
|
||||
}
|
||||
|
||||
QDpi QIOSScreen::logicalDpi() const
|
||||
{
|
||||
return QDpi(72, 72);
|
||||
}
|
||||
|
||||
qreal QIOSScreen::devicePixelRatio() const
|
||||
{
|
||||
return [m_uiScreen scale];
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
|
||||
{
|
||||
return Qt::PortraitOrientation;
|
||||
}
|
||||
|
||||
Qt::ScreenOrientation QIOSScreen::orientation() const
|
||||
{
|
||||
return toQtScreenOrientation([UIDevice currentDevice].orientation);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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):
|
||||
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), this);
|
||||
|
||||
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry);
|
||||
}
|
||||
|
||||
UIScreen *QIOSScreen::uiScreen() const
|
||||
{
|
||||
return m_uiScreen;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 QIOSSOFTWAREINPUTHANDLER_H
|
||||
#define QIOSSOFTWAREINPUTHANDLER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSSoftwareInputHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {}
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
private slots:
|
||||
void activeFocusChanged(bool focus);
|
||||
|
||||
private:
|
||||
bool closeSoftwareInputPanel(QWidget *widget);
|
||||
|
||||
QPointer<QWidget> m_currentFocusWidget;
|
||||
QPointer<QObject> m_currentFocusObject;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -3,7 +3,7 @@
|
|||
** 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.
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
|
@ -39,4 +39,26 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../common/ios/qplatformdefs.h"
|
||||
#ifndef QIOSTHEME_H
|
||||
#define QIOSTHEME_H
|
||||
|
||||
#include <qpa/qplatformtheme.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSTheme : public QPlatformTheme
|
||||
{
|
||||
public:
|
||||
QIOSTheme();
|
||||
~QIOSTheme();
|
||||
|
||||
QVariant themeHint(ThemeHint hint) const;
|
||||
|
||||
const QFont *font(Font type = SystemFont) const;
|
||||
|
||||
static const char *name;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,96 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include <QtGui/QFont>
|
||||
|
||||
#include <UIKit/UIFont.h>
|
||||
#include <UIKit/UIInterface.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
const QFont *QIOSTheme::font(Font type) const
|
||||
{
|
||||
static QHash<QPlatformTheme::Font, QFont *> 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
|
|
@ -3,7 +3,7 @@
|
|||
** 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.
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
|
@ -39,5 +39,8 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <OpenGLES/ES1/gl.h>
|
||||
#include <OpenGLES/ES1/glext.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface QIOSViewController : UIViewController
|
||||
@end
|
||||
|
|
@ -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 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"
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include "qiosscreen.h"
|
||||
#include "qiosglobal.h"
|
||||
|
||||
@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
|
||||
// updates it means it would like to enable auto-rotation, and vice versa.
|
||||
if (QGuiApplication *guiApp = qobject_cast<QGuiApplication *>(qApp))
|
||||
return !guiApp->primaryScreen()->orientationUpdateMask();
|
||||
else
|
||||
return YES; // Startup case: QGuiApplication is not ready yet.
|
||||
|
||||
// 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.
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
|
||||
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
|
||||
{
|
||||
Q_UNUSED(duration);
|
||||
Qt::ScreenOrientation orientation = toQtScreenOrientation(toInterfaceOrientation);
|
||||
if (orientation == -1)
|
||||
return;
|
||||
|
||||
QIOSScreen *qiosScreen = static_cast<QIOSScreen *>(QGuiApplication::primaryScreen()->handle());
|
||||
qiosScreen->setPrimaryOrientation(orientation);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 QIOSWINDOW_H
|
||||
#define QIOSWINDOW_H
|
||||
|
||||
#include <qpa/qplatformwindow.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
class QIOSContext;
|
||||
class QIOSWindow;
|
||||
|
||||
@interface UIView (QIOS)
|
||||
@property(readonly) QWindow *qwindow;
|
||||
@end
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIOSWindow : public QPlatformWindow
|
||||
{
|
||||
public:
|
||||
explicit QIOSWindow(QWindow *window);
|
||||
~QIOSWindow();
|
||||
|
||||
void setGeometry(const QRect &rect);
|
||||
|
||||
void setWindowState(Qt::WindowState state);
|
||||
void setParent(const QPlatformWindow *window);
|
||||
void handleContentOrientationChange(Qt::ScreenOrientation orientation);
|
||||
void setVisible(bool visible);
|
||||
|
||||
void raise() { raiseOrLower(true); }
|
||||
void lower() { raiseOrLower(false); }
|
||||
void requestActivateWindow();
|
||||
|
||||
qreal devicePixelRatio() const;
|
||||
int effectiveWidth() const;
|
||||
int effectiveHeight() const;
|
||||
|
||||
WId winId() const { return WId(m_view); };
|
||||
|
||||
QList<QWindowSystemInterface::TouchPoint> &touchPoints() { return m_touchPoints; }
|
||||
QHash<UITouch *, int> &activeTouches() { return m_activeTouches; }
|
||||
int &touchId() { return m_touchId; }
|
||||
|
||||
private:
|
||||
UIView *m_view;
|
||||
QList<QWindowSystemInterface::TouchPoint> m_touchPoints;
|
||||
QHash<UITouch *, int> m_activeTouches;
|
||||
int m_touchId;
|
||||
|
||||
QRect m_requestedGeometry;
|
||||
int m_windowLevel;
|
||||
qreal m_devicePixelRatio;
|
||||
|
||||
void raiseOrLower(bool raise);
|
||||
void updateWindowLevel();
|
||||
bool blockedByModal();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QIOSWINDOW_H
|
|
@ -0,0 +1,523 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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 "qioswindow.h"
|
||||
#include "qioscontext.h"
|
||||
#include "qiosinputcontext.h"
|
||||
#include "qiosscreen.h"
|
||||
#include "qiosapplicationdelegate.h"
|
||||
#include "qiosviewcontroller.h"
|
||||
#include "qiosintegration.h"
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformintegration.h>
|
||||
|
||||
#import <QuartzCore/CAEAGLLayer.h>
|
||||
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
@interface EAGLView : UIView <UIKeyInput>
|
||||
{
|
||||
@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
|
||||
{
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
-(id)initWithQIOSWindow:(QIOSWindow *)window
|
||||
{
|
||||
if (self = [self initWithFrame:toCGRect(window->geometry())])
|
||||
m_qioswindow = window;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
// Set up EAGL layer
|
||||
CAEAGLLayer *eaglLayer = static_cast<CAEAGLLayer *>(self.layer);
|
||||
eaglLayer.opaque = TRUE;
|
||||
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
|
||||
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
|
||||
|
||||
// Set up text input
|
||||
autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
enablesReturnKeyAutomatically = NO;
|
||||
keyboardAppearance = UIKeyboardAppearanceDefault;
|
||||
keyboardType = UIKeyboardTypeDefault;
|
||||
returnKeyType = UIReturnKeyDone;
|
||||
secureTextEntry = NO;
|
||||
|
||||
if (isQtApplication())
|
||||
self.hidden = YES;
|
||||
|
||||
self.multipleTouchEnabled = YES;
|
||||
}
|
||||
|
||||
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))
|
||||
qWarning() << m_qioswindow->window()
|
||||
<< "is backed by a UIView that has a transform set. This is not supported.";
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
{
|
||||
QList<QWindowSystemInterface::TouchPoint> &touchPoints = m_qioswindow->touchPoints();
|
||||
QHash<UITouch *, int> &activeTouches = m_qioswindow->activeTouches();
|
||||
|
||||
// Mark all touch points as stationary
|
||||
for (QList<QWindowSystemInterface::TouchPoint>::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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) sendTouchEventWithTimestamp:(ulong)timeStamp
|
||||
{
|
||||
// Send touch event synchronously
|
||||
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
QWindowSystemInterface::handleTouchEvent(m_qioswindow->window(), timeStamp,
|
||||
iosIntegration->touchDevice(), m_qioswindow->touchPoints());
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
QWindow *window = m_qioswindow->window();
|
||||
|
||||
// Transfer focus to the touched window:
|
||||
if (window != QGuiApplication::focusWindow())
|
||||
m_qioswindow->requestActivateWindow();
|
||||
|
||||
// Track Cocoa touch id to Qt touch id. The UITouch pointer is constant
|
||||
// for the touch duration.
|
||||
QHash<UITouch *, int> &activeTouches = m_qioswindow->activeTouches();
|
||||
QList<QWindowSystemInterface::TouchPoint> &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 updateTouchList:touches withState:Qt::TouchPointMoved];
|
||||
[self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)];
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
[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<UITouch *, int> &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
|
||||
{
|
||||
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<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
|
||||
QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(event.timestamp * 1000), iosIntegration->touchDevice());
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@implementation UIView (QIOS)
|
||||
|
||||
- (QWindow *)qwindow
|
||||
{
|
||||
if ([self isKindOfClass:[EAGLView class]])
|
||||
return static_cast<EAGLView *>(self)->m_qioswindow->window();
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QIOSWindow::QIOSWindow(QWindow *window)
|
||||
: QPlatformWindow(window)
|
||||
, m_view([[EAGLView alloc] initWithQIOSWindow:this])
|
||||
, m_touchId(0)
|
||||
, m_requestedGeometry(QPlatformWindow::geometry())
|
||||
, m_windowLevel(0)
|
||||
, m_devicePixelRatio(1.0)
|
||||
{
|
||||
setParent(parent());
|
||||
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()
|
||||
{
|
||||
[m_view removeFromSuperview];
|
||||
[m_view release];
|
||||
}
|
||||
|
||||
bool QIOSWindow::blockedByModal()
|
||||
{
|
||||
QWindow *modalWindow = QGuiApplication::modalWindow();
|
||||
return modalWindow && modalWindow != window();
|
||||
}
|
||||
|
||||
void QIOSWindow::setVisible(bool visible)
|
||||
{
|
||||
QPlatformWindow::setVisible(visible);
|
||||
m_view.hidden = !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)
|
||||
updateWindowLevel();
|
||||
|
||||
if (blockedByModal()) {
|
||||
if (visible)
|
||||
raise();
|
||||
return;
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
requestActivateWindow();
|
||||
} else {
|
||||
// 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) {
|
||||
static_cast<QIOSWindow *>(window->handle())->requestActivateWindow();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
m_requestedGeometry = 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);
|
||||
}
|
||||
|
||||
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: {
|
||||
// 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; }
|
||||
default:
|
||||
m_view.frame = toCGRect(m_requestedGeometry);
|
||||
m_view.autoresizingMask = UIViewAutoresizingNone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
|
||||
{
|
||||
if (parentWindow) {
|
||||
UIView *parentView = reinterpret_cast<UIView *>(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
|
||||
// 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<QIOSInputContext *>(context)->focusViewChanged(m_view);
|
||||
QPlatformWindow::requestActivateWindow();
|
||||
}
|
||||
|
||||
void QIOSWindow::raiseOrLower(bool raise)
|
||||
{
|
||||
// Re-insert m_view at the correct index among its sibling views
|
||||
// (QWindows) according to their current m_windowLevel:
|
||||
if (!isQtApplication())
|
||||
return;
|
||||
|
||||
NSArray *subviews = m_view.superview.subviews;
|
||||
if (subviews.count == 1)
|
||||
return;
|
||||
|
||||
for (int i = int(subviews.count) - 1; i >= 0; --i) {
|
||||
UIView *view = static_cast<UIView *>([subviews objectAtIndex:i]);
|
||||
if (view.hidden || view == m_view)
|
||||
continue;
|
||||
int level = static_cast<QIOSWindow *>(view.qwindow->handle())->m_windowLevel;
|
||||
if (m_windowLevel > level || (raise && m_windowLevel == level)) {
|
||||
[m_view.superview insertSubview:m_view aboveSubview:view];
|
||||
return;
|
||||
}
|
||||
}
|
||||
[m_view.superview insertSubview:m_view atIndex:0];
|
||||
}
|
||||
|
||||
void QIOSWindow::updateWindowLevel()
|
||||
{
|
||||
Qt::WindowType type = static_cast<Qt::WindowType>(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<QIOSWindow *>(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
|
||||
// that the task bar (and associated gestures) are aligned correctly:
|
||||
UIDeviceOrientation uiOrientation = fromQtScreenOrientation(orientation);
|
||||
[[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO];
|
||||
}
|
||||
|
||||
qreal QIOSWindow::devicePixelRatio() const
|
||||
{
|
||||
return m_devicePixelRatio;
|
||||
}
|
||||
|
||||
int QIOSWindow::effectiveWidth() const
|
||||
{
|
||||
return geometry().width() * m_devicePixelRatio;
|
||||
}
|
||||
|
||||
int QIOSWindow::effectiveHeight() const
|
||||
{
|
||||
return geometry().height() * m_devicePixelRatio;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,93 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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"
|
||||
#include "qiosviewcontroller.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
|
||||
{
|
||||
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
|
||||
self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease];
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
self.window.backgroundColor = [UIColor cyanColor];
|
||||
#endif
|
||||
|
||||
[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<char *>(malloc([arg lengthOfBytesUsingEncoding:[NSString defaultCStringEncoding]]));
|
||||
strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
}
|
||||
|
||||
qt_main(argc, argv);
|
||||
delete[] argv;
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,8 @@
|
|||
TARGET = qiosmain
|
||||
|
||||
PLUGIN_TYPE = platforms
|
||||
load(qt_plugin)
|
||||
|
||||
QT += gui-private
|
||||
|
||||
OBJECTIVE_SOURCES = qtmain.mm
|
|
@ -6,7 +6,10 @@ contains(QT_CONFIG, xcb) {
|
|||
SUBDIRS += xcb
|
||||
}
|
||||
|
||||
mac:!ios: SUBDIRS += cocoa
|
||||
mac {
|
||||
ios: SUBDIRS += ios
|
||||
else: SUBDIRS += cocoa
|
||||
}
|
||||
|
||||
win32: SUBDIRS += windows
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#if defined(Q_OS_MAC) && !defined(Q_OS_IOS)
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
!x11::mac {
|
||||
!x11:mac:!ios {
|
||||
LIBS_PRIVATE += -framework Carbon -framework Cocoa -lz
|
||||
*-mwerks:INCLUDEPATH += compat
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue