summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Cowgill <james410@cowgill.org.uk>2015-07-04 22:12:39 +0100
committerJames Cowgill <james410@cowgill.org.uk>2015-07-04 22:12:39 +0100
commit0359b3872b8692245372ac16113c2d5b01ae1f73 (patch)
tree3d87055917a47677e439bf94baddcd340ba77aa9
parentdb2817654da26ed2d4844e65d3a4000f39efcfe2 (diff)
parent232f6c9906817eee494907d7bbe8ddf2dacf8fbf (diff)
Merge tag 'upstream/2.3.1+dfsg'
Upstream version 2.3.1+dfsg # gpg: Signature made Sat 04 Jul 2015 22:12:34 BST using RSA key ID EA2D01EF # gpg: Good signature from "James Cowgill <james410@cowgill.org.uk>" # gpg: aka "James Cowgill <jc1311@york.ac.uk>" # gpg: aka "James Cowgill (Imagination Technologies) <James.Cowgill@imgtec.com>"
-rw-r--r--CMakeLists.txt2
-rw-r--r--changelog.txt36
-rw-r--r--include/SFML/Audio/Music.hpp24
-rw-r--r--include/SFML/Audio/SoundRecorder.hpp4
-rw-r--r--include/SFML/Config.hpp2
-rw-r--r--include/SFML/Graphics/Font.hpp16
-rw-r--r--include/SFML/Graphics/RenderStates.hpp2
-rw-r--r--include/SFML/Graphics/Shader.hpp2
-rw-r--r--include/SFML/Graphics/Texture.hpp2
-rw-r--r--include/SFML/System/FileInputStream.hpp2
-rw-r--r--include/SFML/Window/Joystick.hpp2
-rw-r--r--src/SFML/Audio/InputSoundFile.cpp9
-rw-r--r--src/SFML/Audio/OutputSoundFile.cpp4
-rw-r--r--src/SFML/Audio/SoundFileFactory.cpp9
-rw-r--r--src/SFML/Audio/SoundRecorder.cpp4
-rw-r--r--src/SFML/Graphics/GLExtensions.hpp4
-rw-r--r--src/SFML/Graphics/GLExtensions.txt1
-rw-r--r--src/SFML/Graphics/GLLoader.cpp7
-rw-r--r--src/SFML/Graphics/GLLoader.hpp3
-rw-r--r--src/SFML/Graphics/Shader.cpp4
-rw-r--r--src/SFML/Graphics/Shape.cpp2
-rw-r--r--src/SFML/Graphics/Texture.cpp16
-rw-r--r--src/SFML/Main/MainAndroid.cpp71
-rw-r--r--src/SFML/Network/TcpSocket.cpp2
-rw-r--r--src/SFML/System/Android/ResourceStream.cpp2
-rw-r--r--src/SFML/System/FileInputStream.cpp7
-rw-r--r--src/SFML/Window/Android/InputImpl.cpp10
-rw-r--r--src/SFML/Window/Android/WindowImplAndroid.cpp73
-rw-r--r--src/SFML/Window/Android/WindowImplAndroid.hpp8
-rw-r--r--src/SFML/Window/Unix/Display.cpp146
-rw-r--r--src/SFML/Window/Unix/Display.hpp8
-rw-r--r--src/SFML/Window/Unix/InputImpl.cpp216
-rw-r--r--src/SFML/Window/Unix/InputImpl.hpp6
-rw-r--r--src/SFML/Window/Unix/WindowImplX11.cpp112
34 files changed, 518 insertions, 300 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8ac15c3..ee11ead 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,7 +40,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake)
# setup version numbers
set(VERSION_MAJOR 2)
set(VERSION_MINOR 3)
-set(VERSION_PATCH 0)
+set(VERSION_PATCH 1)
# add the SFML header path
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
diff --git a/changelog.txt b/changelog.txt
index b4944c3..c6bd661 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,39 @@
+SFML 2.3.1
+==========
+
+Also available on the website: http://www.sfml-dev.org/changelog.php#sfml-2.3.1
+
+Window
+======
+
+Bugfixes
+--------
+* [Android] Make sure a window still exists before trying to access its dimensions (#854)
+* [Android] Added Android API level checks (#856)
+* [Android] Updated the JNI/event handling code (#906)
+* [Linux] Resized events are only spawned when the window size actually changes (#878, #893)
+* [Linux] Whitelisted X SHAPE events (#879, #883)
+* [Linux] Remap Unix keyboard when user changes layout (#895, #897)
+* [Linux] Fix undefined behavior in ewmhSupported() (#892, #901)
+
+
+Graphics
+========
+
+Bugfixes
+--------
+* Added support for GL_EXT_texture_edge_clamp for systems that don't expose GL_SGIS_texture_edge_clamp (#880, #882)
+
+
+Audio
+=====
+
+Bugfixes
+--------
+* [Android] Fixed audio files not loading (and possibly crashing) (#855, #887)
+
+
+
SFML 2.3
========
diff --git a/include/SFML/Audio/Music.hpp b/include/SFML/Audio/Music.hpp
index a502724..76b4254 100644
--- a/include/SFML/Audio/Music.hpp
+++ b/include/SFML/Audio/Music.hpp
@@ -69,6 +69,10 @@ public:
/// See the documentation of sf::InputSoundFile for the list
/// of supported formats.
///
+ /// \warning Since the music is not loaded at once but rather
+ /// streamed continuously, the file must remain accessible until
+ /// the sf::Music object loads a new music or is destroyed.
+ ///
/// \param filename Path of the music file to open
///
/// \return True if loading succeeded, false if it failed
@@ -85,10 +89,11 @@ public:
/// to do so).
/// See the documentation of sf::InputSoundFile for the list
/// of supported formats.
- /// Since the music is not loaded completely but rather streamed
- /// continuously, the \a data must remain available as long as the
- /// music is playing (i.e. you can't deallocate it right after calling
- /// this function).
+ ///
+ /// \warning Since the music is not loaded at once but rather streamed
+ /// continuously, the \a data buffer must remain accessible until
+ /// the sf::Music object loads a new music or is destroyed. That is,
+ /// you can't deallocate the buffer right after calling this function.
///
/// \param data Pointer to the file data in memory
/// \param sizeInBytes Size of the data to load, in bytes
@@ -107,10 +112,10 @@ public:
/// to do so).
/// See the documentation of sf::InputSoundFile for the list
/// of supported formats.
- /// Since the music is not loaded completely but rather streamed
- /// continuously, the \a stream must remain alive as long as the
- /// music is playing (i.e. you can't destroy it right after calling
- /// this function).
+ ///
+ /// \warning Since the music is not loaded at once but rather
+ /// streamed continuously, the \a stream must remain accessible
+ /// until the sf::Music object loads a new music or is destroyed.
///
/// \param stream Source stream to read from
///
@@ -184,6 +189,9 @@ private:
/// musics that usually take hundreds of MB when they are
/// uncompressed: by streaming it instead of loading it entirely,
/// you avoid saturating the memory and have almost no loading delay.
+/// This implies that the underlying resource (file, stream or
+/// memory buffer) must remain valid for the lifetime of the
+/// sf::Music object.
///
/// Apart from that, a sf::Music has almost the same features as
/// the sf::SoundBuffer / sf::Sound pair: you can play/pause/stop
diff --git a/include/SFML/Audio/SoundRecorder.hpp b/include/SFML/Audio/SoundRecorder.hpp
index ab0eb24..964e4f3 100644
--- a/include/SFML/Audio/SoundRecorder.hpp
+++ b/include/SFML/Audio/SoundRecorder.hpp
@@ -183,7 +183,7 @@ protected:
/// \param interval Processing interval
///
////////////////////////////////////////////////////////////
- void setProcessingInterval(sf::Time interval);
+ void setProcessingInterval(Time interval);
////////////////////////////////////////////////////////////
/// \brief Start capturing audio data
@@ -260,7 +260,7 @@ private:
Thread m_thread; ///< Thread running the background recording task
std::vector<Int16> m_samples; ///< Buffer to store captured samples
unsigned int m_sampleRate; ///< Sample rate
- sf::Time m_processingInterval; ///< Time period between calls to onProcessSamples
+ Time m_processingInterval; ///< Time period between calls to onProcessSamples
bool m_isCapturing; ///< Capturing state
std::string m_deviceName; ///< Name of the audio capture device
};
diff --git a/include/SFML/Config.hpp b/include/SFML/Config.hpp
index 58e9797..294f282 100644
--- a/include/SFML/Config.hpp
+++ b/include/SFML/Config.hpp
@@ -31,7 +31,7 @@
////////////////////////////////////////////////////////////
#define SFML_VERSION_MAJOR 2
#define SFML_VERSION_MINOR 3
-#define SFML_VERSION_PATCH 0
+#define SFML_VERSION_PATCH 1
////////////////////////////////////////////////////////////
diff --git a/include/SFML/Graphics/Font.hpp b/include/SFML/Graphics/Font.hpp
index 84eee27..2b19d39 100644
--- a/include/SFML/Graphics/Font.hpp
+++ b/include/SFML/Graphics/Font.hpp
@@ -95,6 +95,10 @@ public:
/// fonts installed on the user's system, thus you can't
/// load them directly.
///
+ /// \warning SFML cannot preload all the font data in this
+ /// function, so the file has to remain accessible until
+ /// the sf::Font object loads a new font or is destroyed.
+ ///
/// \param filename Path of the font file to load
///
/// \return True if loading succeeded, false if it failed
@@ -109,9 +113,11 @@ public:
///
/// The supported font formats are: TrueType, Type 1, CFF,
/// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42.
- /// Warning: SFML cannot preload all the font data in this
+ ///
+ /// \warning SFML cannot preload all the font data in this
/// function, so the buffer pointed by \a data has to remain
- /// valid as long as the font is used.
+ /// valid until the sf::Font object loads a new font or
+ /// is destroyed.
///
/// \param data Pointer to the file data in memory
/// \param sizeInBytes Size of the data to load, in bytes
@@ -132,6 +138,10 @@ public:
/// function, so the contents of \a stream have to remain
/// valid as long as the font is used.
///
+ /// \warning SFML cannot preload all the font data in this
+ /// function, so the stream has to remain accessible until
+ /// the sf::Font object loads a new font or is destroyed.
+ ///
/// \param stream Source stream to read from
///
/// \return True if loading succeeded, false if it failed
@@ -278,7 +288,7 @@ private:
Page();
GlyphTable glyphs; ///< Table mapping code points to their corresponding glyph
- sf::Texture texture; ///< Texture containing the pixels of the glyphs
+ Texture texture; ///< Texture containing the pixels of the glyphs
unsigned int nextRow; ///< Y position of the next new row in the texture
std::vector<Row> rows; ///< List containing the position of all the existing rows
};
diff --git a/include/SFML/Graphics/RenderStates.hpp b/include/SFML/Graphics/RenderStates.hpp
index b23a778..3ab3271 100644
--- a/include/SFML/Graphics/RenderStates.hpp
+++ b/include/SFML/Graphics/RenderStates.hpp
@@ -150,7 +150,7 @@ public:
/// directly without defining render states explicitly -- the
/// default set of states is ok in most cases.
/// \code
-/// window.Draw(sprite);
+/// window.draw(sprite);
/// \endcode
///
/// If you want to use a single specific render state,
diff --git a/include/SFML/Graphics/Shader.hpp b/include/SFML/Graphics/Shader.hpp
index d3278f9..55cc3bb 100644
--- a/include/SFML/Graphics/Shader.hpp
+++ b/include/SFML/Graphics/Shader.hpp
@@ -399,7 +399,7 @@ public:
/// \param transform Transform to assign
///
////////////////////////////////////////////////////////////
- void setParameter(const std::string& name, const sf::Transform& transform);
+ void setParameter(const std::string& name, const Transform& transform);
////////////////////////////////////////////////////////////
/// \brief Change a texture parameter of the shader
diff --git a/include/SFML/Graphics/Texture.hpp b/include/SFML/Graphics/Texture.hpp
index 421861e..29260d1 100644
--- a/include/SFML/Graphics/Texture.hpp
+++ b/include/SFML/Graphics/Texture.hpp
@@ -187,7 +187,7 @@ public:
/// \see loadFromFile, loadFromMemory, loadFromImage
///
////////////////////////////////////////////////////////////
- bool loadFromStream(sf::InputStream& stream, const IntRect& area = IntRect());
+ bool loadFromStream(InputStream& stream, const IntRect& area = IntRect());
////////////////////////////////////////////////////////////
/// \brief Load the texture from an image
diff --git a/include/SFML/System/FileInputStream.hpp b/include/SFML/System/FileInputStream.hpp
index 1afa939..995351c 100644
--- a/include/SFML/System/FileInputStream.hpp
+++ b/include/SFML/System/FileInputStream.hpp
@@ -123,7 +123,7 @@ private:
// Member data
////////////////////////////////////////////////////////////
#ifdef ANDROID
- sf::priv::ResourceStream *m_file;
+ priv::ResourceStream* m_file;
#else
std::FILE* m_file; ///< stdio file stream
#endif
diff --git a/include/SFML/Window/Joystick.hpp b/include/SFML/Window/Joystick.hpp
index 185fd76..27f6291 100644
--- a/include/SFML/Window/Joystick.hpp
+++ b/include/SFML/Window/Joystick.hpp
@@ -77,7 +77,7 @@ public:
{
Identification();
- sf::String name; ///< Name of the joystick
+ String name; ///< Name of the joystick
unsigned int vendorId; ///< Manufacturer identifier
unsigned int productId; ///< Product identifier
};
diff --git a/src/SFML/Audio/InputSoundFile.cpp b/src/SFML/Audio/InputSoundFile.cpp
index 2f281f5..ede0f47 100644
--- a/src/SFML/Audio/InputSoundFile.cpp
+++ b/src/SFML/Audio/InputSoundFile.cpp
@@ -65,10 +65,7 @@ bool InputSoundFile::openFromFile(const std::string& filename)
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromFilename(filename);
if (!m_reader)
- {
- err() << "Failed to open sound file \"" << filename << "\" (format not supported)" << std::endl;
return false;
- }
// Wrap the file into a stream
FileInputStream* file = new FileInputStream;
@@ -108,10 +105,7 @@ bool InputSoundFile::openFromMemory(const void* data, std::size_t sizeInBytes)
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromMemory(data, sizeInBytes);
if (!m_reader)
- {
- err() << "Failed to open sound file from memory (format not supported)" << std::endl;
return false;
- }
// Wrap the memory file into a stream
MemoryInputStream* memory = new MemoryInputStream;
@@ -147,10 +141,7 @@ bool InputSoundFile::openFromStream(InputStream& stream)
// Find a suitable reader for the file type
m_reader = SoundFileFactory::createReaderFromStream(stream);
if (!m_reader)
- {
- err() << "Failed to open sound file from stream (format not supported)" << std::endl;
return false;
- }
// store the stream
m_stream = &stream;
diff --git a/src/SFML/Audio/OutputSoundFile.cpp b/src/SFML/Audio/OutputSoundFile.cpp
index 5bb0e24..8f43ca7 100644
--- a/src/SFML/Audio/OutputSoundFile.cpp
+++ b/src/SFML/Audio/OutputSoundFile.cpp
@@ -28,7 +28,6 @@
#include <SFML/Audio/OutputSoundFile.hpp>
#include <SFML/Audio/SoundFileWriter.hpp>
#include <SFML/Audio/SoundFileFactory.hpp>
-#include <SFML/System/Err.hpp>
namespace sf
@@ -57,10 +56,7 @@ bool OutputSoundFile::openFromFile(const std::string& filename, unsigned int sam
// Find a suitable writer for the file type
m_writer = SoundFileFactory::createWriterFromFilename(filename);
if (!m_writer)
- {
- err() << "Failed to open sound file \"" << filename << "\" (format not supported)" << std::endl;
return false;
- }
// Pass the stream to the reader
if (!m_writer->open(filename, sampleRate, channelCount))
diff --git a/src/SFML/Audio/SoundFileFactory.cpp b/src/SFML/Audio/SoundFileFactory.cpp
index 02d4c99..fa2811c 100644
--- a/src/SFML/Audio/SoundFileFactory.cpp
+++ b/src/SFML/Audio/SoundFileFactory.cpp
@@ -34,6 +34,7 @@
#include <SFML/Audio/SoundFileWriterWav.hpp>
#include <SFML/System/FileInputStream.hpp>
#include <SFML/System/MemoryInputStream.hpp>
+#include <SFML/System/Err.hpp>
namespace
@@ -69,8 +70,10 @@ SoundFileReader* SoundFileFactory::createReaderFromFilename(const std::string& f
// Wrap the input file into a file stream
FileInputStream stream;
- if (!stream.open(filename))
+ if (!stream.open(filename)) {
+ err() << "Failed to open sound file \"" << filename << "\" (couldn't open stream)" << std::endl;
return NULL;
+ }
// Test the filename in all the registered factories
for (ReaderFactoryArray::const_iterator it = s_readers.begin(); it != s_readers.end(); ++it)
@@ -81,6 +84,7 @@ SoundFileReader* SoundFileFactory::createReaderFromFilename(const std::string& f
}
// No suitable reader found
+ err() << "Failed to open sound file \"" << filename << "\" (format not supported)" << std::endl;
return NULL;
}
@@ -104,6 +108,7 @@ SoundFileReader* SoundFileFactory::createReaderFromMemory(const void* data, std:
}
// No suitable reader found
+ err() << "Failed to open sound file from memory (format not supported)" << std::endl;
return NULL;
}
@@ -123,6 +128,7 @@ SoundFileReader* SoundFileFactory::createReaderFromStream(InputStream& stream)
}
// No suitable reader found
+ err() << "Failed to open sound file from stream (format not supported)" << std::endl;
return NULL;
}
@@ -141,6 +147,7 @@ SoundFileWriter* SoundFileFactory::createWriterFromFilename(const std::string& f
}
// No suitable writer found
+ err() << "Failed to open sound file \"" << filename << "\" (format not supported)" << std::endl;
return NULL;
}
diff --git a/src/SFML/Audio/SoundRecorder.cpp b/src/SFML/Audio/SoundRecorder.cpp
index 84a4854..f051b96 100644
--- a/src/SFML/Audio/SoundRecorder.cpp
+++ b/src/SFML/Audio/SoundRecorder.cpp
@@ -135,7 +135,7 @@ std::vector<std::string> SoundRecorder::getAvailableDevices()
{
std::vector<std::string> deviceNameList;
- const ALchar *deviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
+ const ALchar* deviceList = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
if (deviceList)
{
while (*deviceList)
@@ -210,7 +210,7 @@ bool SoundRecorder::isAvailable()
////////////////////////////////////////////////////////////
-void SoundRecorder::setProcessingInterval(sf::Time interval)
+void SoundRecorder::setProcessingInterval(Time interval)
{
m_processingInterval = interval;
}
diff --git a/src/SFML/Graphics/GLExtensions.hpp b/src/SFML/Graphics/GLExtensions.hpp
index 7cff594..52195a1 100644
--- a/src/SFML/Graphics/GLExtensions.hpp
+++ b/src/SFML/Graphics/GLExtensions.hpp
@@ -45,6 +45,7 @@
// Core since 1.0
#define GLEXT_multitexture true
#define GLEXT_texture_edge_clamp true
+ #define GLEXT_EXT_texture_edge_clamp true
#define GLEXT_blend_minmax true
#define GLEXT_glClientActiveTexture glClientActiveTexture
#define GLEXT_glActiveTexture glActiveTexture
@@ -130,6 +131,9 @@
#define GLEXT_texture_edge_clamp sfogl_ext_SGIS_texture_edge_clamp
#define GLEXT_GL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE_SGIS
+ // Core since 1.2 - EXT_texture_edge_clamp
+ #define GLEXT_EXT_texture_edge_clamp sfogl_ext_EXT_texture_edge_clamp
+
// Core since 1.2 - EXT_blend_minmax
#define GLEXT_blend_minmax sfogl_ext_EXT_blend_minmax
#define GLEXT_glBlendEquation glBlendEquationEXT
diff --git a/src/SFML/Graphics/GLExtensions.txt b/src/SFML/Graphics/GLExtensions.txt
index 5f2b5b3..033404d 100644
--- a/src/SFML/Graphics/GLExtensions.txt
+++ b/src/SFML/Graphics/GLExtensions.txt
@@ -4,6 +4,7 @@
// lua LoadGen.lua -style=pointer_c -spec=gl -version=1.1 -indent=space -prefix=sf -extfile=GLExtensions.txt GLLoader
SGIS_texture_edge_clamp
+//EXT_texture_edge_clamp
EXT_blend_minmax
EXT_blend_subtract
ARB_multitexture
diff --git a/src/SFML/Graphics/GLLoader.cpp b/src/SFML/Graphics/GLLoader.cpp
index cceab2f..e82cd7a 100644
--- a/src/SFML/Graphics/GLLoader.cpp
+++ b/src/SFML/Graphics/GLLoader.cpp
@@ -50,6 +50,7 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name)
}
int sfogl_ext_SGIS_texture_edge_clamp = sfogl_LOAD_FAILED;
+int sfogl_ext_EXT_texture_edge_clamp = sfogl_LOAD_FAILED;
int sfogl_ext_EXT_blend_minmax = sfogl_LOAD_FAILED;
int sfogl_ext_EXT_blend_subtract = sfogl_LOAD_FAILED;
int sfogl_ext_ARB_multitexture = sfogl_LOAD_FAILED;
@@ -317,8 +318,9 @@ typedef struct sfogl_StrToExtMap_s
PFN_LOADFUNCPOINTERS LoadExtension;
} sfogl_StrToExtMap;
-static sfogl_StrToExtMap ExtensionMap[12] = {
+static sfogl_StrToExtMap ExtensionMap[13] = {
{"GL_SGIS_texture_edge_clamp", &sfogl_ext_SGIS_texture_edge_clamp, NULL},
+ {"GL_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
{"GL_EXT_blend_minmax", &sfogl_ext_EXT_blend_minmax, Load_EXT_blend_minmax},
{"GL_EXT_blend_subtract", &sfogl_ext_EXT_blend_subtract, NULL},
{"GL_ARB_multitexture", &sfogl_ext_ARB_multitexture, Load_ARB_multitexture},
@@ -332,7 +334,7 @@ static sfogl_StrToExtMap ExtensionMap[12] = {
{"GL_EXT_framebuffer_object", &sfogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object}
};
-static int g_extensionMapSize = 12;
+static int g_extensionMapSize = 13;
static sfogl_StrToExtMap *FindExtEntry(const char *extensionName)
{
@@ -350,6 +352,7 @@ static sfogl_StrToExtMap *FindExtEntry(const char *extensionName)
static void ClearExtensionVars()
{
sfogl_ext_SGIS_texture_edge_clamp = sfogl_LOAD_FAILED;
+ sfogl_ext_EXT_texture_edge_clamp = sfogl_LOAD_FAILED;
sfogl_ext_EXT_blend_minmax = sfogl_LOAD_FAILED;
sfogl_ext_EXT_blend_subtract = sfogl_LOAD_FAILED;
sfogl_ext_ARB_multitexture = sfogl_LOAD_FAILED;
diff --git a/src/SFML/Graphics/GLLoader.hpp b/src/SFML/Graphics/GLLoader.hpp
index 42e1e09..0006406 100644
--- a/src/SFML/Graphics/GLLoader.hpp
+++ b/src/SFML/Graphics/GLLoader.hpp
@@ -174,6 +174,7 @@ extern "C" {
#endif /*__cplusplus*/
extern int sfogl_ext_SGIS_texture_edge_clamp;
+extern int sfogl_ext_EXT_texture_edge_clamp;
extern int sfogl_ext_EXT_blend_minmax;
extern int sfogl_ext_EXT_blend_subtract;
extern int sfogl_ext_ARB_multitexture;
@@ -188,6 +189,8 @@ extern int sfogl_ext_EXT_framebuffer_object;
#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#define GL_CLAMP_TO_EDGE_EXT 0x812F
+
#define GL_BLEND_EQUATION_EXT 0x8009
#define GL_FUNC_ADD_EXT 0x8006
#define GL_MAX_EXT 0x8008
diff --git a/src/SFML/Graphics/Shader.cpp b/src/SFML/Graphics/Shader.cpp
index 80ca28e..5d87d10 100644
--- a/src/SFML/Graphics/Shader.cpp
+++ b/src/SFML/Graphics/Shader.cpp
@@ -385,7 +385,7 @@ void Shader::setParameter(const std::string& name, const Color& color)
////////////////////////////////////////////////////////////
-void Shader::setParameter(const std::string& name, const sf::Transform& transform)
+void Shader::setParameter(const std::string& name, const Transform& transform)
{
if (m_shaderProgram)
{
@@ -768,7 +768,7 @@ void Shader::setParameter(const std::string& name, const Color& color)
////////////////////////////////////////////////////////////
-void Shader::setParameter(const std::string& name, const sf::Transform& transform)
+void Shader::setParameter(const std::string& name, const Transform& transform)
{
}
diff --git a/src/SFML/Graphics/Shape.cpp b/src/SFML/Graphics/Shape.cpp
index 3487777..5403b40 100644
--- a/src/SFML/Graphics/Shape.cpp
+++ b/src/SFML/Graphics/Shape.cpp
@@ -66,7 +66,7 @@ void Shape::setTexture(const Texture* texture, bool resetRect)
if (texture)
{
// Recompute the texture area if requested, or if there was no texture & rect before
- if (resetRect || (!m_texture && (m_textureRect == sf::IntRect())))
+ if (resetRect || (!m_texture && (m_textureRect == IntRect())))
setTextureRect(IntRect(0, 0, texture->getSize().x, texture->getSize().y));
}
diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp
index a747a2d..610dfa2 100644
--- a/src/SFML/Graphics/Texture.cpp
+++ b/src/SFML/Graphics/Texture.cpp
@@ -158,7 +158,9 @@ bool Texture::create(unsigned int width, unsigned int height)
// Make sure that the current texture binding will be preserved
priv::TextureSaver save;
- if (!m_isRepeated && !GLEXT_texture_edge_clamp)
+ static bool textureEdgeClamp = GLEXT_texture_edge_clamp || GLEXT_EXT_texture_edge_clamp;
+
+ if (!m_isRepeated && !textureEdgeClamp)
{
static bool warned = false;
@@ -175,8 +177,8 @@ bool Texture::create(unsigned int width, unsigned int height)
// Initialize the texture
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_actualSize.x, m_actualSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL));
- glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (GLEXT_texture_edge_clamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
- glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (GLEXT_texture_edge_clamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
+ glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
+ glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_isSmooth ? GL_LINEAR : GL_NEAREST));
m_cacheId = getUniqueId();
@@ -480,7 +482,9 @@ void Texture::setRepeated(bool repeated)
// Make sure that the current texture binding will be preserved
priv::TextureSaver save;
- if (!m_isRepeated && !GLEXT_texture_edge_clamp)
+ static bool textureEdgeClamp = GLEXT_texture_edge_clamp || GLEXT_EXT_texture_edge_clamp;
+
+ if (!m_isRepeated && !textureEdgeClamp)
{
static bool warned = false;
@@ -495,8 +499,8 @@ void Texture::setRepeated(bool repeated)
}
glCheck(glBindTexture(GL_TEXTURE_2D, m_texture));
- glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (GLEXT_texture_edge_clamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
- glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (GLEXT_texture_edge_clamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
+ glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
+ glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_isRepeated ? GL_REPEAT : (textureEdgeClamp ? GLEXT_GL_CLAMP_TO_EDGE : GLEXT_GL_CLAMP)));
}
}
}
diff --git a/src/SFML/Main/MainAndroid.cpp b/src/SFML/Main/MainAndroid.cpp
index 2069402..52e3816 100644
--- a/src/SFML/Main/MainAndroid.cpp
+++ b/src/SFML/Main/MainAndroid.cpp
@@ -53,6 +53,27 @@ namespace sf
{
namespace priv
{
+
+////////////////////////////////////////////////////////////
+int getAndroidApiLevel(ANativeActivity* activity)
+{
+ JNIEnv* lJNIEnv = activity->env;
+
+ jclass versionClass = lJNIEnv->FindClass("android/os/Build$VERSION");
+ if (versionClass == NULL)
+ return 0;
+
+ jfieldID sdkIntFieldID = lJNIEnv->GetStaticFieldID(versionClass, "SDK_INT", "I");
+ if (sdkIntFieldID == NULL)
+ return 0;
+
+ jint sdkInt = 0;
+ sdkInt = lJNIEnv->GetStaticIntField(versionClass, sdkIntFieldID);
+
+ return sdkInt;
+}
+
+
////////////////////////////////////////////////////////////
ActivityStates* retrieveStates(ANativeActivity* activity)
{
@@ -117,6 +138,9 @@ void* main(ActivityStates* states)
////////////////////////////////////////////////////////////
void goToFullscreenMode(ANativeActivity* activity)
{
+ // Get the current Android API level.
+ int apiLevel = sf::priv::getAndroidApiLevel(activity);
+
// Hide the status bar
ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_FULLSCREEN,
AWINDOW_FLAG_FULLSCREEN);
@@ -137,17 +161,35 @@ void goToFullscreenMode(ANativeActivity* activity)
jclass classView = lJNIEnv->FindClass("android/view/View");
- jfieldID FieldSYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_LOW_PROFILE", "I");
- jint SYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_LOW_PROFILE);
+ // Default flags
+ jint flags = 0;
+
+ // API Level 14
+ if (apiLevel >= 14)
+ {
+ jfieldID FieldSYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_LOW_PROFILE", "I");
+ jint SYSTEM_UI_FLAG_LOW_PROFILE = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_LOW_PROFILE);
+ flags |= SYSTEM_UI_FLAG_LOW_PROFILE;
+ }
- jfieldID FieldSYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_FULLSCREEN", "I");
- jint SYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_FULLSCREEN);
+ // API Level 16
+ if (apiLevel >= 16)
+ {
+ jfieldID FieldSYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_FULLSCREEN", "I");
+ jint SYSTEM_UI_FLAG_FULLSCREEN = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_FULLSCREEN);
+ flags |= SYSTEM_UI_FLAG_FULLSCREEN;
+ }
- //jfieldID FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY", "I");
- //jint SYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ // API Level 19
+ if (apiLevel >= 19)
+ {
+ jfieldID FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticFieldID(classView, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY", "I");
+ jint SYSTEM_UI_FLAG_IMMERSIVE_STICKY = lJNIEnv->GetStaticIntField(classView, FieldSYSTEM_UI_FLAG_IMMERSIVE_STICKY);
+ flags |= SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ }
jmethodID methodsetSystemUiVisibility = lJNIEnv->GetMethodID(classView, "setSystemUiVisibility", "(I)V");
- lJNIEnv->CallVoidMethod(objectDecorView, methodsetSystemUiVisibility, SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN | 0x00001000);
+ lJNIEnv->CallVoidMethod(objectDecorView, methodsetSystemUiVisibility, flags);
}
////////////////////////////////////////////////////////////
@@ -386,13 +428,16 @@ static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
sf::Lock lock(states->mutex);
- // Send an event to warn people about the window move/resize
- sf::Event event;
- event.type = sf::Event::Resized;
- event.size.width = ANativeWindow_getWidth(states->window);
- event.size.height = ANativeWindow_getHeight(states->window);
+ // Make sure the window still exists before we access the dimensions on it
+ if (states->window != NULL) {
+ // Send an event to warn people about the window move/resize
+ sf::Event event;
+ event.type = sf::Event::Resized;
+ event.size.width = ANativeWindow_getWidth(states->window);
+ event.size.height = ANativeWindow_getHeight(states->window);
- states->forwardEvent(event);
+ states->forwardEvent(event);
+ }
}
diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp
index 5a032ef..6476c53 100644
--- a/src/SFML/Network/TcpSocket.cpp
+++ b/src/SFML/Network/TcpSocket.cpp
@@ -179,7 +179,7 @@ Socket::Status TcpSocket::connect(const IpAddress& remoteAddress, unsigned short
{
// At this point the connection may have been either accepted or refused.
// To know whether it's a success or a failure, we must check the address of the connected peer
- if (getRemoteAddress() != sf::IpAddress::None)
+ if (getRemoteAddress() != IpAddress::None)
{
// Connection accepted
status = Done;
diff --git a/src/SFML/System/Android/ResourceStream.cpp b/src/SFML/System/Android/ResourceStream.cpp
index abfa29e..fbc1ec4 100644
--- a/src/SFML/System/Android/ResourceStream.cpp
+++ b/src/SFML/System/Android/ResourceStream.cpp
@@ -63,7 +63,7 @@ Int64 ResourceStream::read(void *data, Int64 size)
////////////////////////////////////////////////////////////
Int64 ResourceStream::seek(Int64 position)
{
- AAsset_seek(m_file, position, SEEK_SET);
+ return AAsset_seek(m_file, position, SEEK_SET);
}
diff --git a/src/SFML/System/FileInputStream.cpp b/src/SFML/System/FileInputStream.cpp
index dee021f..82f4d72 100644
--- a/src/SFML/System/FileInputStream.cpp
+++ b/src/SFML/System/FileInputStream.cpp
@@ -60,7 +60,8 @@ bool FileInputStream::open(const std::string& filename)
#ifdef ANDROID
if (m_file)
delete m_file;
- m_file = new sf::priv::ResourceStream(filename);
+ m_file = new priv::ResourceStream(filename);
+ return m_file->tell() != -1;
#else
if (m_file)
std::fclose(m_file);
@@ -127,9 +128,9 @@ Int64 FileInputStream::getSize()
#else
if (m_file)
{
- sf::Int64 position = tell();
+ Int64 position = tell();
std::fseek(m_file, 0, SEEK_END);
- sf::Int64 size = tell();
+ Int64 size = tell();
seek(position);
return size;
}
diff --git a/src/SFML/Window/Android/InputImpl.cpp b/src/SFML/Window/Android/InputImpl.cpp
index 920587b..8940b9e 100644
--- a/src/SFML/Window/Android/InputImpl.cpp
+++ b/src/SFML/Window/Android/InputImpl.cpp
@@ -78,6 +78,7 @@ void InputImpl::setVirtualKeyboardVisible(bool visible)
"INPUT_METHOD_SERVICE", "Ljava/lang/String;");
jobject INPUT_METHOD_SERVICE = lJNIEnv->GetStaticObjectField(ClassContext,
FieldINPUT_METHOD_SERVICE);
+ lJNIEnv->DeleteLocalRef(ClassContext);
// Runs getSystemService(Context.INPUT_METHOD_SERVICE)
jclass ClassInputMethodManager =
@@ -86,6 +87,7 @@ void InputImpl::setVirtualKeyboardVisible(bool visible)
"getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject lInputMethodManager = lJNIEnv->CallObjectMethod(lNativeActivity,
MethodGetSystemService, INPUT_METHOD_SERVICE);
+ lJNIEnv->DeleteLocalRef(INPUT_METHOD_SERVICE);
// Runs getWindow().getDecorView()
jmethodID MethodGetWindow = lJNIEnv->GetMethodID(ClassNativeActivity,
@@ -95,6 +97,8 @@ void InputImpl::setVirtualKeyboardVisible(bool visible)
jmethodID MethodGetDecorView = lJNIEnv->GetMethodID(ClassWindow,
"getDecorView", "()Landroid/view/View;");
jobject lDecorView = lJNIEnv->CallObjectMethod(lWindow, MethodGetDecorView);
+ lJNIEnv->DeleteLocalRef(lWindow);
+ lJNIEnv->DeleteLocalRef(ClassWindow);
if (visible)
{
@@ -112,13 +116,19 @@ void InputImpl::setVirtualKeyboardVisible(bool visible)
"getWindowToken", "()Landroid/os/IBinder;");
jobject lBinder = lJNIEnv->CallObjectMethod(lDecorView,
MethodGetWindowToken);
+ lJNIEnv->DeleteLocalRef(ClassView);
// lInputMethodManager.hideSoftInput(...)
jmethodID MethodHideSoftInput = lJNIEnv->GetMethodID(ClassInputMethodManager,
"hideSoftInputFromWindow", "(Landroid/os/IBinder;I)Z");
jboolean lRes = lJNIEnv->CallBooleanMethod(lInputMethodManager,
MethodHideSoftInput, lBinder, lFlags);
+ lJNIEnv->DeleteLocalRef(lBinder);
}
+ lJNIEnv->DeleteLocalRef(lNativeActivity);
+ lJNIEnv->DeleteLocalRef(ClassNativeActivity);
+ lJNIEnv->DeleteLocalRef(ClassInputMethodManager);
+ lJNIEnv->DeleteLocalRef(lDecorView);
// Finished with the JVM
lJavaVM->DetachCurrentThread();
diff --git a/src/SFML/Window/Android/WindowImplAndroid.cpp b/src/SFML/Window/Android/WindowImplAndroid.cpp
index 2c140b0..fb1906b 100644
--- a/src/SFML/Window/Android/WindowImplAndroid.cpp
+++ b/src/SFML/Window/Android/WindowImplAndroid.cpp
@@ -33,9 +33,11 @@
#include <SFML/System/Err.hpp>
#include <android/looper.h>
-// Define missing constants
-#define AMOTION_EVENT_ACTION_HOVER_MOVE 0x00000007
-#define AMOTION_EVENT_ACTION_SCROLL 0x00000008
+// Define missing constants for older API levels
+#if __ANDROID_API__ < 13
+ #define AMOTION_EVENT_ACTION_HOVER_MOVE 0x00000007
+ #define AMOTION_EVENT_ACTION_SCROLL 0x00000008
+#endif
////////////////////////////////////////////////////////////
// Private data
@@ -232,7 +234,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
if (AInputQueue_preDispatchEvent(states->inputQueue, _event))
return 1;
- int32_t handled = 0;
+ int handled = 0;
int32_t type = AInputEvent_getType(_event);
@@ -244,8 +246,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
if ((action == AKEY_EVENT_ACTION_DOWN || action == AKEY_EVENT_ACTION_UP || action == AKEY_EVENT_ACTION_MULTIPLE) &&
key != AKEYCODE_VOLUME_UP && key != AKEYCODE_VOLUME_DOWN)
{
- processKeyEvent(_event, states);
- handled = 1;
+ handled = processKeyEvent(_event, states);
}
}
else if (type == AINPUT_EVENT_TYPE_MOTION)
@@ -256,16 +257,15 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
{
case AMOTION_EVENT_ACTION_SCROLL:
{
- processScrollEvent(_event, states);
- handled = 1;
+ handled = processScrollEvent(_event, states);
break;
}
- case AMOTION_EVENT_ACTION_HOVER_MOVE:
+ // todo: should hover_move indeed trigger the event?
+ // case AMOTION_EVENT_ACTION_HOVER_MOVE:
case AMOTION_EVENT_ACTION_MOVE:
{
- processMotionEvent(_event, states);
- handled = 1;
+ handled = processMotionEvent(_event, states);
break;
}
@@ -273,8 +273,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_DOWN:
{
- processPointerEvent(true, _event, states);
- handled = 1;
+ handled = processPointerEvent(true, _event, states);
break;
}
@@ -282,8 +281,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
{
- processPointerEvent(false, _event, states);
- handled = 1;
+ handled = processPointerEvent(false, _event, states);
break;
}
}
@@ -298,7 +296,7 @@ int WindowImplAndroid::processEvent(int fd, int events, void* data)
////////////////////////////////////////////////////////////
-void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates* states)
+int WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates* states)
{
// Prepare the Java virtual machine
jint lResult;
@@ -314,8 +312,10 @@ void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates*
lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
- if (lResult == JNI_ERR)
+ if (lResult == JNI_ERR) {
err() << "Failed to initialize JNI, couldn't get the Unicode value" << std::endl;
+ return 0;
+ }
// Retrieve everything we need to create this MotionEvent in Java
jlong downTime = AMotionEvent_getDownTime(_event);
@@ -340,6 +340,9 @@ void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates*
jmethodID MethodGetAxisValue = lJNIEnv->GetMethodID(ClassMotionEvent, "getAxisValue", "(I)F");
jfloat delta = lJNIEnv->CallFloatMethod(ObjectMotionEvent, MethodGetAxisValue, 0x00000001);
+ lJNIEnv->DeleteLocalRef(ClassMotionEvent);
+ lJNIEnv->DeleteLocalRef(ObjectMotionEvent);
+
// Create and send our mouse wheel event
Event event;
event.type = Event::MouseWheelMoved;
@@ -351,11 +354,13 @@ void WindowImplAndroid::processScrollEvent(AInputEvent* _event, ActivityStates*
// Detach this thread from the JVM
lJavaVM->DetachCurrentThread();
+
+ return 1;
}
////////////////////////////////////////////////////////////
-void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* states)
+int WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* states)
{
int32_t device = AInputEvent_getSource(_event);
int32_t action = AKeyEvent_getAction(_event);
@@ -374,7 +379,7 @@ void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* sta
case AKEY_EVENT_ACTION_DOWN:
event.type = Event::KeyPressed;
forwardEvent(event);
- break;
+ return 1;
case AKEY_EVENT_ACTION_UP:
event.type = Event::KeyReleased;
forwardEvent(event);
@@ -385,7 +390,7 @@ void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* sta
event.text.unicode = unicode;
forwardEvent(event);
}
- break;
+ return 1;
case AKEY_EVENT_ACTION_MULTIPLE:
// Since complex inputs don't get separate key down/up events
// both have to be faked at once
@@ -400,27 +405,26 @@ void WindowImplAndroid::processKeyEvent(AInputEvent* _event, ActivityStates* sta
{
// This is a unique sequence, which is not yet exposed in the NDK
// http://code.google.com/p/android/issues/detail?id=33998
+ return 0;
}
- else
+ else if (int unicode = getUnicode(_event)) // This is a repeated sequence
{
- // This is a repeated sequence
- if (int unicode = getUnicode(_event))
- {
- event.type = Event::TextEntered;
- event.text.unicode = unicode;
+ event.type = Event::TextEntered;
+ event.text.unicode = unicode;
- int32_t repeats = AKeyEvent_getRepeatCount(_event);
- for (int32_t i = 0; i < repeats; ++i)
- forwardEvent(event);
- }
+ int32_t repeats = AKeyEvent_getRepeatCount(_event);
+ for (int32_t i = 0; i < repeats; ++i)
+ forwardEvent(event);
+ return 1;
}
break;
}
+ return 0;
}
////////////////////////////////////////////////////////////
-void WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates* states)
+int WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates* states)
{
int32_t device = AInputEvent_getSource(_event);
int32_t action = AMotionEvent_getAction(_event);
@@ -462,11 +466,12 @@ void WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates*
forwardEvent(event);
}
+ return 1;
}
////////////////////////////////////////////////////////////
-void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, ActivityStates* states)
+int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, ActivityStates* states)
{
int32_t device = AInputEvent_getSource(_event);
int32_t action = AMotionEvent_getAction(_event);
@@ -525,6 +530,7 @@ void WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Ac
}
forwardEvent(event);
+ return 1;
}
@@ -693,6 +699,9 @@ int WindowImplAndroid::getUnicode(AInputEvent* event)
jmethodID MethodGetUnicode = lJNIEnv->GetMethodID(ClassKeyEvent, "getUnicodeChar", "(I)I");
int unicode = lJNIEnv->CallIntMethod(ObjectKeyEvent, MethodGetUnicode, metaState);
+ lJNIEnv->DeleteLocalRef(ClassKeyEvent);
+ lJNIEnv->DeleteLocalRef(ObjectKeyEvent);
+
// Detach this thread from the JVM
lJavaVM->DetachCurrentThread();
diff --git a/src/SFML/Window/Android/WindowImplAndroid.hpp b/src/SFML/Window/Android/WindowImplAndroid.hpp
index cdfb521..fb05b35 100644
--- a/src/SFML/Window/Android/WindowImplAndroid.hpp
+++ b/src/SFML/Window/Android/WindowImplAndroid.hpp
@@ -194,10 +194,10 @@ private:
////////////////////////////////////////////////////////////
static int processEvent(int fd, int events, void* data);
- static void processScrollEvent(AInputEvent* _event, ActivityStates* states);
- static void processKeyEvent(AInputEvent* _event, ActivityStates* states);
- static void processMotionEvent(AInputEvent* _event, ActivityStates* states);
- static void processPointerEvent(bool isDown, AInputEvent* event, ActivityStates* states);
+ static int processScrollEvent(AInputEvent* _event, ActivityStates* states);
+ static int processKeyEvent(AInputEvent* _event, ActivityStates* states);
+ static int processMotionEvent(AInputEvent* _event, ActivityStates* states);
+ static int processPointerEvent(bool isDown, AInputEvent* event, ActivityStates* states);
////////////////////////////////////////////////////////////
/// \brief Convert a Android key to SFML key code
diff --git a/src/SFML/Window/Unix/Display.cpp b/src/SFML/Window/Unix/Display.cpp
index e537224..cf1357d 100644
--- a/src/SFML/Window/Unix/Display.cpp
+++ b/src/SFML/Window/Unix/Display.cpp
@@ -145,77 +145,6 @@ namespace
return keysym;
}
-
- void buildMap()
- {
- // Open a connection with the X server
- xcb_connection_t* connection = sf::priv::OpenConnection();
-
- firstKeycode = xcb_get_setup(connection)->min_keycode;
- lastKeycode = xcb_get_setup(connection)->max_keycode;
-
- sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
-
- sf::priv::ScopedXcbPtr<xcb_get_keyboard_mapping_reply_t> keyboardMapping(xcb_get_keyboard_mapping_reply(
- connection,
- xcb_get_keyboard_mapping(
- connection,
- firstKeycode,
- lastKeycode - firstKeycode + 1
- ),
- &error
- ));
-
- sf::priv::CloseConnection(connection);
-
- if (error || !keyboardMapping)
- {
- sf::err() << "Failed to get keyboard mapping" << std::endl;
- return;
- }
-
- uint8_t keysymsPerKeycode = keyboardMapping->keysyms_per_keycode;
-
- if (!keysymsPerKeycode)
- {
- sf::err() << "Error: No keysyms per keycode" << std::endl;
- return;
- }
-
- const xcb_keysym_t* keysyms = xcb_get_keyboard_mapping_keysyms(keyboardMapping.get());
-
- if (!keysyms)
- {
- sf::err() << "Failed to get keyboard mapping keysyms" << std::endl;
- return;
- }
-
- xcb_keycode_t range = lastKeycode - firstKeycode + 1;
-
- std::fill(keysymMap, keysymMap + 256, XK_VoidSymbol);
-
- for (xcb_keycode_t i = firstKeycode; ; ++i)
- {
- const xcb_keysym_t* keysym = &keysyms[(i - firstKeycode) * keysymsPerKeycode];
-
- if ((keysymsPerKeycode == 1) || (keysym[1] == XCB_NO_SYMBOL))
- {
- keysymMap[i] = keysymToLower(keysym[0]);
-
- if (i == lastKeycode)
- break;
-
- continue;
- }
-
- keysymMap[i] = keysym[0];
-
- if (i == lastKeycode)
- break;
- }
-
- mapBuilt = true;
- }
}
namespace sf
@@ -344,11 +273,84 @@ xcb_atom_t getAtom(const std::string& name, bool onlyIfExists)
const xcb_keysym_t* getKeysymMap()
{
if (!mapBuilt)
- buildMap();
+ buildKeysymMap();
return keysymMap;
}
+
+////////////////////////////////////////////////////////////
+void buildKeysymMap()
+{
+ // Open a connection with the X server
+ xcb_connection_t* connection = sf::priv::OpenConnection();
+
+ firstKeycode = xcb_get_setup(connection)->min_keycode;
+ lastKeycode = xcb_get_setup(connection)->max_keycode;
+
+ sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
+
+ sf::priv::ScopedXcbPtr<xcb_get_keyboard_mapping_reply_t> keyboardMapping(xcb_get_keyboard_mapping_reply(
+ connection,
+ xcb_get_keyboard_mapping(
+ connection,
+ firstKeycode,
+ lastKeycode - firstKeycode + 1
+ ),
+ &error
+ ));
+
+ sf::priv::CloseConnection(connection);
+
+ if (error || !keyboardMapping)
+ {
+ sf::err() << "Failed to get keyboard mapping" << std::endl;
+ return;
+ }
+
+ uint8_t keysymsPerKeycode = keyboardMapping->keysyms_per_keycode;
+
+ if (!keysymsPerKeycode)
+ {
+ sf::err() << "Error: No keysyms per keycode" << std::endl;
+ return;
+ }
+
+ const xcb_keysym_t* keysyms = xcb_get_keyboard_mapping_keysyms(keyboardMapping.get());
+
+ if (!keysyms)
+ {
+ sf::err() << "Failed to get keyboard mapping keysyms" << std::endl;
+ return;
+ }
+
+ xcb_keycode_t range = lastKeycode - firstKeycode + 1;
+
+ std::fill(keysymMap, keysymMap + 256, XK_VoidSymbol);
+
+ for (xcb_keycode_t i = firstKeycode; ; ++i)
+ {
+ const xcb_keysym_t* keysym = &keysyms[(i - firstKeycode) * keysymsPerKeycode];
+
+ if ((keysymsPerKeycode == 1) || (keysym[1] == XCB_NO_SYMBOL))
+ {
+ keysymMap[i] = keysymToLower(keysym[0]);
+
+ if (i == lastKeycode)
+ break;
+
+ continue;
+ }
+
+ keysymMap[i] = keysym[0];
+
+ if (i == lastKeycode)
+ break;
+ }
+
+ mapBuilt = true;
+}
+
} // namespace priv
} // namespace sf
diff --git a/src/SFML/Window/Unix/Display.hpp b/src/SFML/Window/Unix/Display.hpp
index 1cda4a7..da29d51 100644
--- a/src/SFML/Window/Unix/Display.hpp
+++ b/src/SFML/Window/Unix/Display.hpp
@@ -51,7 +51,7 @@ Display* OpenDisplay();
/// \brief Get the xcb connection of the shared Display
///
/// This function increments the reference count of the display,
-/// it must be matched with a call to CloseDisplay.
+/// it must be matched with a call to CloseConnection.
///
/// \return Pointer to the shared connection
///
@@ -127,6 +127,12 @@ xcb_atom_t getAtom(const std::string& name, bool onlyIfExists = false);
////////////////////////////////////////////////////////////
const xcb_keysym_t* getKeysymMap();
+////////////////////////////////////////////////////////////
+/// \brief Build the keysym map
+///
+////////////////////////////////////////////////////////////
+void buildKeysymMap();
+
} // namespace priv
} // namespace sf
diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp
index 4d815f8..3949115 100644
--- a/src/SFML/Window/Unix/InputImpl.cpp
+++ b/src/SFML/Window/Unix/InputImpl.cpp
@@ -59,113 +59,6 @@ namespace
return 255;
}
-
- void buildMap()
- {
- keycodeMap[sf::Keyboard::A] = getKeycode(XK_a);
- keycodeMap[sf::Keyboard::B] = getKeycode(XK_b);
- keycodeMap[sf::Keyboard::C] = getKeycode(XK_c);
- keycodeMap[sf::Keyboard::D] = getKeycode(XK_d);
- keycodeMap[sf::Keyboard::E] = getKeycode(XK_e);
- keycodeMap[sf::Keyboard::F] = getKeycode(XK_f);
- keycodeMap[sf::Keyboard::G] = getKeycode(XK_g);
- keycodeMap[sf::Keyboard::H] = getKeycode(XK_h);
- keycodeMap[sf::Keyboard::I] = getKeycode(XK_i);
- keycodeMap[sf::Keyboard::J] = getKeycode(XK_j);
- keycodeMap[sf::Keyboard::K] = getKeycode(XK_k);
- keycodeMap[sf::Keyboard::L] = getKeycode(XK_l);
- keycodeMap[sf::Keyboard::M] = getKeycode(XK_m);
- keycodeMap[sf::Keyboard::N] = getKeycode(XK_n);
- keycodeMap[sf::Keyboard::O] = getKeycode(XK_o);
- keycodeMap[sf::Keyboard::P] = getKeycode(XK_p);
- keycodeMap[sf::Keyboard::Q] = getKeycode(XK_q);
- keycodeMap[sf::Keyboard::R] = getKeycode(XK_r);
- keycodeMap[sf::Keyboard::S] = getKeycode(XK_s);
- keycodeMap[sf::Keyboard::T] = getKeycode(XK_t);
- keycodeMap[sf::Keyboard::U] = getKeycode(XK_u);
- keycodeMap[sf::Keyboard::V] = getKeycode(XK_v);
- keycodeMap[sf::Keyboard::W] = getKeycode(XK_w);
- keycodeMap[sf::Keyboard::X] = getKeycode(XK_x);
- keycodeMap[sf::Keyboard::Y] = getKeycode(XK_y);
- keycodeMap[sf::Keyboard::Z] = getKeycode(XK_z);
- keycodeMap[sf::Keyboard::Num0] = getKeycode(XK_0);
- keycodeMap[sf::Keyboard::Num1] = getKeycode(XK_1);
- keycodeMap[sf::Keyboard::Num2] = getKeycode(XK_2);
- keycodeMap[sf::Keyboard::Num3] = getKeycode(XK_3);
- keycodeMap[sf::Keyboard::Num4] = getKeycode(XK_4);
- keycodeMap[sf::Keyboard::Num5] = getKeycode(XK_5);
- keycodeMap[sf::Keyboard::Num6] = getKeycode(XK_6);
- keycodeMap[sf::Keyboard::Num7] = getKeycode(XK_7);
- keycodeMap[sf::Keyboard::Num8] = getKeycode(XK_8);
- keycodeMap[sf::Keyboard::Num9] = getKeycode(XK_9);
- keycodeMap[sf::Keyboard::Escape] = getKeycode(XK_Escape);
- keycodeMap[sf::Keyboard::LControl] = getKeycode(XK_Control_L);
- keycodeMap[sf::Keyboard::LShift] = getKeycode(XK_Shift_L);
- keycodeMap[sf::Keyboard::LAlt] = getKeycode(XK_Alt_L);
- keycodeMap[sf::Keyboard::LSystem] = getKeycode(XK_Super_L);
- keycodeMap[sf::Keyboard::RControl] = getKeycode(XK_Control_R);
- keycodeMap[sf::Keyboard::RShift] = getKeycode(XK_Shift_R);
- keycodeMap[sf::Keyboard::RAlt] = getKeycode(XK_Alt_R);
- keycodeMap[sf::Keyboard::RSystem] = getKeycode(XK_Super_R);
- keycodeMap[sf::Keyboard::Menu] = getKeycode(XK_Menu);
- keycodeMap[sf::Keyboard::LBracket] = getKeycode(XK_bracketleft);
- keycodeMap[sf::Keyboard::RBracket] = getKeycode(XK_bracketright);
- keycodeMap[sf::Keyboard::SemiColon] = getKeycode(XK_semicolon);
- keycodeMap[sf::Keyboard::Comma] = getKeycode(XK_comma);
- keycodeMap[sf::Keyboard::Period] = getKeycode(XK_period);
- keycodeMap[sf::Keyboard::Quote] = getKeycode(XK_apostrophe);
- keycodeMap[sf::Keyboard::Slash] = getKeycode(XK_slash);
- keycodeMap[sf::Keyboard::BackSlash] = getKeycode(XK_backslash);
- keycodeMap[sf::Keyboard::Tilde] = getKeycode(XK_grave);
- keycodeMap[sf::Keyboard::Equal] = getKeycode(XK_equal);
- keycodeMap[sf::Keyboard::Dash] = getKeycode(XK_minus);
- keycodeMap[sf::Keyboard::Space] = getKeycode(XK_space);
- keycodeMap[sf::Keyboard::Return] = getKeycode(XK_Return);
- keycodeMap[sf::Keyboard::BackSpace] = getKeycode(XK_BackSpace);
- keycodeMap[sf::Keyboard::Tab] = getKeycode(XK_Tab);
- keycodeMap[sf::Keyboard::PageUp] = getKeycode(XK_Prior);
- keycodeMap[sf::Keyboard::PageDown] = getKeycode(XK_Next);
- keycodeMap[sf::Keyboard::End] = getKeycode(XK_End);
- keycodeMap[sf::Keyboard::Home] = getKeycode(XK_Home);
- keycodeMap[sf::Keyboard::Insert] = getKeycode(XK_Insert);
- keycodeMap[sf::Keyboard::Delete] = getKeycode(XK_Delete);
- keycodeMap[sf::Keyboard::Add] = getKeycode(XK_KP_Add);
- keycodeMap[sf::Keyboard::Subtract] = getKeycode(XK_KP_Subtract);
- keycodeMap[sf::Keyboard::Multiply] = getKeycode(XK_KP_Multiply);
- keycodeMap[sf::Keyboard::Divide] = getKeycode(XK_KP_Divide);
- keycodeMap[sf::Keyboard::Left] = getKeycode(XK_Left);
- keycodeMap[sf::Keyboard::Right] = getKeycode(XK_Right);
- keycodeMap[sf::Keyboard::Up] = getKeycode(XK_Up);
- keycodeMap[sf::Keyboard::Down] = getKeycode(XK_Down);
- keycodeMap[sf::Keyboard::Numpad0] = getKeycode(XK_KP_0);
- keycodeMap[sf::Keyboard::Numpad1] = getKeycode(XK_KP_1);
- keycodeMap[sf::Keyboard::Numpad2] = getKeycode(XK_KP_2);
- keycodeMap[sf::Keyboard::Numpad3] = getKeycode(XK_KP_3);
- keycodeMap[sf::Keyboard::Numpad4] = getKeycode(XK_KP_4);
- keycodeMap[sf::Keyboard::Numpad5] = getKeycode(XK_KP_5);
- keycodeMap[sf::Keyboard::Numpad6] = getKeycode(XK_KP_6);
- keycodeMap[sf::Keyboard::Numpad7] = getKeycode(XK_KP_7);
- keycodeMap[sf::Keyboard::Numpad8] = getKeycode(XK_KP_8);
- keycodeMap[sf::Keyboard::Numpad9] = getKeycode(XK_KP_9);
- keycodeMap[sf::Keyboard::F1] = getKeycode(XK_F1);
- keycodeMap[sf::Keyboard::F2] = getKeycode(XK_F2);
- keycodeMap[sf::Keyboard::F3] = getKeycode(XK_F3);
- keycodeMap[sf::Keyboard::F4] = getKeycode(XK_F4);
- keycodeMap[sf::Keyboard::F5] = getKeycode(XK_F5);
- keycodeMap[sf::Keyboard::F6] = getKeycode(XK_F6);
- keycodeMap[sf::Keyboard::F7] = getKeycode(XK_F7);
- keycodeMap[sf::Keyboard::F8] = getKeycode(XK_F8);
- keycodeMap[sf::Keyboard::F9] = getKeycode(XK_F9);
- keycodeMap[sf::Keyboard::F10] = getKeycode(XK_F10);
- keycodeMap[sf::Keyboard::F11] = getKeycode(XK_F11);
- keycodeMap[sf::Keyboard::F12] = getKeycode(XK_F12);
- keycodeMap[sf::Keyboard::F13] = getKeycode(XK_F13);
- keycodeMap[sf::Keyboard::F14] = getKeycode(XK_F14);
- keycodeMap[sf::Keyboard::F15] = getKeycode(XK_F15);
- keycodeMap[sf::Keyboard::Pause] = getKeycode(XK_Pause);
-
- mapBuilt = true;
- }
}
@@ -423,6 +316,115 @@ Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*re
return Vector2i();
}
+
+////////////////////////////////////////////////////////////
+void InputImpl::buildMap()
+{
+ keycodeMap[sf::Keyboard::A] = getKeycode(XK_a);
+ keycodeMap[sf::Keyboard::B] = getKeycode(XK_b);
+ keycodeMap[sf::Keyboard::C] = getKeycode(XK_c);
+ keycodeMap[sf::Keyboard::D] = getKeycode(XK_d);
+ keycodeMap[sf::Keyboard::E] = getKeycode(XK_e);
+ keycodeMap[sf::Keyboard::F] = getKeycode(XK_f);
+ keycodeMap[sf::Keyboard::G] = getKeycode(XK_g);
+ keycodeMap[sf::Keyboard::H] = getKeycode(XK_h);
+ keycodeMap[sf::Keyboard::I] = getKeycode(XK_i);
+ keycodeMap[sf::Keyboard::J] = getKeycode(XK_j);
+ keycodeMap[sf::Keyboard::K] = getKeycode(XK_k);
+ keycodeMap[sf::Keyboard::L] = getKeycode(XK_l);
+ keycodeMap[sf::Keyboard::M] = getKeycode(XK_m);
+ keycodeMap[sf::Keyboard::N] = getKeycode(XK_n);
+ keycodeMap[sf::Keyboard::O] = getKeycode(XK_o);
+ keycodeMap[sf::Keyboard::P] = getKeycode(XK_p);
+ keycodeMap[sf::Keyboard::Q] = getKeycode(XK_q);
+ keycodeMap[sf::Keyboard::R] = getKeycode(XK_r);
+ keycodeMap[sf::Keyboard::S] = getKeycode(XK_s);
+ keycodeMap[sf::Keyboard::T] = getKeycode(XK_t);
+ keycodeMap[sf::Keyboard::U] = getKeycode(XK_u);
+ keycodeMap[sf::Keyboard::V] = getKeycode(XK_v);
+ keycodeMap[sf::Keyboard::W] = getKeycode(XK_w);
+ keycodeMap[sf::Keyboard::X] = getKeycode(XK_x);
+ keycodeMap[sf::Keyboard::Y] = getKeycode(XK_y);
+ keycodeMap[sf::Keyboard::Z] = getKeycode(XK_z);
+ keycodeMap[sf::Keyboard::Num0] = getKeycode(XK_0);
+ keycodeMap[sf::Keyboard::Num1] = getKeycode(XK_1);
+ keycodeMap[sf::Keyboard::Num2] = getKeycode(XK_2);
+ keycodeMap[sf::Keyboard::Num3] = getKeycode(XK_3);
+ keycodeMap[sf::Keyboard::Num4] = getKeycode(XK_4);
+ keycodeMap[sf::Keyboard::Num5] = getKeycode(XK_5);
+ keycodeMap[sf::Keyboard::Num6] = getKeycode(XK_6);
+ keycodeMap[sf::Keyboard::Num7] = getKeycode(XK_7);
+ keycodeMap[sf::Keyboard::Num8] = getKeycode(XK_8);
+ keycodeMap[sf::Keyboard::Num9] = getKeycode(XK_9);
+ keycodeMap[sf::Keyboard::Escape] = getKeycode(XK_Escape);
+ keycodeMap[sf::Keyboard::LControl] = getKeycode(XK_Control_L);
+ keycodeMap[sf::Keyboard::LShift] = getKeycode(XK_Shift_L);
+ keycodeMap[sf::Keyboard::LAlt] = getKeycode(XK_Alt_L);
+ keycodeMap[sf::Keyboard::LSystem] = getKeycode(XK_Super_L);
+ keycodeMap[sf::Keyboard::RControl] = getKeycode(XK_Control_R);
+ keycodeMap[sf::Keyboard::RShift] = getKeycode(XK_Shift_R);
+ keycodeMap[sf::Keyboard::RAlt] = getKeycode(XK_Alt_R);
+ keycodeMap[sf::Keyboard::RSystem] = getKeycode(XK_Super_R);
+ keycodeMap[sf::Keyboard::Menu] = getKeycode(XK_Menu);
+ keycodeMap[sf::Keyboard::LBracket] = getKeycode(XK_bracketleft);
+ keycodeMap[sf::Keyboard::RBracket] = getKeycode(XK_bracketright);
+ keycodeMap[sf::Keyboard::SemiColon] = getKeycode(XK_semicolon);
+ keycodeMap[sf::Keyboard::Comma] = getKeycode(XK_comma);
+ keycodeMap[sf::Keyboard::Period] = getKeycode(XK_period);
+ keycodeMap[sf::Keyboard::Quote] = getKeycode(XK_apostrophe);
+ keycodeMap[sf::Keyboard::Slash] = getKeycode(XK_slash);
+ keycodeMap[sf::Keyboard::BackSlash] = getKeycode(XK_backslash);
+ keycodeMap[sf::Keyboard::Tilde] = getKeycode(XK_grave);
+ keycodeMap[sf::Keyboard::Equal] = getKeycode(XK_equal);
+ keycodeMap[sf::Keyboard::Dash] = getKeycode(XK_minus);
+ keycodeMap[sf::Keyboard::Space] = getKeycode(XK_space);
+ keycodeMap[sf::Keyboard::Return] = getKeycode(XK_Return);
+ keycodeMap[sf::Keyboard::BackSpace] = getKeycode(XK_BackSpace);
+ keycodeMap[sf::Keyboard::Tab] = getKeycode(XK_Tab);
+ keycodeMap[sf::Keyboard::PageUp] = getKeycode(XK_Prior);
+ keycodeMap[sf::Keyboard::PageDown] = getKeycode(XK_Next);
+ keycodeMap[sf::Keyboard::End] = getKeycode(XK_End);
+ keycodeMap[sf::Keyboard::Home] = getKeycode(XK_Home);
+ keycodeMap[sf::Keyboard::Insert] = getKeycode(XK_Insert);
+ keycodeMap[sf::Keyboard::Delete] = getKeycode(XK_Delete);
+ keycodeMap[sf::Keyboard::Add] = getKeycode(XK_KP_Add);
+ keycodeMap[sf::Keyboard::Subtract] = getKeycode(XK_KP_Subtract);
+ keycodeMap[sf::Keyboard::Multiply] = getKeycode(XK_KP_Multiply);
+ keycodeMap[sf::Keyboard::Divide] = getKeycode(XK_KP_Divide);
+ keycodeMap[sf::Keyboard::Left] = getKeycode(XK_Left);
+ keycodeMap[sf::Keyboard::Right] = getKeycode(XK_Right);
+ keycodeMap[sf::Keyboard::Up] = getKeycode(XK_Up);
+ keycodeMap[sf::Keyboard::Down] = getKeycode(XK_Down);
+ keycodeMap[sf::Keyboard::Numpad0] = getKeycode(XK_KP_0);
+ keycodeMap[sf::Keyboard::Numpad1] = getKeycode(XK_KP_1);
+ keycodeMap[sf::Keyboard::Numpad2] = getKeycode(XK_KP_2);
+ keycodeMap[sf::Keyboard::Numpad3] = getKeycode(XK_KP_3);
+ keycodeMap[sf::Keyboard::Numpad4] = getKeycode(XK_KP_4);
+ keycodeMap[sf::Keyboard::Numpad5] = getKeycode(XK_KP_5);
+ keycodeMap[sf::Keyboard::Numpad6] = getKeycode(XK_KP_6);
+ keycodeMap[sf::Keyboard::Numpad7] = getKeycode(XK_KP_7);
+ keycodeMap[sf::Keyboard::Numpad8] = getKeycode(XK_KP_8);
+ keycodeMap[sf::Keyboard::Numpad9] = getKeycode(XK_KP_9);
+ keycodeMap[sf::Keyboard::F1] = getKeycode(XK_F1);
+ keycodeMap[sf::Keyboard::F2] = getKeycode(XK_F2);
+ keycodeMap[sf::Keyboard::F3] = getKeycode(XK_F3);
+ keycodeMap[sf::Keyboard::F4] = getKeycode(XK_F4);
+ keycodeMap[sf::Keyboard::F5] = getKeycode(XK_F5);
+ keycodeMap[sf::Keyboard::F6] = getKeycode(XK_F6);
+ keycodeMap[sf::Keyboard::F7] = getKeycode(XK_F7);
+ keycodeMap[sf::Keyboard::F8] = getKeycode(XK_F8);
+ keycodeMap[sf::Keyboard::F9] = getKeycode(XK_F9);
+ keycodeMap[sf::Keyboard::F10] = getKeycode(XK_F10);
+ keycodeMap[sf::Keyboard::F11] = getKeycode(XK_F11);
+ keycodeMap[sf::Keyboard::F12] = getKeycode(XK_F12);
+ keycodeMap[sf::Keyboard::F13] = getKeycode(XK_F13);
+ keycodeMap[sf::Keyboard::F14] = getKeycode(XK_F14);
+ keycodeMap[sf::Keyboard::F15] = getKeycode(XK_F15);
+ keycodeMap[sf::Keyboard::Pause] = getKeycode(XK_Pause);
+
+ mapBuilt = true;
+}
+
} // namespace priv
} // namespace sf
diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp
index 9425c3d..ec4f11e 100644
--- a/src/SFML/Window/Unix/InputImpl.hpp
+++ b/src/SFML/Window/Unix/InputImpl.hpp
@@ -158,6 +158,12 @@ public:
///
////////////////////////////////////////////////////////////
static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Build the SFML to X11 keymap
+ ///
+ ////////////////////////////////////////////////////////////
+ static void buildMap();
};
} // namespace priv
diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp
index d8c26e0..8387975 100644
--- a/src/SFML/Window/Unix/WindowImplX11.cpp
+++ b/src/SFML/Window/Unix/WindowImplX11.cpp
@@ -28,6 +28,7 @@
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
#include <SFML/Window/Unix/WindowImplX11.hpp>
#include <SFML/Window/Unix/Display.hpp>
+#include <SFML/Window/Unix/InputImpl.hpp>
#include <SFML/Window/Unix/ScopedXcbPtr.hpp>
#include <SFML/System/Utf.hpp>
#include <SFML/System/Err.hpp>
@@ -50,6 +51,10 @@
#define XCB_DRI2_BUFFER_SWAP_COMPLETE 0
#define XCB_DRI2_INVALIDATE_BUFFERS 1
+// So we don't have to require xcb xkb to be present
+#define XCB_XKB_NEW_KEYBOARD_NOTIFY 0
+#define XCB_XKB_MAP_NOTIFY 1
+
#ifdef SFML_OPENGL_ES
#include <SFML/Window/EglContext.hpp>
typedef sf::priv::EglContext ContextType;
@@ -230,28 +235,27 @@ namespace
sf::priv::CloseConnection(connection);
- const char* name = reinterpret_cast<const char*>(xcb_get_property_value(wmName.get()));
-
- windowManagerName = name;
+ // It seems the wm name string reply is not necessarily
+ // null-terminated. The work around is to get its actual
+ // length to build a proper string
+ const char* begin = reinterpret_cast<const char*>(xcb_get_property_value(wmName.get()));
+ const char* end = begin + xcb_get_property_value_length(wmName.get());
+ windowManagerName = sf::String::fromUtf8(begin, end);
return true;
}
- xcb_query_extension_reply_t getDriExtension()
+ xcb_query_extension_reply_t getXExtension(const std::string& name)
{
xcb_connection_t* connection = sf::priv::OpenConnection();
sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
-
- // Check if the DRI2 extension is present
- // We don't use xcb_get_extension_data here to avoid having to link to xcb_dri2
- static const std::string DRI2 = "DRI2";
- sf::priv::ScopedXcbPtr<xcb_query_extension_reply_t> driExt(xcb_query_extension_reply(
+ sf::priv::ScopedXcbPtr<xcb_query_extension_reply_t> extension(xcb_query_extension_reply(
connection,
xcb_query_extension(
connection,
- DRI2.size(),
- DRI2.c_str()
+ name.size(),
+ name.c_str()
),
&error
));
@@ -259,14 +263,14 @@ namespace
// Close the connection with the X server
sf::priv::CloseConnection(connection);
- if (error || !driExt || !driExt->present)
+ if (error || !extension || !extension->present)
{
xcb_query_extension_reply_t reply;
std::memset(&reply, 0, sizeof(reply));
return reply;
}
- return *driExt.get();
+ return *extension.get();
}
void dumpXcbExtensions()
@@ -1926,12 +1930,21 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
if (passEvent(windowEvent, reinterpret_cast<xcb_configure_notify_event_t*>(windowEvent)->window))
return false;
+ // X notifies about "window configuration events", which also includes moving a window only. Check
+ // for a different size and only spawn a Resized event when it differs.
xcb_configure_notify_event_t* e = reinterpret_cast<xcb_configure_notify_event_t*>(windowEvent);
- Event event;
- event.type = Event::Resized;
- event.size.width = e->width;
- event.size.height = e->height;
- pushEvent(event);
+
+ if (e->width != m_previousSize.x || e->height != m_previousSize.y)
+ {
+ m_previousSize.x = e->width;
+ m_previousSize.y = e->height;
+
+ Event event;
+ event.type = Event::Resized;
+ event.size.width = e->width;
+ event.size.height = e->height;
+ pushEvent(event);
+ }
break;
}
@@ -2251,8 +2264,18 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
// Handle any extension events first
+ // SHAPE
+ // Ubuntu's Unity desktop environment makes use of the
+ // Compiz compositing window manager
+ // Compiz seems to send SHAPE events to windows even if they
+ // did not specifically select those events
+ // We ignore those events here in order to not generate warnings
+ static xcb_query_extension_reply_t shapeExtension = getXExtension("SHAPE");
+ if (shapeExtension.present && (responseType == shapeExtension.first_event))
+ break;
+
// DRI2
- static xcb_query_extension_reply_t driExtension = getDriExtension();
+ static xcb_query_extension_reply_t driExtension = getXExtension("DRI2");
if (driExtension.present)
{
// Because we are using the XCB event queue instead of the Xlib event
@@ -2302,6 +2325,57 @@ bool WindowImplX11::processEvent(xcb_generic_event_t* windowEvent)
}
}
+ // XKEYBOARD
+ // When the X server sends us XKEYBOARD events, it means that
+ // the user probably changed the layout of their keyboard
+ // We update our keymaps in that case
+ static xcb_query_extension_reply_t xkeyboardExtension = getXExtension("XKEYBOARD");
+ if (xkeyboardExtension.present && (responseType == xkeyboardExtension.first_event))
+ {
+ // We do this so we don't have to include the xkb header for the struct declaration
+ uint8_t xkbType = reinterpret_cast<const uint8_t*>(windowEvent)[1];
+
+ // We only bother rebuilding our maps if the xkb mapping actually changes
+ if ((xkbType == XCB_XKB_NEW_KEYBOARD_NOTIFY) || (xkbType == XCB_XKB_MAP_NOTIFY))
+ {
+ // keysym map
+ buildKeysymMap();
+
+ // keycode to SFML
+ buildMap();
+
+ // SFML to keycode
+ InputImpl::buildMap();
+
+ // XInputMethod expects keyboard mapping changes to be propagated to it
+ // Same idea here as with the DRI2 events above
+
+ // We lock/unlock the display to protect against concurrent access
+ XLockDisplay(m_display);
+
+ typedef Bool (*wireEventHandler)(Display*, XEvent*, xEvent*);
+
+ // Probe for any handlers that are registered for this event type
+ wireEventHandler handler = XESetWireToEvent(m_display, responseType, 0);
+
+ if (handler)
+ {
+ // Restore the previous handler if one was registered
+ XESetWireToEvent(m_display, responseType, handler);
+
+ XEvent event;
+ windowEvent->sequence = LastKnownRequestProcessed(m_display);
+
+ // Pretend to be the Xlib event queue
+ handler(m_display, &event, reinterpret_cast<xEvent*>(windowEvent));
+ }
+
+ XUnlockDisplay(m_display);
+ }
+
+ break;
+ }
+
// Print any surprises to stderr (would be nice if people report when this happens)
dumpUnhandledEvent(responseType);