diff --git a/doc/doxyfile.in b/doc/doxyfile.in index f8be2c411..9a44a6aa6 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -2377,3 +2377,21 @@ GENERATE_LEGEND = YES # This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# SFML specific aliases +#--------------------------------------------------------------------------- + +# sfplatform{platform(s)} +# sfplatform{platform(s), header} +# +# Warns the user that some specific class or function is only available on +# specific platforms. +# +# This shouldn't be used for incomplete implementations. It's meant for things +# that will never appear on another platform, e.g. Android's native activity. +# +# If a header is given, the user is informed, that this header must be included +# for the mentioned element to be defined. +ALIASES += sfplatform{1}="
Platform Limitation
This is only available on \1.
" +ALIASES += sfplatform{2}="
Platform Limitation
This is only available on \1 and to use it, you'll have to specifically include \2 in your code.
" diff --git a/examples/android/AndroidManifest.xml b/examples/android/AndroidManifest.xml index beb3538db..edee84f45 100644 --- a/examples/android/AndroidManifest.xml +++ b/examples/android/AndroidManifest.xml @@ -10,6 +10,8 @@ + + #include +// Do we want to showcase direct JNI/NDK interaction? +// Undefine this to get real cross-platform code. +#define USE_JNI +#if defined(USE_JNI) +// These headers are only needed for direct NDK/JDK interaction +#include +#include + +// Since we want to get the native activity from SFML, we'll have to use an +// extra header here: +#include + +// NDK/JNI sub example - call Java code from native code +int vibrate(sf::Time duration) +{ + // First we'll need the native activity handle + ANativeActivity *activity = sf::getNativeActivity(); + + // Retrieve the JVM and JNI environment + JavaVM* vm = activity->vm; + JNIEnv* env = activity->env; + + // First, attach this thread to the main thread + JavaVMAttachArgs attachargs; + attachargs.version = JNI_VERSION_1_6; + attachargs.name = "NativeThread"; + attachargs.group = NULL; + jint res = vm->AttachCurrentThread(&env, &attachargs); + + if (res == JNI_ERR) + return EXIT_FAILURE; + + // Retrieve class information + jclass natact = env->FindClass("android/app/NativeActivity"); + jclass context = env->FindClass("android/content/Context"); + + // Get the value of a constant + jfieldID fid = env->GetStaticFieldID(context, "VIBRATOR_SERVICE", "Ljava/lang/String;"); + jobject svcstr = env->GetStaticObjectField(context, fid); + + // Get the method 'getSystemService' and call it + jmethodID getss = env->GetMethodID(natact, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); + jobject vib_obj = env->CallObjectMethod(activity->clazz, getss, svcstr); + + // Get the object's class and retrieve the member name + jclass vib_cls = env->GetObjectClass(vib_obj); + jmethodID vibrate = env->GetMethodID(vib_cls, "vibrate", "(J)V"); + + // Determine the timeframe + jlong length = duration.asMilliseconds(); + + // Bzzz! + env->CallVoidMethod(vib_obj, vibrate, length); + + // Free references + env->DeleteLocalRef(vib_obj); + env->DeleteLocalRef(vib_cls); + env->DeleteLocalRef(svcstr); + env->DeleteLocalRef(context); + env->DeleteLocalRef(natact); + + // Detach thread again + vm->DetachCurrentThread(); +} +#endif + +// This is the actual Android example. You don't have to write any platform +// specific code, unless you want to use things not directly exposed. +// ('vibrate()' in this example; undefine 'USE_JNI' above to disable it) int main(int argc, char *argv[]) { sf::RenderWindow window(sf::VideoMode::getDesktopMode(), ""); @@ -31,23 +100,26 @@ int main(int argc, char *argv[]) while (window.pollEvent(event)) { - if (event.type == sf::Event::Closed) + switch (event.type) { - window.close(); + case sf::Event::Closed: + window.close(); + break; + case sf::Event::Resized: + view.setSize(event.size.width, event.size.height); + view.setCenter(event.size.width/2, event.size.height/2); + window.setView(view); + break; + case sf::Event::TouchBegan: + if (event.touch.finger == 0) + { + image.setPosition(event.touch.x, event.touch.y); +#if defined(USE_JNI) + vibrate(sf::milliseconds(10)); +#endif + } + break; } - - if (event.type == sf::Event::Resized) - { - view.setSize(event.size.width, event.size.height); - view.setCenter(event.size.width/2, event.size.height/2); - window.setView(view); - } - } - - if (sf::Touch::isDown(0)) - { - sf::Vector2i position = sf::Touch::getPosition(0); - image.setPosition(position.x, position.y); } window.clear(sf::Color::White); diff --git a/include/SFML/System/NativeActivity.hpp b/include/SFML/System/NativeActivity.hpp new file mode 100644 index 000000000..06d0a0821 --- /dev/null +++ b/include/SFML/System/NativeActivity.hpp @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_NATIVEACTIVITY_HPP +#define SFML_NATIVEACTIVITY_HPP + + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + + +#if !defined(SFML_SYSTEM_ANDROID) +#error NativeActivity.hpp: This header is Android only. +#endif + + +struct ANativeActivity; + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// \ingroup system +/// \brief Return a pointer to the Android native activity +/// +/// You shouldn't have to use this function, unless you want +/// to implement very specific details, that SFML doesn't +/// support, or to use a workaround for a known issue. +/// +/// \return Pointer to Android native activity structure +/// +/// \sfplatform{Android,SFML/System/NativeActivity.hpp} +/// +//////////////////////////////////////////////////////////// +SFML_SYSTEM_API ANativeActivity* getNativeActivity(); + +} // namespace sf + + +#endif // SFML_NATIVEACTIVITY_HPP diff --git a/src/SFML/System/Android/NativeActivity.cpp b/src/SFML/System/Android/NativeActivity.cpp new file mode 100644 index 000000000..cf4f8085b --- /dev/null +++ b/src/SFML/System/Android/NativeActivity.cpp @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + +namespace sf +{ +//////////////////////////////////////////////////////////// +ANativeActivity* getNativeActivity() +{ + return priv::getActivity()->activity; +} + +} // namespace sf diff --git a/src/SFML/System/CMakeLists.txt b/src/SFML/System/CMakeLists.txt index 48629f4e0..54da9a07c 100644 --- a/src/SFML/System/CMakeLists.txt +++ b/src/SFML/System/CMakeLists.txt @@ -14,6 +14,7 @@ set(SRC ${INCROOT}/Lock.hpp ${SRCROOT}/Mutex.cpp ${INCROOT}/Mutex.hpp + ${INCROOT}/NativeActivity.hpp ${INCROOT}/NonCopyable.hpp ${SRCROOT}/Sleep.cpp ${INCROOT}/Sleep.hpp @@ -75,6 +76,7 @@ else() set(PLATFORM_SRC ${PLATFORM_SRC} ${SRCROOT}/Android/Activity.hpp ${SRCROOT}/Android/Activity.cpp + ${SRCROOT}/Android/NativeActivity.cpp ${SRCROOT}/Android/ResourceStream.cpp ${SRCROOT}/Android/ResourceStream.cpp )