diff --git a/build/xcode/dist/autogen.sh b/build/xcode/dist/autogen.sh index d73d28f9..bda27806 100755 --- a/build/xcode/dist/autogen.sh +++ b/build/xcode/dist/autogen.sh @@ -35,20 +35,45 @@ XCODE_C_ROOT_DIR="$ROOT_DIR/CSFML/xcode" XCODE_CXX_ROOT_DIR="$ROOT_DIR/build/xcode" XCODE_SAMPLES_ROOT_DIR="$ROOT_DIR/samples/build/xcode" XCODE_FRAMEWORKS_PROJECT="SFML.xcodeproj" +XCODE_64B_FRAMEWORKS_PROJECT="SFML with Intel 64 bits.xcodeproj" XCODE_LIBRARIES_PROJECT="SFML-bare.xcodeproj" XCODE_SAMPLES_PROJECT="samples.xcodeproj" +XCODE_64B_SAMPLES_PROJECT="samples with Intel 64 bits.xcodeproj" XCODE_BUILD_STYLE="Release" XCODE_C_TARGETS=("SFML" "csfml-system" "csfml-network" "csfml-audio" "csfml-window" "csfml-graphics") XCODE_CXX_TARGETS=("SFML" "sfml-system" "sfml-network" "sfml-audio" "sfml-window" "sfml-graphics") -C_FRAMEWORKS_DIR="$ROOT_DIR/CSFML/lib" -CXX_FRAMEWORKS_DIR="$ROOT_DIR/lib" -CXX_SAMPLES_DIR="$ROOT_DIR/samples/bin" -PACKAGES_ROOT_DIR="$ROOT_DIR/dist" -CXX_SDK_PACKAGE="SFML-$SFML_VERSION-sdk-$OS" -CXX_DEV_PACKAGE="SFML-$SFML_VERSION-dev-$OS" -C_SDK_PACKAGE="SFML-$SFML_VERSION-c-sdk-$OS" -C_DEV_PACKAGE="SFML-$SFML_VERSION-c-dev-$OS" + +# Architectures +ARCH_32B="ub32" # ppc + i386 +ARCH_3264B="ub32+64" # ppc + i386 + x86_64 +ARCH_64B="$ARCH_3264B" # same as 3264B for now + +C_FRAMEWORKS_DIR="$ROOT_DIR/CSFML/lib" # target directory for C frameworks +CXX_FRAMEWORKS_DIR="$ROOT_DIR/lib" # target directory for C++ frameworks +CXX_32B_FRAMEWORKS_DIR="$CXX_FRAMEWORKS_DIR" # target directory for '32b' C++ frameworks +CXX_64B_FRAMEWORKS_DIR="$ROOT_DIR/lib/$ARCH_3264B" # target directory for '3264b' C++ frameworks +CXX_SAMPLES_DIR="$ROOT_DIR/samples/bin" # target directory for C++ samples +PACKAGES_ROOT_DIR="$ROOT_DIR/dist" # target directory for '32b' packages +PACKAGES_ROOT_DIR_64B="$PACKAGES_ROOT_DIR/$ARCH_64B" # target directory for '64b' packages + +# Packages names (default, 32 bits, 64 bits) +CXX_SDK_PACKAGE="SFML-$SFML_VERSION-sdk-$OS-$ARCH_32B" +CXX_DEV_PACKAGE="SFML-$SFML_VERSION-dev-$OS-$ARCH_32B" +C_SDK_PACKAGE="SFML-$SFML_VERSION-c-sdk-$OS-$ARCH_32B" +C_DEV_PACKAGE="SFML-$SFML_VERSION-c-dev-$OS-$ARCH_32B" + +CXX_SDK_PACKAGE_32B="$CXX_SDK_PACKAGE" +CXX_DEV_PACKAGE_32B="$CXX_DEV_PACKAGE" +C_SDK_PACKAGE_32B="$C_SDK_PACKAGE" +C_DEV_PACKAGE_32B="$C_DEV_PACKAGE" + +CXX_SDK_PACKAGE_64B="SFML-$SFML_VERSION-sdk-$OS-$ARCH_64B" +CXX_DEV_PACKAGE_64B="SFML-$SFML_VERSION-dev-$OS-$ARCH_64B" +C_SDK_PACKAGE_64B="SFML-$SFML_VERSION-c-sdk-$OS-$ARCH_64B" +C_DEV_PACKAGE_64B="SFML-$SFML_VERSION-c-dev-$OS-$ARCH_64B" + +# Package directories CXX_SDK_PACKAGE_DIR="$PACKAGES_ROOT_DIR/$CXX_SDK_PACKAGE" CXX_DEV_PACKAGE_DIR="$PACKAGES_ROOT_DIR/$CXX_DEV_PACKAGE" C_SDK_PACKAGE_DIR="$PACKAGES_ROOT_DIR/$C_SDK_PACKAGE" @@ -57,6 +82,11 @@ C_DEV_PACKAGE_DIR="$PACKAGES_ROOT_DIR/$C_DEV_PACKAGE" C_DEV_PACKAGE_SUB_DIR="$PACKAGES_ROOT_DIR/$C_DEV_PACKAGE/CSFML" PACKAGES_INFO_FILES_DIR="$XCODE_CXX_ROOT_DIR/dist" +CXX_SDK_PACKAGE_DIR_64B="$PACKAGES_ROOT_DIR_64B/$CXX_SDK_PACKAGE_64B" +CXX_DEV_PACKAGE_DIR_64B="$PACKAGES_ROOT_DIR_64B/$CXX_DEV_PACKAGE_64B" +C_SDK_PACKAGE_DIR_64B="$PACKAGES_ROOT_DIR_64B/$C_SDK_PACKAGE_64B" +C_DEV_PACKAGE_DIR_64B="$PACKAGES_ROOT_DIR_64B/$C_DEV_PACKAGE_64B" + CXX_SDK_DIRS=("build" "src" "include" "lib" "extlibs" "samples" "doc") CXX_DEV_DIRS=("lib" "extlibs" "build/xcode/templates") C_SDK_DIRS=("src" "include" "extlibs") @@ -65,9 +95,15 @@ C_DEV_DIRS=("extlibs") C_DEV_SUB_DIRS=("CSFML/xcode/templates" "CSFML/lib") PACKAGE_INFO_FILES=("Read Me.rtf" "Release Notes.rtf" "Notes de version.rtf" "license.txt" "Lisez-moi.rtf") + +# Build detection +SHOULD_CONSIDER_64B="yes" SHOULD_CONSIDER_CXX="yes" +SHOULD_CONSIDER_CXX_64B="yes" SHOULD_CONSIDER_C="yes" +SHOULD_CONSIDER_C_64B="yes" SHOULD_CONSIDER_SAMPLES="yes" +SHOULD_CONSIDER_SAMPLES_64B="yes" VERBOSE_OUTPUT="/dev/null" @@ -82,6 +118,7 @@ check_last_process() fi else echo "*** Last process did not end properly. Process stopped." + echo "*** Error occured when executed from `pwd`" exit 1 fi } @@ -89,7 +126,7 @@ check_last_process() # User help print_usage() { - echo "Usage: $0 [clean | build | build-samples | build-pkg | all [--verbose]]" + echo "Usage: $0 [clean[-32|-64] | build[-32|-64] | build-samples[-32|-64] | build-pkg[-32|-64] | all[-32|-64] [--verbose]]" echo echo "Commands:" echo " clean\t\tdeletes the C and C++ frameworks, object files and packages" @@ -102,23 +139,42 @@ print_usage() echo "Options:" echo " --verbose\t\tdo not hide standard ouput, errors are still shown" echo + echo "Command suffixes:" + echo " -32\t\t\tapply command for 32 bits PowerPC and Intel binaries" + echo " -64\t\t\tapply command for 32 bits PowerPC and Intel, and 64 bits Intel binaries" + echo " \t\t\tDefault applies command for both choices" + echo " \t\t\t(ie. build frameworks for both 32 and 64 bits platforms)" + echo echo "Contents summary:" - echo " Found C++ project : $SHOULD_CONSIDER_CXX" - echo " Found C project : $SHOULD_CONSIDER_C" - echo " Found samples project : $SHOULD_CONSIDER_SAMPLES" + echo " Found C++ frameworks project \t\t $SHOULD_CONSIDER_CXX" + echo " Found C frameworks project \t\t\t $SHOULD_CONSIDER_C" + echo " Found samples project \t\t\t $SHOULD_CONSIDER_SAMPLES" + echo " Can build Intel 64 bits binaries \t\t $SHOULD_CONSIDER_64B" + echo " Found C++ 64 bits frameworks project \t $SHOULD_CONSIDER_CXX_64B" + echo " Found C 64 bits frameworks project \t\t $SHOULD_CONSIDER_C_64B" + echo " Found 64 bits samples project \t\t $SHOULD_CONSIDER_SAMPLES_64B" echo " Missing projects will be skiped without further warning." } # Checks that the user computer can run this script check_config() { + # Check OS type and version os=`uname -s` + version=`uname -r` # 10.2.0 form; 8.x = Mac OS X 10.4 if [ $os != "Darwin" ] then echo "You're not running Mac OS X !" exit 1 fi + version=${version%%.*} + if test $version -le 8 # 64 bits builds not supported on Mac OS X 10.4 and earlier + then + SHOULD_CONSIDER_64B="no" + fi + + # Check scripts tools if ! test -f "/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp" then echo "Missing tool pbxcp needed by this script (should be located at /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp). Make sure Apple Developer Tools are correctly installed." @@ -138,6 +194,7 @@ check_config() exit 1 fi + # Check Xcode projects availability if ! test -d "$XCODE_CXX_ROOT_DIR/$XCODE_FRAMEWORKS_PROJECT" then SHOULD_CONSIDER_CXX="no" @@ -152,6 +209,29 @@ check_config() then SHOULD_CONSIDER_SAMPLES="no" fi + + # 64 bits projects + if [ "$SHOULD_CONSIDER_64B" == "no" ] + then + SHOULD_CONSIDER_CXX_64B="no" + SHOULD_CONSIDER_C_64B="no" + SHOULD_CONSIDER_SAMPLES_64B="no" + else + if ! test -d "$XCODE_CXX_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + SHOULD_CONSIDER_CXX_64B="no" + fi + + if ! test -d "$XCODE_C_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + SHOULD_CONSIDER_C_64B="no" + fi + + if ! test -d "$XCODE_SAMPLES_ROOT_DIR/$XCODE_64B_SAMPLE_PROJECT" + then + SHOULD_CONSIDER_SAMPLES_64B="no" + fi + fi } # Makes a directory if needed @@ -160,6 +240,7 @@ make_dir() if ! test -d "$1" then mkdir -p "$1" + check_last_process "[param:$1]" fi } @@ -271,6 +352,85 @@ clean_all() check_last_process " done" } +# Delete built frameworks and intermediate object files (64 bits) +clean_all_64b() +{ + if [ "$SHOULD_CONSIDER_64B" == "yes" ] + then + cd "$ROOT_DIR" + + # Process cleaning for C++ project + if [ "$SHOULD_CONSIDER_CXX_64B" == "yes" ] + then + printf "Cleaning 64 bits C++ products..." + if test -d "$XCODE_CXX_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + cd "$XCODE_CXX_ROOT_DIR" + xcodebuild -project "$XCODE_64B_FRAMEWORKS_PROJECT" -target "All" -configuration "$XCODE_BUILD_STYLE" clean > "$VERBOSE_OUTPUT" + check_last_process " done" + else + if test -d "$XCODE_CXX_ROOT_DIR" + then + echo "*** Missing file $XCODE_CXX_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT. Process stopped." + exit 1 + else + echo " not found. Skiped" + fi + fi + fi + + + # Process cleaning for C project + if [ "$SHOULD_CONSIDER_C_64B" == "yes" ] + then + printf "Cleaning 64 bits C products..." + if test -d "$XCODE_C_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + cd "$XCODE_C_ROOT_DIR" + xcodebuild -project "$XCODE_64B_FRAMEWORKS_PROJECT" -target "All" -configuration "$XCODE_BUILD_STYLE" clean > "$VERBOSE_OUTPUT" + check_last_process " done" + else + # Do not produce error if the package does no contain the C stuff + if test -d "$XCODE_C_ROOT_DIR" + then + echo "*** Missing file $XCODE_C_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT. Process stopped." + exit 1 + else + echo " not found. Skiped" + fi + fi + fi + + # Process cleaning for samples + if [ "$SHOULD_CONSIDER_64B_SAMPLES" == "yes" ] + then + printf "Cleaning 64 bits samples..." + if test -d "$XCODE_SAMPLES_ROOT_DIR/$XCODE_64B_SAMPLES_PROJECT" + then + cd "$XCODE_SAMPLES_ROOT_DIR" + xcodebuild -project "$XCODE_64B_SAMPLES_PROJECT" -target "All" -configuration "$XCODE_BUILD_STYLE" clean > "$VERBOSE_OUTPUT" + check_last_process " done" + else + # Do not produce error if the package does not contain the samples + if test -d "$XCODE_SAMPLES_ROOT_DIR" + then + echo "*** Missing file $XCODE_SAMPLES_ROOT_DIR/$XCODE_64B_SAMPLES_PROJECT. Process stopped." + exit 1 + else + echo " not found. Skiped" + fi + fi + fi + + # Process cleaning for packages + printf "Removing 64 bits packages..." + remove_dir "$PACKAGES_ROOT_DIR" + check_last_process " done" + else + echo "Intel 64 bits is not supported on your computer. Process skiped" + fi +} + # Build C and C++ frameworks build_frameworks() { @@ -323,6 +483,63 @@ build_frameworks() fi } +# Build C and C++ frameworks (with Intel 64 bits) +build_frameworks_64b() +{ + if [ "$SHOULD_CONSIDER_64B" == "yes" ] + then + # Go into the C++ project directory + if [ "$SHOULD_CONSIDER_CXX_64B" == "yes" ] + then + cd "$XCODE_CXX_ROOT_DIR" + check_last_process + echo "Building 64 bits C++ SFML frameworks in $XCODE_BUILD_STYLE mode..." + + if test -d "$XCODE_CXX_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + # Build every C++ target (building manually each target to be able to show progress) + for target in "${XCODE_CXX_TARGETS[@]}" + do + printf "Building 64 bits $target framework..." + xcodebuild -project "$XCODE_64B_FRAMEWORKS_PROJECT" -target "$target" -parallelizeTargets -configuration "$XCODE_BUILD_STYLE" build > "$VERBOSE_OUTPUT" + check_last_process " done" + done + + echo "All C++ SFML frameworks built." + else + echo "*** Missing file $XCODE_CXX_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT. Process stopped." + exit 1 + fi + fi + + # Go into the C project directory + if [ "$SHOULD_CONSIDER_C_64B" == "yes" ] + then + cd "$XCODE_C_ROOT_DIR" + check_last_process + echo "Building C SFML frameworks in $XCODE_BUILD_STYLE mode..." + + if test -d "$XCODE_C_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT" + then + # Build every C target + for target in "${XCODE_C_TARGETS[@]}" + do + printf "Building 64 bits $target framework..." + xcodebuild -project "$XCODE_64B_FRAMEWORKS_PROJECT" -target "$target" -parallelizeTargets -configuration "$XCODE_BUILD_STYLE" build > "$VERBOSE_OUTPUT" + check_last_process " done" + done + + echo "All C SFML frameworks built." + else + echo "*** Missing file $XCODE_C_ROOT_DIR/$XCODE_64B_FRAMEWORKS_PROJECT. Process stopped." + exit 1 + fi + fi + else + echo "Intel 64 bits is not supported on your computer. Process skiped" + fi +} + # Build the samples build_samples() { @@ -347,6 +564,35 @@ build_samples() fi } +# Build the samples (with Intel 64 bits) +build_samples_64b() +{ + if [ "$SHOULD_CONSIDER_64B" == "yes" ] + then + # Go into the samples project directory + if [ "$SHOULD_CONSIDER_SAMPLES_64B" == "yes" ] + then + cd "$XCODE_SAMPLES_ROOT_DIR" + check_last_process + + printf "Building 64 bits SFML samples in $XCODE_BUILD_STYLE mode..." + if test -d "$XCODE_SAMPLES_ROOT_DIR/$XCODE_64B_SAMPLES_PROJECT" + then + # Build the samples + xcodebuild -project "$XCODE_64B_SAMPLES_PROJECT" -target "All" -parallelizeTargets -configuration "$XCODE_BUILD_STYLE" build > "$VERBOSE_OUTPUT" + check_last_process " done" + echo "In order to run the samples, the SFML frameworks (located in \"lib\") must be copied in the /Library/Frameworks directory." > "$CXX_SAMPLES_DIR/README" + check_last_process + else + echo "*** Missing file $XCODE_SAMPLES_ROOT_DIR/$XCODE_64B_SAMPLES_PROJECT. Process stopped." + exit 1 + fi + fi + else + echo "Intel 64 bits is not supported on your computer. Process skiped" + fi +} + # Put the information files in the package copy_info_files() { @@ -494,6 +740,147 @@ build_packages() echo "All packages have been built. See $PACKAGES_ROOT_DIR." } +# Build the archives of the C and C++ Dev and SDK packages (for Intel 64 bits) +build_packages_64b() +{ + if [ "$SHOULD_CONSIDER_64B" == "yes" ] + then + cd "$ROOT_DIR" + make_dir "$PACKAGES_ROOT_DIR_64B" + + # Build the C++ SDK package + if [ "$SHOULD_CONSIDER_CXX_64B" == "yes" ] + then + printf "Building 64 bits C++ SDK package..." + make_dir "$CXX_SDK_PACKAGE_DIR_64B" + for dir in "${CXX_SDK_DIRS[@]}" + do + case "$dir" in + "doc") + if ! test -f "$ROOT_DIR/$dir/html/index.htm" + then + echo "*** $ROOT_DIR/$dir/html/index.htm not found. Make sure the documentation has been built." + exit 1 + fi + ;; + esac + + copy "$ROOT_DIR/$dir" "$CXX_SDK_PACKAGE_DIR_64B" + check_last_process + done + copy_info_files "$CXX_SDK_PACKAGE_DIR_64B" + check_last_process + + # Build the archive + cd "$PACKAGES_ROOT_DIR_64B" + tar -cjlf "$PACKAGES_ROOT_DIR_64B/$CXX_SDK_PACKAGE_64B.tar.bz2" "$CXX_SDK_PACKAGE_64B" > "$VERBOSE_OUTPUT" + check_last_process " done" + + # Build the C++ Dev package + printf "Building 64 bits C++ Development package..." + make_dir "$CXX_DEV_PACKAGE_DIR_64B" + for dir in "${CXX_DEV_DIRS[@]}" + do + copy "$ROOT_DIR/$dir" "$CXX_DEV_PACKAGE_DIR_64B" + check_last_process + + case $dir in + "build/xcode/templates") + # Special consideration for the templates folder that is to be moved in build/xcode + move_dir "$CXX_DEV_PACKAGE_DIR_64B/templates" "$CXX_DEV_PACKAGE_DIR_64B/build/xcode" + check_last_process + ;; + "extlibs") + # Drop the libs-xcode and headers directories + remove_dir "$CXX_DEV_PACKAGE_DIR_64B/extlibs/libs-xcode" + check_last_process + remove_dir "$CXX_DEV_PACKAGE_DIR_64B/extlibs/headers" + check_last_process + ;; + *) + ;; + esac + done + copy_info_files "$CXX_DEV_PACKAGE_DIR_64B" + + # Build the archive + cd "$PACKAGES_ROOT_DIR_64B" + tar -cjlf "$PACKAGES_ROOT_DIR_64B/$CXX_DEV_PACKAGE_64B.tar.bz2" "$CXX_DEV_PACKAGE_64B" > "$VERBOSE_OUTPUT" + check_last_process " done" + fi # SHOULD_CONSIDER_CXX + + + # Build the C SDK package + if [ "$SHOULD_CONSIDER_C_64B" == "yes" ] + then + printf "Building 64 bits C SDK package..." + make_dir "$C_SDK_PACKAGE_DIR_64B" + for dir in "${C_SDK_DIRS[@]}" + do + copy "$ROOT_DIR/$dir" "$C_SDK_PACKAGE_DIR_64B" + check_last_process + done + + make_dir "$C_SDK_PACKAGE_SUB_DIR" + for dir in "${C_SDK_SUB_DIRS[@]}" + do + copy "$ROOT_DIR/$dir" "$C_SDK_PACKAGE_SUB_DIR" + check_last_process + done + copy_info_files "$C_SDK_PACKAGE_DIR_64B" + + # Build the archive + cd "$PACKAGES_ROOT_DIR_64B" + tar -cjlf "$PACKAGES_ROOT_DIR_64B/$C_SDK_PACKAGE_64B.tar.bz2" "$C_SDK_PACKAGE_64B" > "$VERBOSE_OUTPUT" + check_last_process " done" + + # Build the C Development package + printf "Building 64 bits C Development package..." + make_dir "$C_DEV_PACKAGE_DIR_64B" + for dir in "${C_DEV_DIRS[@]}" + do + copy "$ROOT_DIR/$dir" "$C_DEV_PACKAGE_DIR_64B" + check_last_process + + case $dir in + "extlibs") + # Drop the libs-xcode and headers directories + remove_dir "$C_DEV_PACKAGE_DIR_64B/extlibs/libs-xcode" + check_last_process + remove_dir "$C_DEV_PACKAGE_DIR_64B/extlibs/headers" + check_last_process + ;; + esac + done + + make_dir "$C_DEV_PACKAGE_SUB_DIR" + for dir in "${C_DEV_SUB_DIRS[@]}" + do + copy "$ROOT_DIR/$dir" "$C_DEV_PACKAGE_SUB_DIR_64B" + check_last_process + + case $dir in + "CSFML/xcode/templates") + # Special consideration for the templates folder that is to be moved in build/xcode + move_dir "$C_DEV_PACKAGE_DIR_64B/CSFML/templates" "$C_DEV_PACKAGE_DIR_64B/CSFML/xcode" + check_last_process + ;; + esac + done + copy_info_files "$C_DEV_PACKAGE_DIR_64B" + + # Build the archive + cd "$PACKAGES_ROOT_DIR_64B" + tar -cjlf "$PACKAGES_ROOT_DIR_64B/$C_DEV_PACKAGE_64B.tar.bz2" "$C_DEV_PACKAGE_64B" > "$VERBOSE_OUTPUT" + check_last_process " done" + fi + + echo "All packages have been built. See $PACKAGES_ROOT_DIR_64B." + else + echo "Intel 64 bits is not supported on your computer. Process skiped" + fi +} + main() { # First make sure the user will be able to run the script @@ -517,28 +904,77 @@ main() case $action in "clean") clean_all $* + clean_all_64b $* ;; + + "clean-32") + clean_all $* + ;; + + "clean-64") + clean_all_64b $* + ;; + "build") build_frameworks $* + build_frameworks_64b $* ;; + + "build-32") + build_frameworks $* + ;; + + "build-64") + build_frameworks_64b $* + ;; + "build-samples") build_samples $* + build_samples_64b $* ;; + "build-samples-32") + build_samples $* + ;; + + "build-samples-64") + build_samples_64b $* + ;; + "build-pkg") build_packages $* + build_packages_64b $* ;; + + "build-pkg-32") + build_packages $* + ;; + + "build-pkg-64") + build_packages_64b $* + ;; + "all") build_frameworks $* + build_frameworks_64b $* build_samples $* + build_samples_64b $* build_packages $* + build_packages64b $* ;; - "-h") - print_usage $* - ;; - "--help") - print_usage $* - ;; - "help") + + "all-32") + build_frameworks $* + build_samples $* + build_packages $* + ;; + + "all-64") + build_frameworks_64b $* + build_samples_64b $* + build_packages_64b $* + ;; + + "-h" | "--help" | "help") print_usage $* ;; "--verbose") diff --git a/include/SFML/Graphics/Sprite.hpp b/include/SFML/Graphics/Sprite.hpp index fc5f25ea..4b9e96de 100644 --- a/include/SFML/Graphics/Sprite.hpp +++ b/include/SFML/Graphics/Sprite.hpp @@ -61,7 +61,7 @@ public : /// \param color : Color of the sprite /// //////////////////////////////////////////////////////////// - Sprite(const Image& image, const Vector2f& position = Vector2f(0, 0), const Vector2f& scale = Vector2f(1, 1), float rotation = 0.f, const Color& color = Color(255, 255, 255, 255)); + explicit Sprite(const Image& image, const Vector2f& position = Vector2f(0, 0), const Vector2f& scale = Vector2f(1, 1), float rotation = 0.f, const Color& color = Color(255, 255, 255, 255)); //////////////////////////////////////////////////////////// /// Change the image of the sprite diff --git a/include/SFML/Network/SocketTCP.hpp b/include/SFML/Network/SocketTCP.hpp index dcc5a245..4adacf48 100644 --- a/include/SFML/Network/SocketTCP.hpp +++ b/include/SFML/Network/SocketTCP.hpp @@ -214,8 +214,10 @@ private : // Member data //////////////////////////////////////////////////////////// SocketHelper::SocketType mySocket; ///< Socket descriptor - std::vector myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode) - Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode) + Uint32 myPendingHeader; ///< Data of the current pending packet header, if any + Uint32 myPendingHeaderSize; ///< Size of the current pending packet header, if any + std::vector myPendingPacket; ///< Data of the current pending packet, if any + Int32 myPendingPacketSize; ///< Size of the current pending packet, if any bool myIsBlocking; ///< Is the socket blocking or non-blocking ? }; diff --git a/include/SFML/Network/SocketUDP.hpp b/include/SFML/Network/SocketUDP.hpp index 3c9b965a..a177c3bf 100644 --- a/include/SFML/Network/SocketUDP.hpp +++ b/include/SFML/Network/SocketUDP.hpp @@ -215,8 +215,10 @@ private : //////////////////////////////////////////////////////////// SocketHelper::SocketType mySocket; ///< Socket identifier unsigned short myPort; ///< Port to which the socket is bound - std::vector myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode) - Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode) + Uint32 myPendingHeader; ///< Data of the current pending packet header, if any + Uint32 myPendingHeaderSize; ///< Size of the current pending packet header, if any + std::vector myPendingPacket; ///< Data of the current pending packet, if any + Int32 myPendingPacketSize; ///< Size of the current pending packet, if any bool myIsBlocking; ///< Is the socket blocking or non-blocking ? }; diff --git a/src/SFML/Network/Ftp.cpp b/src/SFML/Network/Ftp.cpp index b9a3f4b0..8ebfc213 100644 --- a/src/SFML/Network/Ftp.cpp +++ b/src/SFML/Network/Ftp.cpp @@ -380,7 +380,9 @@ Ftp::Response Ftp::Download(const std::string& distantFile, const std::string& d std::ofstream file((path + filename).c_str(), std::ios_base::binary); if (!file) return Response(Response::InvalidFile); - file.write(&fileData[0], static_cast(fileData.size())); + + if (!fileData.empty()) + file.write(&fileData[0], static_cast(fileData.size())); } } } @@ -398,11 +400,13 @@ Ftp::Response Ftp::Upload(const std::string& localFile, const std::string& destP std::ifstream file(localFile.c_str(), std::ios_base::binary); if (!file) return Response(Response::InvalidFile); + file.seekg(0, std::ios::end); std::size_t length = file.tellg(); file.seekg(0, std::ios::beg); std::vector fileData(length); - file.read(&fileData[0], static_cast(length)); + if (length > 0) + file.read(&fileData[0], static_cast(length)); // Extract the filename from the file path std::string filename = localFile; @@ -700,7 +704,8 @@ void Ftp::DataChannel::Receive(std::vector& data) void Ftp::DataChannel::Send(const std::vector& data) { // Send data - myDataSocket.Send(&data[0], data.size()); + if (!data.empty()) + myDataSocket.Send(&data[0], data.size()); // Close the data socket myDataSocket.Close(); diff --git a/src/SFML/Network/Http.cpp b/src/SFML/Network/Http.cpp index ad880dcd..a9695246 100644 --- a/src/SFML/Network/Http.cpp +++ b/src/SFML/Network/Http.cpp @@ -27,6 +27,8 @@ //////////////////////////////////////////////////////////// #include #include +#include +#include #include @@ -294,8 +296,7 @@ void Http::Response::FromString(const std::string& data) // Finally extract the body myBody.clear(); - while (std::getline(in, line)) - myBody += line + "\n"; + std::copy(std::istreambuf_iterator(in), std::istreambuf_iterator(), std::back_inserter(myBody)); } diff --git a/src/SFML/Network/SocketTCP.cpp b/src/SFML/Network/SocketTCP.cpp index cc50d751..278dc995 100644 --- a/src/SFML/Network/SocketTCP.cpp +++ b/src/SFML/Network/SocketTCP.cpp @@ -344,11 +344,20 @@ Socket::Status SocketTCP::Receive(Packet& packet) std::size_t received = 0; if (myPendingPacketSize < 0) { - Socket::Status status = Receive(reinterpret_cast(&packetSize), sizeof(packetSize), received); - if (status != Socket::Done) - return status; + // Loop until we've received the entire size of the packet + // (even a 4 bytes variable may be received in more than one call) + while (myPendingHeaderSize < sizeof(myPendingHeader)) + { + char* data = reinterpret_cast(&myPendingHeader) + myPendingHeaderSize; + Socket::Status status = Receive(data, sizeof(myPendingHeader) - myPendingHeaderSize, received); + myPendingHeaderSize += received; - packetSize = ntohl(packetSize); + if (status != Socket::Done) + return status; + } + + packetSize = ntohl(myPendingHeader); + myPendingHeaderSize = 0; } else { @@ -472,6 +481,7 @@ void SocketTCP::Create(SocketHelper::SocketType descriptor) myIsBlocking = true; // Reset the pending packet + myPendingHeaderSize = 0; myPendingPacket.clear(); myPendingPacketSize = -1; diff --git a/src/SFML/Network/SocketUDP.cpp b/src/SFML/Network/SocketUDP.cpp index 05e96839..a31805b4 100644 --- a/src/SFML/Network/SocketUDP.cpp +++ b/src/SFML/Network/SocketUDP.cpp @@ -249,11 +249,20 @@ Socket::Status SocketUDP::Receive(Packet& packet, IPAddress& address, unsigned s std::size_t received = 0; if (myPendingPacketSize < 0) { - Socket::Status status = Receive(reinterpret_cast(&packetSize), sizeof(packetSize), received, address, port); - if (status != Socket::Done) - return status; + // Loop until we've received the entire size of the packet + // (even a 4 bytes variable may be received in more than one call) + while (myPendingHeaderSize < sizeof(myPendingHeader)) + { + char* data = reinterpret_cast(&myPendingHeader) + myPendingHeaderSize; + Socket::Status status = Receive(data, sizeof(myPendingHeader) - myPendingHeaderSize, received, address, port); + myPendingHeaderSize += received; - packetSize = ntohl(packetSize); + if (status != Socket::Done) + return status; + } + + packetSize = ntohl(myPendingHeader); + myPendingHeaderSize = 0; } else { @@ -261,9 +270,6 @@ Socket::Status SocketUDP::Receive(Packet& packet, IPAddress& address, unsigned s packetSize = myPendingPacketSize; } - // Clear the user packet - packet.Clear(); - // Use another address instance for receiving the packet data ; // chunks of data coming from a different sender will be discarded (and lost...) IPAddress sender; @@ -398,6 +404,7 @@ void SocketUDP::Create(SocketHelper::SocketType descriptor) myPort = 0; // Reset the pending packet + myPendingHeaderSize = 0; myPendingPacket.clear(); myPendingPacketSize = -1; diff --git a/src/SFML/System/Randomizer.cpp b/src/SFML/System/Randomizer.cpp index e8402436..aebd2bb8 100644 --- a/src/SFML/System/Randomizer.cpp +++ b/src/SFML/System/Randomizer.cpp @@ -26,8 +26,8 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -#include +#include +#include //////////////////////////////////////////////////////////// @@ -39,7 +39,7 @@ namespace // in milliseconds, so that it is always different unsigned int InitializeSeed() { - unsigned int seed = static_cast(sf::priv::Platform::GetSystemTime() * 1000); + unsigned int seed = static_cast(time(NULL)); srand(seed); return seed; } diff --git a/src/SFML/System/Thread.cpp b/src/SFML/System/Thread.cpp index ae561c39..80bf590f 100644 --- a/src/SFML/System/Thread.cpp +++ b/src/SFML/System/Thread.cpp @@ -71,7 +71,7 @@ Thread::~Thread() //////////////////////////////////////////////////////////// void Thread::Launch() { - delete myThreadImpl; + Wait(); myThreadImpl = new priv::ThreadImpl(this); } diff --git a/src/SFML/Window/Cocoa/AppController.h b/src/SFML/Window/Cocoa/AppController.h index e87fe3a3..de2d055f 100644 --- a/src/SFML/Window/Cocoa/AppController.h +++ b/src/SFML/Window/Cocoa/AppController.h @@ -36,10 +36,10 @@ enum { CleanScreen }; -@class WindowWrapper; -@interface AppController : NSObject { +@class sfPrivWindow; +@interface sfPrivAppController : NSObject { BOOL myOwningEventLoop; - WindowWrapper *myFullscreenWrapper; + sfPrivWindow *myFullscreenWrapper; NSAutoreleasePool *myMainPool; sf::VideoMode myDesktopMode; sf::VideoMode myPrevMode; @@ -48,7 +48,7 @@ enum { //////////////////////////////////////////////////////////// /// Return the shared AppController instance. Make one if needed. //////////////////////////////////////////////////////////// -+ (AppController *)sharedController; ++ (sfPrivAppController *)sharedController; //////////////////////////////////////////////////////////// /// Returns the primay computer's screen @@ -76,7 +76,7 @@ enum { /// Set @window as the current fullscreen window /// Change the screen resolution if needed according to @window and @fullscreenMode //////////////////////////////////////////////////////////// -- (void)setFullscreenWindow:(WindowWrapper *)window mode:(sf::VideoMode *)fullscreenMode; +- (void)setFullscreenWindow:(sfPrivWindow *)window mode:(sf::VideoMode *)fullscreenMode; //////////////////////////////////////////////////////////// /// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen} diff --git a/src/SFML/Window/Cocoa/AppController.mm b/src/SFML/Window/Cocoa/AppController.mm index 5a90c21c..93560906 100644 --- a/src/SFML/Window/Cocoa/AppController.mm +++ b/src/SFML/Window/Cocoa/AppController.mm @@ -57,7 +57,7 @@ @end -@implementation AppController +@implementation sfPrivAppController //////////////////////////////////////////////////////////// @@ -129,10 +129,10 @@ //////////////////////////////////////////////////////////// /// Return the shared AppController instance. Make one if needed. //////////////////////////////////////////////////////////// -+ (AppController *)sharedController ++ (sfPrivAppController *)sharedController { // AppController singleton object - static AppController *shared = [[AppController alloc] init]; + static sfPrivAppController *shared = [[sfPrivAppController alloc] init]; return shared; } @@ -192,7 +192,7 @@ if (myFullscreenWrapper) { myPrevMode = sf::VideoMode::GetDesktopMode(); - CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen], + CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen], myDesktopMode.BitsPerPixel, myDesktopMode.Width, myDesktopMode.Height, @@ -202,7 +202,7 @@ [[myFullscreenWrapper window] setAlphaValue:0.0f]; // Switch to the wished display mode - CGDisplaySwitchToMode([AppController primaryScreen], displayMode); + CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode); } } @@ -213,7 +213,7 @@ - (void)applicationWillActivate:(NSNotification *)aNotification { if (myFullscreenWrapper) { - CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen], + CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen], myPrevMode.BitsPerPixel, myPrevMode.Width, myPrevMode.Height, @@ -221,7 +221,7 @@ [NSMenu setMenuBarVisible:NO]; // Switch to the wished display mode - CGDisplaySwitchToMode([AppController primaryScreen], displayMode); + CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode); // Show the fullscreen window if existing if (myFullscreenWrapper) @@ -380,14 +380,14 @@ myOwningEventLoop = YES; } - // Clean the autorelease pool - [myMainPool release]; - myMainPool = [[NSAutoreleasePool alloc] init]; - NSEvent *event = nil; if (myOwningEventLoop) { + // Clean the autorelease pool + [myMainPool release]; + myMainPool = [[NSAutoreleasePool alloc] init]; + // Minimal event loop while (nil != (event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil @@ -404,13 +404,13 @@ /// Set @window as the current fullscreen window /// Change the screen resolution if needed according to @window and @fullscreenMode //////////////////////////////////////////////////////////// -- (void)setFullscreenWindow:(WindowWrapper *)aWrapper mode:(sf::VideoMode *)fullscreenMode +- (void)setFullscreenWindow:(sfPrivWindow *)aWindow mode:(sf::VideoMode *)fullscreenMode { // If we have a fullscreen window and want to remove it - if (aWrapper == nil && myFullscreenWrapper) + if (aWindow == nil && myFullscreenWrapper) { // Get the CoreGraphics display mode according to the desktop mode - CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen], + CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen], myDesktopMode.BitsPerPixel, myDesktopMode.Width, myDesktopMode.Height, @@ -422,7 +422,7 @@ #endif // Switch to the desktop display mode - CGDisplaySwitchToMode([AppController primaryScreen], displayMode); + CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode); // Close the window [[myFullscreenWrapper window] close]; @@ -438,13 +438,13 @@ // Release the saved window wrapper myFullscreenWrapper = nil; } - else if (aWrapper) + else if (aWindow) { // else if we want to SET fullscreen assert(fullscreenMode != NULL); // Get the CoreGraphics display mode according to the given sf mode - CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([AppController primaryScreen], + CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen], fullscreenMode->BitsPerPixel, fullscreenMode->Width, fullscreenMode->Height, @@ -465,7 +465,7 @@ { // Switch to the wished display mode myPrevMode = *fullscreenMode; - CGDisplaySwitchToMode([AppController primaryScreen], displayMode); + CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode); } if (myFullscreenWrapper) @@ -474,8 +474,8 @@ } // Open and center the window - [[aWrapper window] makeKeyAndOrderFront:nil]; - [[aWrapper window] center]; + [[aWindow window] makeKeyAndOrderFront:nil]; + [[aWindow window] center]; #if ENABLE_FADE_OPERATIONS // Fade to normal screen @@ -483,11 +483,11 @@ #endif // Save the fullscreen wrapper - myFullscreenWrapper = aWrapper; + myFullscreenWrapper = aWindow; } else { - std::cerr << "Inconcistency error for arguments given to -[AppController setFullscreenWindow:mode:]" << std::endl; + std::cerr << "Inconcistency error for arguments given to -[sfPrivAppController setFullscreenWindow:mode:]" << std::endl; } } @@ -514,7 +514,7 @@ if (!result) { // Capture display but do not fill the screen with black // so that we can see the fade operation - capture = CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoFill); + capture = CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill); if (!capture) { // Do the increasing fade operation @@ -524,11 +524,11 @@ 0.0f, 0.0f, 0.0f, sync); // Now, release the non black-filling capture - CGDisplayRelease([AppController primaryScreen]); + CGDisplayRelease([sfPrivAppController primaryScreen]); // And capture with filling // so that we don't see the switching in the meantime - CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoOptions); + CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoOptions); } prevToken = token; @@ -541,10 +541,10 @@ if (!result) { if (!capture) { // Release the black-filling capture - CGDisplayRelease([AppController primaryScreen]); + CGDisplayRelease([sfPrivAppController primaryScreen]); // Capture the display but do not fill with black (still for the fade operation) - CGDisplayCaptureWithOptions([AppController primaryScreen], kCGCaptureNoFill); + CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill); // Do the decreasing fading CGDisplayFade(token, time, @@ -560,7 +560,7 @@ } // Release the captured display - CGDisplayRelease([AppController primaryScreen]); + CGDisplayRelease([sfPrivAppController primaryScreen]); } } } diff --git a/src/SFML/Window/Cocoa/GLKit.h b/src/SFML/Window/Cocoa/GLKit.h index ca916c78..39420944 100644 --- a/src/SFML/Window/Cocoa/GLKit.h +++ b/src/SFML/Window/Cocoa/GLKit.h @@ -32,10 +32,7 @@ //////////////////////////////////////////////////////////// /// Window independant OpenGL context class //////////////////////////////////////////////////////////// -@interface GLContext : NSOpenGLContext -{ - -} +@interface sfPrivGLContext : NSOpenGLContext //////////////////////////////////////////////////////////// /// Return the shared OpenGL context instance (making one if needed) @@ -47,7 +44,7 @@ /// and the shared context @context //////////////////////////////////////////////////////////// - (id)initWithAttributes:(sf::WindowSettings&)attribs - sharedContext:(GLContext *)context; + sharedContext:(sfPrivGLContext *)context; @end @@ -55,22 +52,31 @@ //////////////////////////////////////////////////////////// /// Customized Cocoa OpenGL view //////////////////////////////////////////////////////////// -@interface GLView : NSOpenGLView +@interface sfPrivGLView : NSOpenGLView { sf::priv::WindowImplCocoa *myDelegate; - GLContext *myGLContext; + sfPrivGLContext *myGLContext; } //////////////////////////////////////////////////////////// /// Make a new view according the the rect @frame, /// the video mode @mode, the window settings @settings -/// and the sf window delegate @delegate /// @delegate must not be null //////////////////////////////////////////////////////////// - (id)initWithFrame:(NSRect)frame mode:(const sf::VideoMode&)mode - settings:(sf::WindowSettings&)settings - delegate:(sf::priv::WindowImplCocoa *)delegate; + settings:(sf::WindowSettings&)settings; + + +//////////////////////////////////////////////////////////// +/// Sets @aDelegate as the view delegate +//////////////////////////////////////////////////////////// +- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate; + +//////////////////////////////////////////////////////////// +/// Returns the view delegate +//////////////////////////////////////////////////////////// +- (sf::priv::WindowImplCocoa *)delegate; //////////////////////////////////////////////////////////// /// Finish view setting (after having added it to the window) @@ -94,53 +100,16 @@ @end - //////////////////////////////////////////////////////////// -/// WindowWrapper class : handles both imported and self-built windows +/// Parent class for handling general SFML window stuff //////////////////////////////////////////////////////////// -@interface WindowWrapper : NSObject +@interface sfPrivWindow : NSObject { +@private NSWindow *myWindow; - GLView *myView; - sf::VideoMode myFullscreenMode; - bool myIsFullscreen; + sfPrivGLView *myView; } -//////////////////////////////////////////////////////////// -/// Make a new window wrapper according to the window settings @attribs, -/// the video mode @mode, the window style @style, the window title @title -/// and the sf window implementation delegate @delegate -//////////////////////////////////////////////////////////// -- (id)initWithSettings:(sf::WindowSettings&)attribs - videoMode:(sf::VideoMode&)mode - style:(unsigned long)style - title:(NSString *)title - delegate:(sf::priv::WindowImplCocoa *)delegate; - -//////////////////////////////////////////////////////////// -/// Make a new window wrapper by importing @window and according to -/// the window settings @params and the sf window implementation delegate -/// @delegate -/// @window and @delegate must not be null -//////////////////////////////////////////////////////////// -- (id)initWithWindow:(NSWindow *)window - settings:(sf::WindowSettings&)params - delegate:(sf::priv::WindowImplCocoa *)delegate; - -//////////////////////////////////////////////////////////// -/// Make a new window wrapper by importing @window if it's not null and according to -/// the window settings @params and the sf window implementation delegate -/// @delegate; or by creating a new window if @window is null. In this case @title -/// must therefore not be null and @params must be valid. -/// @delegate must never be null -//////////////////////////////////////////////////////////// -- (id)initWithWindow:(NSWindow *)window - settings:(sf::WindowSettings&)params - videoMode:(sf::VideoMode&)mode - style:(unsigned long)style - title:(NSString *)title - delegate:(sf::priv::WindowImplCocoa *)delegate; - //////////////////////////////////////////////////////////// /// Return a reference to the internal Cocoa window //////////////////////////////////////////////////////////// @@ -149,7 +118,17 @@ //////////////////////////////////////////////////////////// /// Return a reference to the internal Cocoa OpenGL view //////////////////////////////////////////////////////////// -- (GLView *)glView; +- (sfPrivGLView *)view; + +//////////////////////////////////////////////////////////// +/// Sets @aDelegate as the window delegate +//////////////////////////////////////////////////////////// +- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate; + +//////////////////////////////////////////////////////////// +/// Returns the window delegate +//////////////////////////////////////////////////////////// +- (sf::priv::WindowImplCocoa *)delegate; //////////////////////////////////////////////////////////// /// Forward call to set the window position on screen @@ -193,3 +172,61 @@ @end +//////////////////////////////////////////////////////////// +/// Class for creating new SFML windows from informations +//////////////////////////////////////////////////////////// +@interface sfPrivOwnedWindow : sfPrivWindow +{ +@private + sf::VideoMode myFullscreenMode; + bool myIsFullscreen; +} + +//////////////////////////////////////////////////////////// +/// Creates and returns a new SFML window handler with +/// the given parameters +//////////////////////////////////////////////////////////// +- (id)initWithVideoMode:(sf::VideoMode&)aMode + settings:(sf::WindowSettings&)someSettings + style:(unsigned long)aStyle + title:(NSString *)aTitle; + +//////////////////////////////////////////////////////////// +/// Returns the window's fullscreen state +//////////////////////////////////////////////////////////// +- (BOOL)isFullscreen; + +@end + + +//////////////////////////////////////////////////////////// +/// Class for creating SFML windows from Cocoa windows +//////////////////////////////////////////////////////////// +@interface sfPrivImportedWindow : sfPrivWindow + +//////////////////////////////////////////////////////////// +/// Returns a new SFML window handler with the given window +/// and parameters +//////////////////////////////////////////////////////////// +- (id)initWithWindow:(NSWindow *)aWindow + settings:(sf::WindowSettings&)someSettings; + +@end + + +//////////////////////////////////////////////////////////// +/// Class for creating SFML windows from Cocoa views +//////////////////////////////////////////////////////////// +@interface sfPrivImportedView : sfPrivWindow +{ + NSView *parentView; +} + +//////////////////////////////////////////////////////////// +/// Returns a new SFML window handler with the given view +/// and parameters +//////////////////////////////////////////////////////////// +- (id)initWithView:(NSView *)aView + settings:(sf::WindowSettings&)someSettings; + +@end diff --git a/src/SFML/Window/Cocoa/GLKit.mm b/src/SFML/Window/Cocoa/GLKit.mm index 8793f23b..bf2e8b68 100644 --- a/src/SFML/Window/Cocoa/GLKit.mm +++ b/src/SFML/Window/Cocoa/GLKit.mm @@ -33,10 +33,39 @@ #import +@interface sfPrivWindow (Protected) + +//////////////////////////////////////////////////////////// +/// Registers a reference to the internal Cocoa window +//////////////////////////////////////////////////////////// +- (void)setWindow:(NSWindow *)aWindow; + +//////////////////////////////////////////////////////////// +/// Registers the the OpenGL view and adds it to its parent container +//////////////////////////////////////////////////////////// +- (void)putOpenGLView:(sfPrivGLView *)aView; + +//////////////////////////////////////////////////////////// +/// Registers a reference to the internal Cocoa OpenGL view +//////////////////////////////////////////////////////////// +- (void)setView:(sfPrivGLView *)aView; + +@end + +@interface sfPrivOwnedWindow (Private) + +//////////////////////////////////////////////////////////// +/// Sets the window's fullscreen state +//////////////////////////////////////////////////////////// +- (void)setFullscreen:(BOOL)aFlag; + +@end + + //////////////////////////////////////////////////////////// /// Window independant OpenGL context class //////////////////////////////////////////////////////////// -@implementation GLContext +@implementation sfPrivGLContext //////////////////////////////////////////////////////////// @@ -46,13 +75,13 @@ { // Make a new context with the default parameters sf::WindowSettings params; - static GLContext *sharedCtx = [[GLContext alloc] initWithAttributes:params sharedContext:nil]; + static sfPrivGLContext *sharedCtx = [[sfPrivGLContext alloc] initWithAttributes:params sharedContext:nil]; return sharedCtx; } - (void)dealloc { - [[GLContext sharedContext] release]; + [[sfPrivGLContext sharedContext] release]; [super dealloc]; } @@ -60,7 +89,7 @@ /// Make a new OpenGL context according to the @attribs settings /// and the shared context @context //////////////////////////////////////////////////////////// -- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(GLContext *)sharedContext +- (id)initWithAttributes:(sf::WindowSettings&)attribs sharedContext:(sfPrivGLContext *)sharedContext { // Note about antialiasing and other context attributes : // OpenGL context sharing does not allow the shared contexts to use different attributes. @@ -72,7 +101,9 @@ // I've no way to fix this for now. if (attribs.AntialiasingLevel) - std::cerr << "Warning: antialiasing settings are inhibited under Mac OS X for technical reasons" << std::endl; + std::cerr + << "Warning: antialiasing settings are inhibited under Mac OS X for technical reasons" + << std::endl; NSOpenGLPixelFormat *myPixelFormat = nil; unsigned idx = 0; @@ -87,7 +118,7 @@ // Force use of first screen //ctxtAttribs[idx++] = NSOpenGLPFAScreenMask; - //ctxtAttribs[idx++] = CGDisplayIDToOpenGLDisplayMask([AppController primaryScreen]); + //ctxtAttribs[idx++] = CGDisplayIDToOpenGLDisplayMask([sfPrivAppController primaryScreen]); // windowed context (even fullscreen mode uses a window) ctxtAttribs[idx++] = NSOpenGLPFAWindow; @@ -144,7 +175,7 @@ //////////////////////////////////////////////////////////// /// Customized Cocoa OpenGL view //////////////////////////////////////////////////////////// -@implementation GLView +@implementation sfPrivGLView //////////////////////////////////////////////////////////// /// Make a new view according the the rect @frame, @@ -155,10 +186,7 @@ - (id)initWithFrame:(NSRect)frame mode:(const sf::VideoMode&)mode settings:(sf::WindowSettings&)settings - delegate:(sf::priv::WindowImplCocoa *)delegate { - assert(delegate != NULL); - // make the view self = [super initWithFrame:frame pixelFormat:nil]; @@ -168,8 +196,8 @@ [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; // make the OpenGL context - myGLContext = [[GLContext alloc] initWithAttributes:settings - sharedContext:[GLContext sharedContext]]; + myGLContext = [[sfPrivGLContext alloc] initWithAttributes:settings + sharedContext:[sfPrivGLContext sharedContext]]; if (!myGLContext) { [self release]; @@ -182,9 +210,6 @@ selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self]; - - // Save the delegate - myDelegate = delegate; } return self; @@ -203,6 +228,22 @@ [super dealloc]; } +//////////////////////////////////////////////////////////// +/// Sets @aDelegate as the view delegate +//////////////////////////////////////////////////////////// +- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate +{ + myDelegate = aDelegate; +} + +//////////////////////////////////////////////////////////// +/// Returns the view delegate +//////////////////////////////////////////////////////////// +- (sf::priv::WindowImplCocoa *)delegate +{ + return myDelegate; +} + //////////////////////////////////////////////////////////// /// Finish view setting (after having added it to the window) @@ -437,215 +478,9 @@ @end -//////////////////////////////////////////////////////////// -/// WindowWrapper class : handles both imported and self-built windows -//////////////////////////////////////////////////////////// -@implementation WindowWrapper -//////////////////////////////////////////////////////////// -/// Make a new window wrapper according to the window settings @attribs, -/// the video mode @mode, the window style @style, the window title @title -/// and the sf window implementation delegate @delegate -//////////////////////////////////////////////////////////// -- (id)initWithSettings:(sf::WindowSettings&)params - videoMode:(sf::VideoMode&)mode - style:(unsigned long)style - title:(NSString *)title - delegate:(sf::priv::WindowImplCocoa *)delegate -{ - return [self initWithWindow:nil - settings:params - videoMode:mode - style:style - title:title - delegate:delegate]; -} +@implementation sfPrivWindow - -//////////////////////////////////////////////////////////// -/// Make a new window wrapper by importing @window and according to -/// the window settings @params and the sf window implementation delegate -/// @delegate -/// @window and @delegate must not be null -//////////////////////////////////////////////////////////// -- (id)initWithWindow:(NSWindow *)window - settings:(sf::WindowSettings&)params - delegate:(sf::priv::WindowImplCocoa *)delegate -{ - sf::VideoMode mode([[myWindow contentView] frame].size.width, [[myWindow contentView] frame].size.height); - return [self initWithWindow:window - settings:params - videoMode:mode - style:0 - title:nil - delegate:delegate]; -} - - -//////////////////////////////////////////////////////////// -/// Make a new window wrapper by importing @window if it's not null and according to -/// the window settings @params and the sf window implementation delegate -/// @delegate; or by creating a new window if @window is null. In this case @title -/// must therefore not be null and @params must be valid. -/// @delegate must never be null -//////////////////////////////////////////////////////////// -- (id)initWithWindow:(NSWindow *)window - settings:(sf::WindowSettings&)params - videoMode:(sf::VideoMode&)mode - style:(unsigned long)style - title:(NSString *)title - delegate:(sf::priv::WindowImplCocoa *)delegate -{ - assert(delegate != NULL); - - self = [super init]; - - if (self) - { - if (window) { - myWindow = [window retain]; - } else { - assert(title != nil); - - NSRect frame = NSMakeRect (0.0f, 0.0f, (float) mode.Width, (float) mode.Height); - unsigned int mask = 0; - - if (style & sf::Style::Fullscreen) { - myIsFullscreen = true; - - // Check display mode and put new values in 'mode' if needed - boolean_t exact = true; - - CFDictionaryRef properties = CGDisplayBestModeForParameters([AppController primaryScreen], mode.BitsPerPixel, - mode.Width, mode.Height, &exact); - - if (!properties) { - std::cerr << "Unable to get a display mode with the given parameters" << std::endl; - [self autorelease]; - return nil; - } - - if (exact == false) { - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayWidth), - kCFNumberIntType, &mode.Width); - - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayHeight), - kCFNumberIntType, &mode.Height); - - CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, kCGDisplayBitsPerPixel), - kCFNumberIntType, &mode.BitsPerPixel); - - } - } - - // We grab options from WindowStyle and add them to our window mask - if (style & sf::Style::None || style & sf::Style::Fullscreen) { - mask |= NSBorderlessWindowMask; - - - - } else { - if (style & sf::Style::Titlebar) { - mask |= NSTitledWindowMask; - mask |= NSMiniaturizableWindowMask; - } - - if (style & sf::Style::Resize) { - mask |= NSTitledWindowMask; - mask |= NSMiniaturizableWindowMask; - mask |= NSResizableWindowMask; - } - - if (style & sf::Style::Close) { - mask |= NSTitledWindowMask; - mask |= NSClosableWindowMask; - mask |= NSMiniaturizableWindowMask; - } - } - - // Now we make the window with the values we got - // Note: defer flag set to NO to be able to use OpenGL in our window - myWindow = [[NSWindow alloc] initWithContentRect:frame - styleMask:mask - backing:NSBackingStoreBuffered - defer:NO]; - - if (myWindow) { - // We set title and window position - [myWindow setTitle:title]; - [myWindow center]; - } else { - std::cerr << "Unable to create the Cocoa window" << std::endl; - [self autorelease]; - return nil; - } - } - - // Make the OpenGL view - myView = [[GLView alloc] initWithFrame:[[myWindow contentView] frame] - mode:mode - settings:params - delegate:delegate]; - - if (myView) { - // Finish setting up the view and window - // Add the view to our window and tell it to the view - [[myWindow contentView] addSubview:myView]; - [myView finishInitialization]; - - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - - // We want to know when our window got the focus - [nc addObserver:self - selector:@selector(windowDidBecomeMain:) - name:NSWindowDidBecomeMainNotification - object:myWindow]; - - // We want to know when our window lost the focus - [nc addObserver:self - selector:@selector(windowDidResignMain:) - name:NSWindowDidResignMainNotification - object:myWindow]; - - // We want to know when the user closes the window - [nc addObserver:self - selector:@selector(windowWillClose:) - name:NSWindowWillCloseNotification - object:myWindow]; - - // I want to re-center the window if it's a full screen one and moved by Spaces - [nc addObserver:self - selector:@selector(windowDidMove:) - name:NSWindowDidMoveNotification - object:myWindow]; - - // Needed not to make application crash when releasing the window in our destructor - // (I prefer to take control of everything :P) - [myWindow setReleasedWhenClosed:NO]; - [myWindow setAcceptsMouseMovedEvents:YES]; - - } else { - std::cerr << "Unable to create the OpenGL view" << std::endl; - [self autorelease]; - return nil; - } - - if (myIsFullscreen) { - myFullscreenMode = mode; - - // Using this because full screen window was not always - // in front of the other application windows when unhiding app - [myWindow setLevel:NSFloatingWindowLevel]; - } - } - - return self; -} - - -//////////////////////////////////////////////////////////// -/// Clean the window wrapper -//////////////////////////////////////////////////////////// - (void)dealloc { NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init]; @@ -656,93 +491,173 @@ [self show:false]; // Release the window and view - [myView removeFromSuperviewWithoutNeedingDisplay]; + [[self view] removeFromSuperviewWithoutNeedingDisplay]; - [myView release]; - [myWindow release]; + [self setWindow:nil]; + [self setView:nil]; + [self setDelegate:nil]; [super dealloc]; [localPool release]; } +//////////////////////////////////////////////////////////// +/// Registers a reference to the internal Cocoa window +//////////////////////////////////////////////////////////// +- (void)setWindow:(NSWindow *)aWindow +{ + if (myWindow != aWindow) + { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + + // Drop the observers on the previously set window + if ([self window]) { + [nc removeObserver:self + name:NSWindowDidBecomeMainNotification + object:[self window]]; + [nc removeObserver:self + name:NSWindowDidResignMainNotification + object:[self window]]; + [nc removeObserver:self + name:NSWindowWillCloseNotification + object:[self window]]; + } + + [myWindow release]; + myWindow = [aWindow retain]; + + // Set the new observers + // We want to know when our window got the focus + [nc addObserver:self + selector:@selector(windowDidBecomeMain:) + name:NSWindowDidBecomeMainNotification + object:[self window]]; + + // We want to know when our window lost the focus + [nc addObserver:self + selector:@selector(windowDidResignMain:) + name:NSWindowDidResignMainNotification + object:[self window]]; + + // We want to know when the user closes the window + [nc addObserver:self + selector:@selector(windowWillClose:) + name:NSWindowWillCloseNotification + object:[self window]]; + + } +} //////////////////////////////////////////////////////////// /// Return a reference to the internal Cocoa window //////////////////////////////////////////////////////////// - (NSWindow *)window { - return myWindow; + return [[myWindow retain] autorelease]; } +//////////////////////////////////////////////////////////// +/// Registers the the OpenGL view and adds it to its parent container +//////////////////////////////////////////////////////////// +- (void)putOpenGLView:(sfPrivGLView *)aView +{ + [self setView:aView]; + + // Finish setting up the view and window + // Add the view to our window and tell it to the view + [[[self window] contentView] addSubview:[self view]]; + [[self view] finishInitialization]; +} + +//////////////////////////////////////////////////////////// +/// Registers a reference to the internal Cocoa OpenGL view +//////////////////////////////////////////////////////////// +- (void)setView:(sfPrivGLView *)aView +{ + if (myView != aView) + { + [myView release]; + myView = [aView retain]; + } +} + //////////////////////////////////////////////////////////// /// Return a reference to the internal Cocoa OpenGL view //////////////////////////////////////////////////////////// -- (GLView *)glView +- (sfPrivGLView *)view { - return myView; + return [[myView retain] autorelease]; } +//////////////////////////////////////////////////////////// +/// Sets @aDelegate as the window delegate +//////////////////////////////////////////////////////////// +- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate +{ + [[self view] setDelegate:aDelegate]; +} + +//////////////////////////////////////////////////////////// +/// Returns the window delegate +//////////////////////////////////////////////////////////// +- (sf::priv::WindowImplCocoa *)delegate +{ + return [[self view] delegate]; +} //////////////////////////////////////////////////////////// /// Forward call to set the window position on screen //////////////////////////////////////////////////////////// - (void)setPosition:(NSPoint)pos { - assert(myWindow != nil); + NSAssert([self window] != nil, @"expected valid window"); - if (!myIsFullscreen) { - // Flip Y and set window position - pos.y = [[myWindow screen] frame].size.height - pos.y; - [myWindow setFrameTopLeftPoint:pos]; - } + // Flip Y and set window position + pos.y = [[[self window] screen] frame].size.height - pos.y; + [[self window] setFrameTopLeftPoint:pos]; } - //////////////////////////////////////////////////////////// /// Forward call to set the window size //////////////////////////////////////////////////////////// - (void)setSize:(NSSize)size { - assert(myWindow != nil); + NSAssert([self window] != nil, @"expected valid window"); - if (!myIsFullscreen) { - [myWindow setFrame:NSMakeRect([myWindow frame].origin.x, - [myWindow frame].origin.y, - size.width, size.height) - display:YES]; - } + [[self window] setFrame:NSMakeRect([[self window] frame].origin.x, + [[self window] frame].origin.y, + size.width, size.height) + display:YES]; } - //////////////////////////////////////////////////////////// /// Return the mouse location relative to the internal window //////////////////////////////////////////////////////////// - (NSPoint)mouseLocation { - assert(myWindow != nil); + NSAssert([self window] != nil, @"expected valid window"); - NSPoint relativeLocation = [myWindow convertScreenToBase:[NSEvent mouseLocation]]; - relativeLocation.y = [[self glView] frame].size.height - relativeLocation.y; + NSPoint relativeLocation = [[self window] convertScreenToBase:[NSEvent mouseLocation]]; + relativeLocation.y = [[self view] frame].size.height - relativeLocation.y; return relativeLocation; } - //////////////////////////////////////////////////////////// /// Return whether the mouse is on our window //////////////////////////////////////////////////////////// - (BOOL)mouseInside { - assert(myWindow != nil); - assert(myView != nil); + NSAssert([self window] != nil, @"expected valid window"); + NSAssert([self view] != nil, @"expected valid OpenGL view"); BOOL flag = NO; - if ([myWindow isVisible]) { - NSPoint relativeToWindow = [myWindow mouseLocationOutsideOfEventStream]; - NSPoint relativeToView = [myView convertPoint:relativeToWindow fromView:nil]; + if ([[self window] isVisible]) { + NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream]; + NSPoint relativeToView = [[self view] convertPoint:relativeToWindow fromView:nil]; - if (NSPointInRect (relativeToView, [myView bounds])) + if (NSPointInRect (relativeToView, [[self view] bounds])) { flag = YES; } @@ -751,32 +666,23 @@ return flag; } - //////////////////////////////////////////////////////////// /// Close or open the window //////////////////////////////////////////////////////////// - (void)show:(bool)flag { - assert(myWindow != nil); + NSAssert([self window] != nil, @"expected valid window"); - if (flag && ![myWindow isVisible]) { + if (flag && ![[self window] isVisible]) { // Wanna open the closed window - if (myIsFullscreen) { - [[AppController sharedController] setFullscreenWindow:self mode:&myFullscreenMode]; - } else { - // Show the window - [myWindow makeKeyAndOrderFront:nil]; - } - } else if (!flag && [myWindow isVisible]) { + // Show the window + [[self window] makeKeyAndOrderFront:nil]; + } else if (!flag && [[self window] isVisible]) { // Wanna close the opened window - if (myIsFullscreen) { - [[AppController sharedController] setFullscreenWindow:nil mode:NULL]; - } else { - // Close the window - [myWindow close]; - } + // Close the window + [[self window] close]; } } @@ -786,31 +692,28 @@ //////////////////////////////////////////////////////////// - (void)enableVerticalSync:(bool)flag { - assert(myView != nil); - [myView enableVerticalSync:flag]; + NSAssert([self view] != nil, @"expected valid OpenGL view"); + [[self view] enableVerticalSync:flag]; } - //////////////////////////////////////////////////////////// /// Forward 'setActive' call the the OpenGL view //////////////////////////////////////////////////////////// - (void)setActive:(bool)flag { - assert(myView != nil); - [myView setActive:flag]; + NSAssert([self view] != nil, @"expected valid OpenGL view"); + [[self view] setActive:flag]; } - //////////////////////////////////////////////////////////// /// Forward call to flush the OpenGL view //////////////////////////////////////////////////////////// - (void)flushBuffer { - assert(myView != nil); - [myView flushBuffer]; + NSAssert([self view] != nil, @"expected valid OpenGL view"); + [[self view] flushBuffer]; } - //////////////////////////////////////////////////////////// /// Notification method receiver when the window gains focus //////////////////////////////////////////////////////////// @@ -819,7 +722,7 @@ sf::Event ev; ev.Type = sf::Event::GainedFocus; - [myView pushEvent:ev]; + [[self view] pushEvent:ev]; } @@ -831,7 +734,7 @@ sf::Event ev; ev.Type = sf::Event::LostFocus; - [myView pushEvent:ev]; + [[self view] pushEvent:ev]; } @@ -843,10 +746,171 @@ sf::Event ev; ev.Type = sf::Event::Closed; - [myView pushEvent:ev]; + [[self view] pushEvent:ev]; } +@end + + +@implementation sfPrivOwnedWindow + +- (id)initWithVideoMode:(sf::VideoMode&)aMode + settings:(sf::WindowSettings&)someSettings + style:(unsigned long)aStyle + title:(NSString *)aTitle +{ + self = [super init]; + if (self) + { + if (aStyle & sf::Style::Fullscreen) { + [self setFullscreen:YES]; + } + + NSRect frame = NSMakeRect (0.0f, 0.0f, (float) aMode.Width, (float) aMode.Height); + unsigned int mask = 0; + + if (aStyle & sf::Style::Fullscreen) { + // Check display mode and put new values in 'mode' if needed + boolean_t exact = true; + + CFDictionaryRef properties = + CGDisplayBestModeForParameters([sfPrivAppController primaryScreen], + aMode.BitsPerPixel, + aMode.Width, + aMode.Height, + &exact); + + if (!properties) { + std::cerr + << "Unable to get a display mode with the given parameters" + << std::endl; + + [self autorelease]; + return nil; + } + + if (exact == false) { + CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, + kCGDisplayWidth), + kCFNumberIntType, &aMode.Width); + + CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, + kCGDisplayHeight), + kCFNumberIntType, &aMode.Height); + + CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, + kCGDisplayBitsPerPixel), + kCFNumberIntType, &aMode.BitsPerPixel); + + } + } + + // We grab options from WindowStyle and add them to our window mask + if (aStyle & sf::Style::None || aStyle & sf::Style::Fullscreen) { + mask |= NSBorderlessWindowMask; + } else { + if (aStyle & sf::Style::Titlebar) { + mask |= NSTitledWindowMask; + mask |= NSMiniaturizableWindowMask; + } + + if (aStyle & sf::Style::Resize) { + mask |= NSTitledWindowMask; + mask |= NSMiniaturizableWindowMask; + mask |= NSResizableWindowMask; + } + + if (aStyle & sf::Style::Close) { + mask |= NSTitledWindowMask; + mask |= NSClosableWindowMask; + mask |= NSMiniaturizableWindowMask; + } + } + + // Now we make the window with the values we got + // Note: defer flag set to NO to be able to use OpenGL in our window + NSWindow *newWindow = [[NSWindow alloc] + initWithContentRect:frame + styleMask:mask + backing:NSBackingStoreBuffered + defer:NO]; + + if (newWindow) { + [self setWindow:[newWindow autorelease]]; + } else { + std::cerr << "Unable to create the Cocoa window" << std::endl; + [self autorelease]; + return nil; + } + + // We set title and window position + [[self window] setTitle:aTitle != nil ? aTitle : @""]; + [[self window] center]; + + // Make the OpenGL view + sfPrivGLView *newView = [[sfPrivGLView alloc] + initWithFrame:[[[self window] contentView] frame] + mode:aMode + settings:someSettings]; + + if (!newView) { + std::cerr << "Unable to create the OpenGL view" << std::endl; + [self autorelease]; + return nil; + } + + // Put our view in the window + [self putOpenGLView:[newView autorelease]]; + + // I want to re-center the window if it's a full screen one and moved by Spaces + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(windowDidMove:) + name:NSWindowDidMoveNotification + object:[self window]]; + + // Needed not to make application crash when releasing the window in our destructor + // (I prefer to take control of everything :P) + [[self window] setReleasedWhenClosed:NO]; + [[self window] setAcceptsMouseMovedEvents:YES]; + + if ([self isFullscreen]) { + myFullscreenMode = aMode; + + // Using this because full screen window was not always + // in front of the other application windows when unhiding app + [[self window] setLevel:NSFloatingWindowLevel]; + } + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSWindowDidMoveNotification + object:[self window]]; + [super dealloc]; +} + +//////////////////////////////////////////////////////////// +/// Sets the window's fullscreen state +//////////////////////////////////////////////////////////// +- (void)setFullscreen:(BOOL)aFlag +{ + myIsFullscreen = aFlag; +} + +//////////////////////////////////////////////////////////// +/// Returns the window's fullscreen state +//////////////////////////////////////////////////////////// +- (BOOL)isFullscreen +{ + return myIsFullscreen; +} + //////////////////////////////////////////////////////////// /// Notification method receiver when the window finish moving //////////////////////////////////////////////////////////// @@ -858,5 +922,176 @@ [sender center]; } +//////////////////////////////////////////////////////////// +/// Close or open the window +//////////////////////////////////////////////////////////// +- (void)show:(bool)flag +{ + NSAssert([self window] != nil, @"expected valid window"); + + if (flag && ![[self window] isVisible]) { + // Wanna open the closed window + + if ([self isFullscreen]) { + [[sfPrivAppController sharedController] + setFullscreenWindow:self + mode:&myFullscreenMode]; + } else { + // Show the window + [[self window] makeKeyAndOrderFront:nil]; + } + } else if (!flag && [[self window] isVisible]) { + // Wanna close the opened window + + if ([self isFullscreen]) { + [[sfPrivAppController sharedController] + setFullscreenWindow:nil + mode:NULL]; + } else { + // Close the window + [[self window] close]; + } + } +} + +//////////////////////////////////////////////////////////// +/// Forward call to set the window position on screen +//////////////////////////////////////////////////////////// +- (void)setPosition:(NSPoint)aPosition +{ + if (![self isFullscreen]) { + [super setPosition:aPosition]; + } +} + +//////////////////////////////////////////////////////////// +/// Forward call to set the window size +//////////////////////////////////////////////////////////// +- (void)setSize:(NSSize)size +{ + if (![self isFullscreen]) { + [super setSize:size]; + } +} + +@end + + +@implementation sfPrivImportedWindow + +- (id)initWithWindow:(NSWindow *)aWindow + settings:(sf::WindowSettings&)someSettings +{ + self = [super init]; + + if (self) { + [self setWindow:aWindow]; + + // Make the OpenGL view + sf::VideoMode mode([[[self window] contentView] frame].size.width, + [[[self window] contentView] frame].size.height); + sfPrivGLView *newView = [[sfPrivGLView alloc] + initWithFrame:[[[self window] contentView] frame] + mode:mode + settings:someSettings]; + + if (!newView) { + std::cerr << "Unable to create the OpenGL view" << std::endl; + [self autorelease]; + return nil; + } + + [self putOpenGLView:[newView autorelease]]; + } + + return self; +} + +@end + + +@implementation sfPrivImportedView + + +- (id)initWithView:(NSView *)aView + settings:(sf::WindowSettings&)someSettings +{ + self = [super init]; + if (self) + { + parentView = [aView retain]; + [self setWindow:[parentView window]]; + + // Make the OpenGL view + sf::VideoMode mode([parentView bounds].size.width, + [parentView bounds].size.height); + sfPrivGLView *newView = [[sfPrivGLView alloc] + initWithFrame:[parentView bounds] + mode:mode + settings:someSettings]; + + if (!newView) { + std::cerr << "Unable to create the OpenGL view" << std::endl; + [self autorelease]; + return nil; + } + + [self putOpenGLView:[newView autorelease]]; + + } + return self; +} + +- (void)dealloc +{ + [parentView release]; + [super dealloc]; +} + +//////////////////////////////////////////////////////////// +/// Registers the the OpenGL view and adds it to its parent container +//////////////////////////////////////////////////////////// +- (void)putOpenGLView:(sfPrivGLView *)aView +{ + [self setView:aView]; + + // Finish setting up the view and window + NSRect originalFrame = [[self window] frame]; + NSRect tmpFrame = originalFrame; + originalFrame.origin.x++; + + [[self window] setFrame:tmpFrame display:YES]; + [[self window] setFrame:originalFrame display:YES]; + + + // Add the view to our *parent view* and tell it to the view + [parentView addSubview:[self view]]; + [[self view] finishInitialization]; +} + +//////////////////////////////////////////////////////////// +/// Forward call to set the window position on screen +//////////////////////////////////////////////////////////// +- (void)setPosition:(NSPoint)aPosition +{ + std::cerr + << "Warning: called Window::SetPosition() on a window imported from a widget. " + << "This method has been disabled in this case and has no effect. " + << "Directly use the widget if you want to move it." + << std::endl; +} + +//////////////////////////////////////////////////////////// +/// Forward call to set the window size +//////////////////////////////////////////////////////////// +- (void)setSize:(NSSize)size +{ + std::cerr + << "Warning: called Window::SetSize() on a window imported from a widget. " + << "This method has been disabled in this case and has no effect. " + << "Directly use the widget if you want to resize it." + << std::endl; +} + @end diff --git a/src/SFML/Window/Cocoa/WindowImplCocoa.hpp b/src/SFML/Window/Cocoa/WindowImplCocoa.hpp index 25bef322..62158f0f 100644 --- a/src/SFML/Window/Cocoa/WindowImplCocoa.hpp +++ b/src/SFML/Window/Cocoa/WindowImplCocoa.hpp @@ -33,10 +33,10 @@ #include #ifdef __OBJC__ -@class WindowWrapper; -typedef WindowWrapper* WindowWrapperRef; +@class sfPrivWindow; +typedef sfPrivWindow* sfPrivWindowRef; #else -typedef void* WindowWrapperRef; +typedef void* sfPrivWindowRef; #endif namespace sf @@ -192,7 +192,7 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - WindowWrapperRef myWrapper; + sfPrivWindowRef myWrapper; bool myUseKeyRepeat; bool myMouseIn; float myWheelStatus; diff --git a/src/SFML/Window/Cocoa/WindowImplCocoa.mm b/src/SFML/Window/Cocoa/WindowImplCocoa.mm index b1fe2204..13dec839 100644 --- a/src/SFML/Window/Cocoa/WindowImplCocoa.mm +++ b/src/SFML/Window/Cocoa/WindowImplCocoa.mm @@ -67,10 +67,10 @@ myUseKeyRepeat(false), myMouseIn(false), myWheelStatus(0.0f) { - [AppController sharedController]; + [sfPrivAppController sharedController]; // Create the shared OpenGL context - if ([GLContext sharedContext]) { + if ([sfPrivGLContext sharedContext]) { // Then we make it the current active OpenGL context SetActive(); } else { @@ -88,22 +88,19 @@ myUseKeyRepeat(false), myMouseIn(false), myWheelStatus(0.0f) { - if (Handle) - { - NSWindow *cocoaWindow = nil; - + if (Handle) { // Classical window import - if ([(id)Handle isKindOfClass:[NSWindow class]]) - { - cocoaWindow = (NSWindow *)Handle; + if ([(id)Handle isKindOfClass:[NSWindow class]]) { + myWrapper = [[sfPrivImportedWindow alloc] + initWithWindow:(NSWindow *)Handle + settings:params]; } // Qt "window" import - else if ([(id)Handle isKindOfClass:[NSView class]]) - { - cocoaWindow = [(NSView *)Handle window]; - } - else - { + else if ([(id)Handle isKindOfClass:[NSView class]]) { + myWrapper = [[sfPrivImportedView alloc] + initWithView:(NSView *)Handle + settings:params]; + } else { std::cerr << "Cannot import this Window Handle because it is neither" << "a nor object" @@ -114,36 +111,23 @@ myWheelStatus(0.0f) } - if (cocoaWindow) - { + if (myWrapper) { + [myWrapper setDelegate:this]; - // We create the window according to the given handle - myWrapper = [[WindowWrapper alloc] initWithWindow:cocoaWindow - settings:params - delegate:this]; + // initial mouse state + myMouseIn = [myWrapper mouseInside]; - if (myWrapper) - { - // initial mouse state - myMouseIn = [myWrapper mouseInside]; - - // We set the myWidth and myHeight members to the correct values - myWidth = (int) [[myWrapper glView] frame].size.width; - myHeight = (int) [[myWrapper glView] frame].size.height; - } else { - std::cerr << "Failed to make the public window" << std::endl; - } + // We set the myWidth and myHeight members to the correct values + myWidth = (int) [[myWrapper view] frame].size.width; + myHeight = (int) [[myWrapper view] frame].size.height; + } else { + std::cerr << "Failed to make the public window" << std::endl; } - else - { - std::cerr - << "Could not get a valid NSWindow object from the given handle" - << " (%p <" - << [[(id)Handle className] UTF8String] - << ">" - << std::endl; - } - + } else { + std::cerr + << "Invalid null handle given to " + << "Window::Window(WindowHandle Handle, const WindowSettings& Params)" + << std::endl; } } @@ -163,14 +147,18 @@ myWheelStatus(0.0f) encoding:NSASCIIStringEncoding]; // We create the window - myWrapper = [[WindowWrapper alloc] initWithSettings:params - videoMode:Mode - style:WindowStyle - title:title - delegate:this]; + myWrapper = [[sfPrivOwnedWindow alloc] + initWithVideoMode:Mode + settings:params + style:WindowStyle + title:title]; + + if (myWrapper) { + [myWrapper setDelegate:this]; + // initial mouse state myMouseIn = [myWrapper mouseInside]; @@ -566,7 +554,7 @@ void WindowImplCocoa::Display() void WindowImplCocoa::ProcessEvents() { // Forward event handling call to the application controller - [[AppController sharedController] processEvents]; + [[sfPrivAppController sharedController] processEvents]; } @@ -581,10 +569,10 @@ void WindowImplCocoa::SetActive(bool Active) const else { // Or directly activate the shared OpenGL context if we're not using a window if (Active) { - if ([NSOpenGLContext currentContext] != [GLContext sharedContext]) - [[GLContext sharedContext] makeCurrentContext]; + if ([NSOpenGLContext currentContext] != [sfPrivGLContext sharedContext]) + [[sfPrivGLContext sharedContext] makeCurrentContext]; } else { - if ([NSOpenGLContext currentContext] == [GLContext sharedContext]) + if ([NSOpenGLContext currentContext] == [sfPrivGLContext sharedContext]) [NSOpenGLContext clearCurrentContext]; } } @@ -626,7 +614,7 @@ void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top) pos.y = [[myWrapper window] frame].size.height - pos.y; // Adjust for view reference instead of window - pos.y -= [[myWrapper window] frame].size.height - [[myWrapper glView] frame].size.height; + pos.y -= [[myWrapper window] frame].size.height - [[myWrapper view] frame].size.height; // Convert to screen coordinates NSPoint absolute = [[myWrapper window] convertBaseToScreen:pos]; @@ -635,7 +623,8 @@ void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top) absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y; // Move cursor - CGDisplayMoveCursorToPoint([AppController primaryScreen], CGPointMake(absolute.x, absolute.y)); + CGDisplayMoveCursorToPoint([sfPrivAppController primaryScreen], + CGPointMake(absolute.x, absolute.y)); } } diff --git a/src/SFML/Window/Win32/ContextWGL.cpp b/src/SFML/Window/Win32/ContextWGL.cpp index d7e9e7b0..d1c0422c 100644 --- a/src/SFML/Window/Win32/ContextWGL.cpp +++ b/src/SFML/Window/Win32/ContextWGL.cpp @@ -224,6 +224,7 @@ void ContextWGL::CreateContext(ContextWGL* shared, unsigned int bitsPerPixel, co descriptor.cColorBits = static_cast(bitsPerPixel); descriptor.cDepthBits = static_cast(mySettings.DepthBits); descriptor.cStencilBits = static_cast(mySettings.StencilBits); + descriptor.cAlphaBits = bitsPerPixel == 32 ? 8 : 0; // Get the pixel format that best matches our requirements bestFormat = ChoosePixelFormat(myDeviceContext, &descriptor); diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp index b16eee31..fec89b64 100644 --- a/src/SFML/Window/Win32/WindowImplWin32.cpp +++ b/src/SFML/Window/Win32/WindowImplWin32.cpp @@ -367,14 +367,14 @@ void WindowImplWin32::SwitchToFullscreen(const VideoMode& mode) return; } - // Resize the window so that it fits the entire screen - SetWindowPos(myHandle, HWND_TOP, 0, 0, mode.Width, mode.Height, SWP_FRAMECHANGED); - ShowWindow(myHandle, SW_SHOW); - // Make the window flags compatible with fullscreen mode SetWindowLong(myHandle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); SetWindowLong(myHandle, GWL_EXSTYLE, WS_EX_APPWINDOW); + // Resize the window so that it fits the entire screen + SetWindowPos(myHandle, HWND_TOP, 0, 0, mode.Width, mode.Height, SWP_FRAMECHANGED); + ShowWindow(myHandle, SW_SHOW); + // Set "this" as the current fullscreen window FullscreenWindow = this; }