From 89cf033a9268570d7adc2b99cfb5b7a7770a4682 Mon Sep 17 00:00:00 2001 From: "Marty E. Plummer" Date: Wed, 11 Apr 2018 04:26:44 -0500 Subject: [PATCH 01/39] cmake/Macros.cmake: ex:->examples: vim interprets the # ex: comments as a modeline, which causes editing this file with vim to throw an error. Signed-off-by: Marty E. Plummer --- cmake/Macros.cmake | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index be523459..91a1631b 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -1,7 +1,7 @@ include(CMakeParseArguments) # set the appropriate standard library on each platform for the given target -# ex: sfml_set_stdlib(sfml-system) +# example: sfml_set_stdlib(sfml-system) function(sfml_set_stdlib target) # for gcc >= 4.0 on Windows, apply the SFML_USE_STATIC_STD_LIBS option if it is enabled if(SFML_OS_WINDOWS AND SFML_COMPILER_GCC AND NOT SFML_GCC_VERSION VERSION_LESS "4") @@ -23,9 +23,9 @@ function(sfml_set_stdlib target) endfunction() # add a new target which is a SFML library -# ex: sfml_add_library(sfml-graphics -# SOURCES sprite.cpp image.cpp ... -# [STATIC]) # Always create a static library and ignore BUILD_SHARED_LIBS +# example: sfml_add_library(sfml-graphics +# SOURCES sprite.cpp image.cpp ... +# [STATIC]) # Always create a static library and ignore BUILD_SHARED_LIBS macro(sfml_add_library target) # parse the arguments @@ -178,11 +178,11 @@ macro(sfml_add_library target) endmacro() # add a new target which is a SFML example -# ex: sfml_add_example(ftp -# SOURCES ftp.cpp ... -# BUNDLE_RESOURCES MainMenu.nib ... # Files to be added in target but not installed next to the executable -# DEPENDS sfml-network -# RESOURCES_DIR resources) # A directory to install next to the executable and sources +# example: sfml_add_example(ftp +# SOURCES ftp.cpp ... +# BUNDLE_RESOURCES MainMenu.nib ... # Files to be added in target but not installed next to the executable +# DEPENDS sfml-network +# RESOURCES_DIR resources) # A directory to install next to the executable and sources macro(sfml_add_example target) # parse the arguments From bd7f30d0ba4597dda7a4574f1a6c9c87f8f0b726 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Tue, 15 May 2018 15:48:46 +0100 Subject: [PATCH 02/39] Install CMake config files into lib${LIB_SIFFIX} --- cmake/Macros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index 91a1631b..63490245 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -320,7 +320,7 @@ function(sfml_export_targets) if (SFML_BUILD_FRAMEWORKS) set(config_package_location "SFML.framework/Resources/CMake") else() - set(config_package_location lib/cmake/SFML) + set(config_package_location lib${LIB_SUFFIX}/cmake/SFML) endif() configure_package_config_file("${CURRENT_DIR}/SFMLConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/SFMLConfig.cmake" INSTALL_DESTINATION "${config_package_location}") From 8fea4fbfb426b95fdf3612afbafef75284460b97 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Wed, 16 May 2018 01:26:17 +0200 Subject: [PATCH 03/39] Postpone generation of the RenderTarget ID to RenderTarget::initialize() so that a new ID is generated whenever the RenderTarget is re-create()ed. --- src/SFML/Graphics/RenderTarget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp index 7eccf829..59e9e202 100644 --- a/src/SFML/Graphics/RenderTarget.cpp +++ b/src/SFML/Graphics/RenderTarget.cpp @@ -129,7 +129,7 @@ RenderTarget::RenderTarget() : m_defaultView(), m_view (), m_cache (), -m_id (getUniqueId()) +m_id (0) { m_cache.glStatesSet = false; } @@ -547,6 +547,10 @@ void RenderTarget::initialize() // Set GL states only on first draw, so that we don't pollute user's states m_cache.glStatesSet = false; + + // Generate a unique ID for this RenderTarget to track + // whether it is active within a specific context + m_id = getUniqueId(); } From f3d7468372242091efd47f7fd532424fdc818847 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Fri, 18 May 2018 01:29:53 +0200 Subject: [PATCH 04/39] Fixed RenderTextureImplFBO's destructor incorrectly triggering deletion of other RenderTextureImplFBOs' active FBOs even when the context they reside in isn't being destroyed. --- src/SFML/Graphics/RenderTextureImplFBO.cpp | 28 +++++++++++++++------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/SFML/Graphics/RenderTextureImplFBO.cpp b/src/SFML/Graphics/RenderTextureImplFBO.cpp index 301aa043..4a4f1f62 100644 --- a/src/SFML/Graphics/RenderTextureImplFBO.cpp +++ b/src/SFML/Graphics/RenderTextureImplFBO.cpp @@ -53,6 +53,23 @@ namespace // Mutex to protect both active and stale frame buffer sets sf::Mutex mutex; + // This function is called either when a RenderTextureImplFBO is + // destroyed or via contextDestroyCallback when context destruction + // might trigger deletion of its contained stale FBOs + void destroyStaleFBOs() + { + sf::Uint64 contextId = sf::Context::getActiveContextId(); + + for (std::set >::iterator iter = staleFrameBuffers.begin(); iter != staleFrameBuffers.end(); ++iter) + { + if (iter->first == contextId) + { + GLuint frameBuffer = static_cast(iter->second); + glCheck(GLEXT_glDeleteFramebuffers(1, &frameBuffer)); + } + } + } + // Callback that is called every time a context is destroyed void contextDestroyCallback(void* arg) { @@ -79,14 +96,7 @@ namespace } // Destroy stale frame buffer objects - for (std::set >::iterator iter = staleFrameBuffers.begin(); iter != staleFrameBuffers.end(); ++iter) - { - if (iter->first == contextId) - { - GLuint frameBuffer = static_cast(iter->second); - glCheck(GLEXT_glDeleteFramebuffers(1, &frameBuffer)); - } - } + destroyStaleFBOs(); } } @@ -150,7 +160,7 @@ RenderTextureImplFBO::~RenderTextureImplFBO() staleFrameBuffers.insert(std::make_pair(iter->first, iter->second)); // Clean up FBOs - contextDestroyCallback(0); + destroyStaleFBOs(); // Delete the backup context if we had to create one delete m_context; From 6e84b2d97df906990f1df3a5cef1ef7d921a112a Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 20 May 2018 23:42:20 +0200 Subject: [PATCH 05/39] Fixed RenderWindow::setActive incorrectly trying to unbind an FBO during deactivation. --- src/SFML/Graphics/RenderWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 906363b3..446e9060 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -81,7 +81,7 @@ bool RenderWindow::setActive(bool active) // If FBOs are available, make sure none are bound when we // try to draw to the default framebuffer of the RenderWindow - if (result && priv::RenderTextureImplFBO::isAvailable()) + if (active && result && priv::RenderTextureImplFBO::isAvailable()) { priv::RenderTextureImplFBO::unbind(); From b9303866a6ea0b7ed7d9ae641f26d9752b306cfe Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 3 Jun 2018 19:40:30 +0200 Subject: [PATCH 06/39] Fixed RenderTexture::display() dereferencing a NULL pointer when being called before RenderTexture::create(). --- src/SFML/Graphics/RenderTexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SFML/Graphics/RenderTexture.cpp b/src/SFML/Graphics/RenderTexture.cpp index 0805627b..51abee92 100644 --- a/src/SFML/Graphics/RenderTexture.cpp +++ b/src/SFML/Graphics/RenderTexture.cpp @@ -161,7 +161,7 @@ bool RenderTexture::setActive(bool active) void RenderTexture::display() { // Update the target texture - if (priv::RenderTextureImplFBO::isAvailable() || setActive(true)) + if (m_impl && (priv::RenderTextureImplFBO::isAvailable() || setActive(true))) { m_impl->updateTexture(m_texture.m_texture); m_texture.m_pixelsFlipped = true; From 4a41f37d5d0c8b3be91205f3e4e21671a7cf3f63 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 3 Jun 2018 18:55:23 +0200 Subject: [PATCH 07/39] Fixed stale FBOs not being erased from the staleFramebuffers set after they have been deleted. --- src/SFML/Graphics/RenderTextureImplFBO.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SFML/Graphics/RenderTextureImplFBO.cpp b/src/SFML/Graphics/RenderTextureImplFBO.cpp index 4a4f1f62..c0debd79 100644 --- a/src/SFML/Graphics/RenderTextureImplFBO.cpp +++ b/src/SFML/Graphics/RenderTextureImplFBO.cpp @@ -60,12 +60,18 @@ namespace { sf::Uint64 contextId = sf::Context::getActiveContextId(); - for (std::set >::iterator iter = staleFrameBuffers.begin(); iter != staleFrameBuffers.end(); ++iter) + for (std::set >::iterator iter = staleFrameBuffers.begin(); iter != staleFrameBuffers.end();) { if (iter->first == contextId) { GLuint frameBuffer = static_cast(iter->second); glCheck(GLEXT_glDeleteFramebuffers(1, &frameBuffer)); + + staleFrameBuffers.erase(iter++); + } + else + { + ++iter; } } } From 33c26dd6e6681b6544ad029c39c59b193d2b96b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Sat, 9 Jun 2018 11:45:16 +0200 Subject: [PATCH 08/39] Fixed performance issue with reading WAV files Calling tell() and thus std::ftell() for every reading iteration ate up 80-90% of the whole read call. By manually tracking the current position the calls to tell() can be safely removed. --- src/SFML/Audio/SoundFileReaderWav.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SFML/Audio/SoundFileReaderWav.cpp b/src/SFML/Audio/SoundFileReaderWav.cpp index dc1dc52b..84d92c1e 100644 --- a/src/SFML/Audio/SoundFileReaderWav.cpp +++ b/src/SFML/Audio/SoundFileReaderWav.cpp @@ -155,7 +155,11 @@ Uint64 SoundFileReaderWav::read(Int16* samples, Uint64 maxCount) assert(m_stream); Uint64 count = 0; - while ((count < maxCount) && (static_cast(m_stream->tell()) < m_dataEnd)) + Uint64 startPos = m_stream->tell(); + + // Tracking of m_dataEnd is important to prevent sf::Music from reading + // data until EOF, as WAV files may have metadata at the end. + while ((count < maxCount) && (startPos + count * m_bytesPerSample < m_dataEnd)) { switch (m_bytesPerSample) { From f843097fbe46381813086ee613f749b8c9f556e3 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Tue, 15 May 2018 23:28:32 +0200 Subject: [PATCH 09/39] Fixed the Unix clipboard implementation causing an abort due to internal data races in Xlib. --- include/SFML/Window/Clipboard.hpp | 19 +- src/SFML/Window/Unix/ClipboardImpl.cpp | 523 +++++++++++++++---------- src/SFML/Window/Unix/ClipboardImpl.hpp | 78 ++++ src/SFML/Window/Unix/WindowImplX11.cpp | 4 + 4 files changed, 420 insertions(+), 204 deletions(-) diff --git a/include/SFML/Window/Clipboard.hpp b/include/SFML/Window/Clipboard.hpp index 436da8f9..50ea8042 100644 --- a/include/SFML/Window/Clipboard.hpp +++ b/include/SFML/Window/Clipboard.hpp @@ -60,7 +60,12 @@ public: /// This function sets the content of the clipboard as a /// string. /// - /// \param text sf::String containing the data to be sent + /// \warning Due to limitations on some operating systems, + /// setting the clipboard contents is only + /// guaranteed to work if there is currently an + /// open window for which events are being handled. + /// + /// \param text sf::String containing the data to be sent /// to the clipboard /// //////////////////////////////////////////////////////////// @@ -80,6 +85,11 @@ public: /// sf::Clipboard provides an interface for getting and /// setting the contents of the system clipboard. /// +/// It is important to note that due to limitations on some +/// operating systems, setting the clipboard contents is +/// only guaranteed to work if there is currently an open +/// window for which events are being handled. +/// /// Usage example: /// \code /// // get the clipboard content as a string @@ -96,11 +106,12 @@ public: /// // Using Ctrl + V to paste a string into SFML /// if(event.key.control && event.key.code == sf::Keyboard::V) /// string = sf::Clipboard::getString(); +/// +/// // Using Ctrl + C to copy a string out of SFML +/// if(event.key.control && event.key.code == sf::Keyboard::C) +/// sf::Clipboard::setString("Hello World!"); /// } /// } -/// -/// // set the clipboard to a string -/// sf::Clipboard::setString("Hello World!"); /// \endcode /// /// \see sf::String, sf::Event diff --git a/src/SFML/Window/Unix/ClipboardImpl.cpp b/src/SFML/Window/Unix/ClipboardImpl.cpp index 32ef21bc..df2fd954 100644 --- a/src/SFML/Window/Unix/ClipboardImpl.cpp +++ b/src/SFML/Window/Unix/ClipboardImpl.cpp @@ -27,143 +27,20 @@ //////////////////////////////////////////////////////////// #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include namespace { -//////////////////////////////////////////////////////////// -void initClipboard(); -void* hostSelection(void*); - -sf::String string; - -pthread_mutex_t mutex; -pthread_t host_thread; - -bool is_fail = false; -bool is_init = false; -bool is_host = false; - -Display* display = NULL; -Window window = 0; - -Atom selection = 0; -Atom atom_targ = 0; -Atom atom_text = 0; -Atom utf8_text = 0; -int xa_string = 31; -int xa_atom = 4; - -//////////////////////////////////////////////////////////// -void initClipboard() -{ - is_init = true; - - display = XOpenDisplay(NULL); - int screen = DefaultScreen(display); - window = XCreateSimpleWindow(display, RootWindow(display, screen), - 0, 0, 1, 1, 0, BlackPixel(display, screen), WhitePixel(display, screen)); - - selection = XInternAtom(display, "CLIPBOARD", false); - atom_targ = XInternAtom(display, "TARGETS", false); - atom_text = XInternAtom(display, "TEXT", false); - utf8_text = XInternAtom(display, "UTF8_STRING", true); - - if(utf8_text == None) + // Filter the events received by windows (only allow those matching a specific window) + Bool checkEvent(::Display*, XEvent* event, XPointer userData) { - std::cerr << "UTF-8 format unavailable on clipboard." << std::endl; - utf8_text = xa_string; + // Just check if the event matches the window + return event->xany.window == reinterpret_cast< ::Window >(userData); } - - if(pthread_mutex_init(&mutex, NULL)) - { - is_fail = true; - std::cerr << "Unable to initialize mutex. Failed to initialize clipboard." << std::endl; - return; - } - - if(pthread_create(&host_thread, NULL, hostSelection, NULL)) - { - is_fail = true; - std::cerr << "Unable to create host thread. Failed to initialize clipboard." << std::endl; - return; - } -} - -//////////////////////////////////////////////////////////// -void* hostSelection(void*) -{ - while(true) - { - if(XPending(display) && is_host) - { - XEvent event; - - pthread_mutex_lock(&mutex); - XNextEvent(display, &event); - pthread_mutex_unlock(&mutex); - - switch(event.type) - { - case SelectionClear: - { - pthread_mutex_lock(&mutex); - is_host = false; - pthread_mutex_unlock(&mutex); - - break; - } - case SelectionRequest: - { - if(event.xselectionrequest.selection == selection) - { - XSelectionRequestEvent* sel_req_event = &event.xselectionrequest; - XSelectionEvent sel_event = {0}; - - int result = 0; - sel_event.type = SelectionNotify, - sel_event.display = sel_req_event->display, - sel_event.requestor = sel_req_event->requestor, - sel_event.selection = sel_req_event->selection, - sel_event.time = sel_req_event->time, - sel_event.target = sel_req_event->target, - sel_event.property = sel_req_event->property; - - std::basic_string str = string.toUtf8(); - - if(sel_event.target == atom_targ) - result = XChangeProperty(sel_event.display, sel_event.requestor, - sel_event.property, xa_atom, 32, PropModeReplace, - reinterpret_cast(&utf8_text), 1); - else if(sel_event.target == xa_string || sel_event.target == atom_text) - result = XChangeProperty(sel_event.display, sel_event.requestor, - sel_event.property, xa_string, 8, PropModeReplace, - reinterpret_cast(&str[0]), str.size()); - else if(sel_event.target == utf8_text) - result = XChangeProperty(sel_event.display, sel_event.requestor, - sel_event.property, utf8_text, 8, PropModeReplace, - reinterpret_cast(&str[0]), str.size()); - else - sel_event.property = None; - - if((result & 2) == 0) - XSendEvent(display, sel_event.requestor, 0, 0, - reinterpret_cast(&sel_event)); - } - break; - } - default: break; - } - } - else - sf::sleep(sf::milliseconds(20)); - } -} } namespace sf @@ -174,86 +51,332 @@ namespace priv //////////////////////////////////////////////////////////// String ClipboardImpl::getString() { - if(!is_init) - initClipboard(); - - if(is_fail || is_host) - return string; - - // Dangerous! Wipes all previous events! - XSync(display, true); - XConvertSelection(display, selection, utf8_text, atom_text, window, CurrentTime); - - XEvent event; - - pthread_mutex_lock(&mutex); - XNextEvent(display, &event); - pthread_mutex_unlock(&mutex); - - if(event.type == SelectionNotify) - { - if(event.xselection.selection != selection || event.xselection.target != utf8_text) - { - std::cerr << "Failed to convert selection." << std::endl; - return string; - } - - if(event.xselection.property) - { - Atom target; - int format; - unsigned long size; - unsigned long byte_left; - unsigned char* data; - - XGetWindowProperty(event.xselection.display, - event.xselection.requestor, event.xselection.property, - 0L, (~0L), false, AnyPropertyType, - &target, &format, &size, &byte_left, &data); - - if(target == utf8_text) - { - std::basic_string str(data, size); - string = sf::String::fromUtf8(str.begin(), str.end()); - - XFree(data); - } - - XDeleteProperty(event.xselection.display, event.xselection.requestor, event.xselection.property); - } - } - - return string; + return getInstance().getStringImpl(); } //////////////////////////////////////////////////////////// void ClipboardImpl::setString(const String& text) { - if(!is_init) - initClipboard(); + getInstance().setStringImpl(text); +} - if(is_fail) - return; - if(!is_host) +//////////////////////////////////////////////////////////// +void ClipboardImpl::processEvents() +{ + getInstance().processEventsImpl(); +} + + +//////////////////////////////////////////////////////////// +ClipboardImpl::ClipboardImpl() : +m_window (0), +m_requestResponded(false) +{ + // Open a connection with the X server + m_display = OpenDisplay(); + + // Get the atoms we need to make use of the clipboard + m_clipboard = getAtom("CLIPBOARD", false); + m_targets = getAtom("TARGETS", false); + m_text = getAtom("TEXT", false); + m_utf8String = getAtom("UTF8_STRING", true ); + m_targetProperty = getAtom("SFML_CLIPBOARD_TARGET_PROPERTY", false); + + // Create a hidden window that will broker our clipboard interactions with X + m_window = XCreateSimpleWindow(m_display, DefaultRootWindow(m_display), 0, 0, 1, 1, 0, 0, 0); + + // Register the events we are interested in + XSelectInput(m_display, m_window, SelectionNotify | SelectionClear | SelectionRequest); +} + + +//////////////////////////////////////////////////////////// +ClipboardImpl::~ClipboardImpl() +{ + // Destroy the window + if (m_window) { - XSetSelectionOwner(display, selection, window, CurrentTime); - - if(XGetSelectionOwner(display, selection) != window) - { - std::cerr << "Unable to get ownership of selection." << std::endl; - return; - } - - pthread_mutex_lock(&mutex); - is_host = true; - pthread_mutex_unlock(&mutex); + XDestroyWindow(m_display, m_window); + XFlush(m_display); } - pthread_mutex_lock(&mutex); - string = text; - pthread_mutex_unlock(&mutex); + // Close the connection with the X server + CloseDisplay(m_display); +} + + +//////////////////////////////////////////////////////////// +ClipboardImpl& ClipboardImpl::getInstance() +{ + static ClipboardImpl instance; + + return instance; +} + + +//////////////////////////////////////////////////////////// +String ClipboardImpl::getStringImpl() +{ + // Check if anybody owns the current selection + if (XGetSelectionOwner(m_display, m_clipboard) == None) + { + m_clipboardContents.clear(); + + return m_clipboardContents; + } + + // Process any already pending events + processEvents(); + + m_requestResponded = false; + + // Request the current selection to be converted to UTF-8 (or STRING + // if UTF-8 is not available) and written to our window property + XConvertSelection( + m_display, + m_clipboard, + (m_utf8String != None) ? m_utf8String : XA_STRING, + m_targetProperty, + m_window, + CurrentTime + ); + + Clock clock; + + // Wait for a response for up to 1000ms + while (!m_requestResponded && (clock.getElapsedTime().asMilliseconds() < 1000)) + processEvents(); + + // If no response was received within the time period, clear our clipboard contents + if (!m_requestResponded) + m_clipboardContents.clear(); + + return m_clipboardContents; +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::setStringImpl(const String& text) +{ + m_clipboardContents = text; + + // Set our window as the current owner of the selection + XSetSelectionOwner(m_display, m_clipboard, m_window, CurrentTime); + + // Check if setting the selection owner was successful + if (XGetSelectionOwner(m_display, m_clipboard) != m_window) + err() << "Cannot set clipboard string: Unable to get ownership of X selection" << std::endl; +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::processEventsImpl() +{ + XEvent event; + + // Pick out the events that are interesting for this window + while (XCheckIfEvent(m_display, &event, &checkEvent, reinterpret_cast(m_window))) + m_events.push_back(event); + + // Handle the events for this window that we just picked out + while (!m_events.empty()) + { + event = m_events.front(); + m_events.pop_front(); + processEvent(event); + } +} + + +//////////////////////////////////////////////////////////// +void ClipboardImpl::processEvent(XEvent& windowEvent) +{ + switch (windowEvent.type) + { + case SelectionClear: + { + // We don't have any resources we need to clean up + // when losing selection ownership so we don't do + // anything when we receive SelectionClear + // We will still respond to any future SelectionRequest + // events since doing so doesn't really do any harm + break; + } + case SelectionNotify: + { + // Notification that the current selection owner + // has responded to our request + + XSelectionEvent& selectionEvent = *reinterpret_cast(&windowEvent.xselection); + + m_clipboardContents.clear(); + + // If retrieving the selection fails or conversion is unsuccessful + // we leave the contents of the clipboard empty since we don't + // own it and we don't know what it could currently be + if ((selectionEvent.property == None) || (selectionEvent.selection != m_clipboard)) + break; + + Atom type; + int format; + unsigned long items; + unsigned long remainingBytes; + unsigned char* data = 0; + + // The selection owner should have wrote the selection + // data to the specified window property + int result = XGetWindowProperty( + m_display, + m_window, + m_targetProperty, + 0, + 0x7fffffff, + False, + AnyPropertyType, + &type, + &format, + &items, + &remainingBytes, + &data + ); + + if (result == Success) + { + // We don't support INCR for now + // It is very unlikely that this will be returned + // for purely text data transfer anyway + if (type != getAtom("INCR", false)) + { + // Only copy the data if the format is what we expect + if ((type == m_utf8String) && (format == 8)) + { + m_clipboardContents = String::fromUtf8(data, data + items); + } + else if ((type == XA_STRING) && (format == 8)) + { + // Convert from ANSI std::string to sf::String + m_clipboardContents = std::string(data, data + items); + } + } + + XFree(data); + + // The selection requestor must always delete the property themselves + XDeleteProperty(m_display, m_window, m_targetProperty); + } + + m_requestResponded = true; + + break; + } + case SelectionRequest: + { + // Respond to a request for our clipboard contents + XSelectionRequestEvent& selectionRequestEvent = *reinterpret_cast(&windowEvent.xselectionrequest); + + // Our reply + XSelectionEvent selectionEvent; + + selectionEvent.type = SelectionNotify; + selectionEvent.requestor = selectionRequestEvent.requestor; + selectionEvent.selection = selectionRequestEvent.selection; + selectionEvent.property = selectionRequestEvent.property; + selectionEvent.time = selectionRequestEvent.time; + + if (selectionRequestEvent.selection == m_clipboard) + { + if (selectionRequestEvent.target == m_targets) + { + // Respond to a request for our valid conversion targets + std::vector targets; + + targets.push_back(m_targets); + targets.push_back(m_text); + targets.push_back(XA_STRING); + + if (m_utf8String != None) + targets.push_back(m_utf8String); + + XChangeProperty( + m_display, + selectionRequestEvent.requestor, + selectionRequestEvent.property, + XA_ATOM, + 32, + PropModeReplace, + reinterpret_cast(&targets[0]), + targets.size() + ); + + // Notify the requestor that they can read the targets from their window property + selectionEvent.target = m_targets; + + XSendEvent(m_display, selectionRequestEvent.requestor, True, NoEventMask, reinterpret_cast(&selectionEvent)); + + break; + } + else if ((selectionRequestEvent.target == XA_STRING) || ((m_utf8String == None) && (selectionRequestEvent.target == m_text))) + { + // Respond to a request for conversion to a Latin-1 string + std::string data = m_clipboardContents.toAnsiString(); + + XChangeProperty( + m_display, + selectionRequestEvent.requestor, + selectionRequestEvent.property, + XA_STRING, + 8, + PropModeReplace, + reinterpret_cast(data.c_str()), + data.size() + ); + + // Notify the requestor that they can read the data from their window property + selectionEvent.target = XA_STRING; + + XSendEvent(m_display, selectionRequestEvent.requestor, True, NoEventMask, reinterpret_cast(&selectionEvent)); + + break; + } + else if ((m_utf8String != None) && ((selectionRequestEvent.target == m_utf8String) || (selectionRequestEvent.target == m_text))) + { + // Respond to a request for conversion to a UTF-8 string + // or an encoding of our choosing (we always choose UTF-8) + std::basic_string data = m_clipboardContents.toUtf8(); + + XChangeProperty( + m_display, + selectionRequestEvent.requestor, + selectionRequestEvent.property, + m_utf8String, + 8, + PropModeReplace, + reinterpret_cast(data.c_str()), + data.size() + ); + + // Notify the requestor that they can read the data from their window property + selectionEvent.target = m_utf8String; + + XSendEvent(m_display, selectionRequestEvent.requestor, True, NoEventMask, reinterpret_cast(&selectionEvent)); + + break; + } + } + + // Notify the requestor that we could not respond to their request + selectionEvent.target = selectionRequestEvent.target; + selectionEvent.property = None; + + XSendEvent(m_display, selectionRequestEvent.requestor, True, NoEventMask, reinterpret_cast(&selectionEvent)); + + break; + } + default: + break; + } } } // namespace priv diff --git a/src/SFML/Window/Unix/ClipboardImpl.hpp b/src/SFML/Window/Unix/ClipboardImpl.hpp index f4aca983..48ec7876 100644 --- a/src/SFML/Window/Unix/ClipboardImpl.hpp +++ b/src/SFML/Window/Unix/ClipboardImpl.hpp @@ -29,6 +29,8 @@ // Headers //////////////////////////////////////////////////////////// #include +#include +#include namespace sf @@ -67,6 +69,82 @@ public: /// //////////////////////////////////////////////////////////// static void setString(const String& text); + + //////////////////////////////////////////////////////////// + /// \brief Process pending events for the hidden clipboard window + /// + /// This function has to be called as part of normal window + /// event processing in order for our application to respond + /// to selection requests from other applications. + /// + //////////////////////////////////////////////////////////// + static void processEvents(); + +private: + + //////////////////////////////////////////////////////////// + /// \brief Constructor + /// + //////////////////////////////////////////////////////////// + ClipboardImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Destructor + /// + //////////////////////////////////////////////////////////// + ~ClipboardImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Get singleton instance + /// + /// \return Singleton instance + /// + //////////////////////////////////////////////////////////// + static ClipboardImpl& getInstance(); + + //////////////////////////////////////////////////////////// + /// \brief getString implementation + /// + /// \return Current content of the clipboard + /// + //////////////////////////////////////////////////////////// + String getStringImpl(); + + //////////////////////////////////////////////////////////// + /// \brief setString implementation + /// + /// \param text sf::String object containing the data to be sent to the clipboard + /// + //////////////////////////////////////////////////////////// + void setStringImpl(const String& text); + + //////////////////////////////////////////////////////////// + /// \brief processEvents implementation + /// + //////////////////////////////////////////////////////////// + void processEventsImpl(); + + //////////////////////////////////////////////////////////// + /// \brief Process an incoming event from the window + /// + /// \param windowEvent Event which has been received + /// + //////////////////////////////////////////////////////////// + void processEvent(XEvent& windowEvent); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + ::Window m_window; ///< X identifier defining our window + ::Display* m_display; ///< Pointer to the display + Atom m_clipboard; ///< X Atom identifying the CLIPBOARD selection + Atom m_targets; ///< X Atom identifying TARGETS + Atom m_text; ///< X Atom identifying TEXT + Atom m_utf8String; ///< X Atom identifying UTF8_STRING + Atom m_targetProperty; ///< X Atom identifying our destination window property + String m_clipboardContents; ///< Our clipboard contents + std::deque m_events; ///< Queue we use to store pending events for this window + bool m_requestResponded; ///< Holds whether our selection request has been responded to or not }; } // namespace priv diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index e2c8d290..ee5bf356 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -26,6 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include #include @@ -779,6 +780,9 @@ void WindowImplX11::processEvents() m_events.pop_front(); processEvent(event); } + + // Process clipboard window events + priv::ClipboardImpl::processEvents(); } From e26fc1bfd26c6dfd96fc8e42688079b46e48a698 Mon Sep 17 00:00:00 2001 From: Bruno Van de Velde Date: Fri, 27 Jul 2018 20:13:07 +0200 Subject: [PATCH 10/39] ANativeActivity_onCreate is not exported in sfml-main (fixes #1457) --- src/SFML/Main/MainAndroid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SFML/Main/MainAndroid.cpp b/src/SFML/Main/MainAndroid.cpp index fcb85001..fe67bbad 100644 --- a/src/SFML/Main/MainAndroid.cpp +++ b/src/SFML/Main/MainAndroid.cpp @@ -464,7 +464,7 @@ static void onLowMemory(ANativeActivity* activity) //////////////////////////////////////////////////////////// -void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) +JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) { // Create an activity states (will keep us in the know, about events we care) sf::priv::ActivityStates* states = NULL; From fd071fb4ab9d9428b324274d2b2ea9f06aa73dde Mon Sep 17 00:00:00 2001 From: "Lionel Aimerie (Pixium Digital)" Date: Sun, 22 Jul 2018 11:33:20 +0800 Subject: [PATCH 11/39] ANDROID flag fix to SFML_SYSTEM_ANDROID --- include/SFML/System/FileInputStream.hpp | 4 ++-- src/SFML/System/FileInputStream.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/SFML/System/FileInputStream.hpp b/include/SFML/System/FileInputStream.hpp index 43618da6..ca267972 100644 --- a/include/SFML/System/FileInputStream.hpp +++ b/include/SFML/System/FileInputStream.hpp @@ -35,7 +35,7 @@ #include #include -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID namespace sf { namespace priv @@ -122,7 +122,7 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID priv::ResourceStream* m_file; #else std::FILE* m_file; ///< stdio file stream diff --git a/src/SFML/System/FileInputStream.cpp b/src/SFML/System/FileInputStream.cpp index 852470de..89e77c47 100644 --- a/src/SFML/System/FileInputStream.cpp +++ b/src/SFML/System/FileInputStream.cpp @@ -26,7 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID #include #endif @@ -44,7 +44,7 @@ FileInputStream::FileInputStream() //////////////////////////////////////////////////////////// FileInputStream::~FileInputStream() { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID if (m_file) delete m_file; #else @@ -57,7 +57,7 @@ FileInputStream::~FileInputStream() //////////////////////////////////////////////////////////// bool FileInputStream::open(const std::string& filename) { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID if (m_file) delete m_file; m_file = new priv::ResourceStream(filename); @@ -76,7 +76,7 @@ bool FileInputStream::open(const std::string& filename) //////////////////////////////////////////////////////////// Int64 FileInputStream::read(void* data, Int64 size) { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID return m_file->read(data, size); #else if (m_file) @@ -90,7 +90,7 @@ Int64 FileInputStream::read(void* data, Int64 size) //////////////////////////////////////////////////////////// Int64 FileInputStream::seek(Int64 position) { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID return m_file->seek(position); #else if (m_file) @@ -111,7 +111,7 @@ Int64 FileInputStream::seek(Int64 position) //////////////////////////////////////////////////////////// Int64 FileInputStream::tell() { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID return m_file->tell(); #else if (m_file) @@ -125,7 +125,7 @@ Int64 FileInputStream::tell() //////////////////////////////////////////////////////////// Int64 FileInputStream::getSize() { -#ifdef ANDROID +#ifdef SFML_SYSTEM_ANDROID return m_file->getSize(); #else if (m_file) From 1b1ae8e48e9e6f1ecc45b34b9e3b62dc46150ebc Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Thu, 12 Apr 2018 11:58:46 -0700 Subject: [PATCH 12/39] Use default supported rotations when none are specified --- src/SFML/Window/iOS/SFAppDelegate.mm | 2 +- src/SFML/Window/iOS/SFViewController.hpp | 8 -------- src/SFML/Window/iOS/SFViewController.mm | 8 -------- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/SFML/Window/iOS/SFAppDelegate.mm b/src/SFML/Window/iOS/SFAppDelegate.mm index 6b173849..4177eb3d 100644 --- a/src/SFML/Window/iOS/SFAppDelegate.mm +++ b/src/SFML/Window/iOS/SFAppDelegate.mm @@ -173,7 +173,7 @@ namespace NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"]; if (!supportedOrientations) - return false; + return (1 << orientation) & [rootViewController supportedInterfaceOrientations]; int appFlags = 0; if ([supportedOrientations containsObject:@"UIInterfaceOrientationPortrait"]) diff --git a/src/SFML/Window/iOS/SFViewController.hpp b/src/SFML/Window/iOS/SFViewController.hpp index b8a77aad..2b65d358 100644 --- a/src/SFML/Window/iOS/SFViewController.hpp +++ b/src/SFML/Window/iOS/SFViewController.hpp @@ -55,14 +55,6 @@ //////////////////////////////////////////////////////////// - (BOOL)shouldAutorotate; -//////////////////////////////////////////////////////////// -/// \brief Returns the supported orientations (iOS >= 6) -/// -/// \return A combination of all the supported orientations -/// -//////////////////////////////////////////////////////////// -- (NSUInteger)supportedInterfaceOrientations; - //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/iOS/SFViewController.mm b/src/SFML/Window/iOS/SFViewController.mm index d8be0478..8c23cdcf 100644 --- a/src/SFML/Window/iOS/SFViewController.mm +++ b/src/SFML/Window/iOS/SFViewController.mm @@ -46,12 +46,4 @@ return self.orientationCanChange; } - -//////////////////////////////////////////////////////////// -- (NSUInteger)supportedInterfaceOrientations -{ - return UIInterfaceOrientationMaskAll; -} - - @end From 8aae69055a8af1d5468a06ea322f99d770dc1f6e Mon Sep 17 00:00:00 2001 From: Ceylo Date: Mon, 9 Apr 2018 00:19:55 +0200 Subject: [PATCH 13/39] On iOS, make sure to be notified if you forgot to include --- src/SFML/Window/iOS/SFAppDelegate.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SFML/Window/iOS/SFAppDelegate.mm b/src/SFML/Window/iOS/SFAppDelegate.mm index 4177eb3d..ea69f41e 100644 --- a/src/SFML/Window/iOS/SFAppDelegate.mm +++ b/src/SFML/Window/iOS/SFAppDelegate.mm @@ -56,6 +56,10 @@ namespace //////////////////////////////////////////////////////////// + (SFAppDelegate*)getInstance { + NSAssert(delegateInstance, + @"SFAppDelegate instance is nil, this means SFML was not properly initialized. " + "Make sure that the file defining your main() function includes "); + return delegateInstance; } From 61078aa90bc771301d38416ec0cf552b1101e999 Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Thu, 12 Apr 2018 11:48:33 -0700 Subject: [PATCH 14/39] Fix config for finding dependencies on iOS --- cmake/SFMLConfigDependencies.cmake.in | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmake/SFMLConfigDependencies.cmake.in b/cmake/SFMLConfigDependencies.cmake.in index 2f85b388..97f33c01 100644 --- a/cmake/SFMLConfigDependencies.cmake.in +++ b/cmake/SFMLConfigDependencies.cmake.in @@ -13,7 +13,11 @@ if(SFML_STATIC_LIBRARIES) elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set(FIND_SFML_OS_FREEBSD 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(FIND_SFML_OS_MACOSX 1) + if (DEFINED IOS) + set(FIND_SFML_OS_IOS 1) + else() + set(FIND_SFML_OS_MACOSX 1) + endif() endif() # start with an empty list @@ -51,7 +55,7 @@ if(SFML_STATIC_LIBRARIES) if (FIND_SFML_OS_WINDOWS) set_property(TARGET OpenGL APPEND PROPERTY INTERFACE_LINK_LIBRARIES "OpenGL32") - else() + elseif(NOT FIND_SFML_OS_IOS) sfml_bind_dependency(TARGET OpenGL FRIENDLY_NAME "OpenGL" SEARCH_NAMES "OpenGL" "GL") endif() endif() @@ -68,8 +72,10 @@ if(SFML_STATIC_LIBRARIES) sfml_bind_dependency(TARGET OpenAL FRIENDLY_NAME "OpenAL" SEARCH_NAMES "OpenAL" "openal" "openal32") sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Ogg" SEARCH_NAMES "ogg") sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Vorbis" SEARCH_NAMES "vorbis") - sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisFile" SEARCH_NAMES "vorbisfile") - sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisEnc" SEARCH_NAMES "vorbisenc") + if (NOT FIND_SFML_OS_IOS) + sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisFile" SEARCH_NAMES "vorbisfile") + sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisEnc" SEARCH_NAMES "vorbisenc") + endif() sfml_bind_dependency(TARGET FLAC FRIENDLY_NAME "FLAC" SEARCH_NAMES "FLAC") endif() From d97bbc38f23e1dcd7e3f71de7cf576b6c10b4066 Mon Sep 17 00:00:00 2001 From: Ironbell Date: Wed, 13 Jun 2018 21:09:48 +0200 Subject: [PATCH 15/39] Fixed two conversion warnings (C4267) --- src/SFML/Graphics/RenderTarget.cpp | 2 +- src/SFML/Network/TcpSocket.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SFML/Graphics/RenderTarget.cpp b/src/SFML/Graphics/RenderTarget.cpp index 59e9e202..9a6e3018 100644 --- a/src/SFML/Graphics/RenderTarget.cpp +++ b/src/SFML/Graphics/RenderTarget.cpp @@ -708,7 +708,7 @@ void RenderTarget::drawPrimitives(PrimitiveType type, std::size_t firstVertex, s GLenum mode = modes[type]; // Draw the primitives - glCheck(glDrawArrays(mode, firstVertex, static_cast(vertexCount))); + glCheck(glDrawArrays(mode, static_cast(firstVertex), static_cast(vertexCount))); } diff --git a/src/SFML/Network/TcpSocket.cpp b/src/SFML/Network/TcpSocket.cpp index e11f76b2..d8effa1c 100644 --- a/src/SFML/Network/TcpSocket.cpp +++ b/src/SFML/Network/TcpSocket.cpp @@ -246,7 +246,7 @@ Socket::Status TcpSocket::send(const void* data, std::size_t size, std::size_t& for (sent = 0; sent < size; sent += result) { // Send a chunk of data - result = ::send(getHandle(), static_cast(data) + sent, size - sent, flags); + result = ::send(getHandle(), static_cast(data) + sent, static_cast(size - sent), flags); // Check for errors if (result < 0) From a2002339a6f2ac38c86f1de1ec9232968c2f813c Mon Sep 17 00:00:00 2001 From: assematt Date: Fri, 16 Dec 2016 10:52:19 -0500 Subject: [PATCH 16/39] Fixed bug in sf::Text when applying an outline color/thickness When applying an outline thickness to sf::Text in combination with a strikethrough and/or an underlined style, the ensureGeometryUpdate function adds unwanted vertices if the string contains two consecutive '\n' charecter. To fix this we need to add an additional check in the if statements to check if both the current and previous character it's a new line character. --- src/SFML/Graphics/Text.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index 3773616d..fae7d9ac 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -444,12 +444,15 @@ void Text::ensureGeometryUpdate() const { Uint32 curChar = m_string[i]; + // Skip the \r char to avoid weird graphical issues + if (curChar == '\r') + continue; + // Apply the kerning offset x += m_font->getKerning(prevChar, curChar, m_characterSize); - prevChar = curChar; // If we're using the underlined style and there's a new line, draw a line - if (isUnderlined && (curChar == L'\n')) + if (isUnderlined && (curChar == L'\n' && prevChar != L'\n')) { addLine(m_vertices, x, y, m_fillColor, underlineOffset, underlineThickness); @@ -458,7 +461,7 @@ void Text::ensureGeometryUpdate() const } // If we're using the strike through style and there's a new line, draw a line across all characters - if (isStrikeThrough && (curChar == L'\n')) + if (isStrikeThrough && (curChar == L'\n' && prevChar != L'\n')) { addLine(m_vertices, x, y, m_fillColor, strikeThroughOffset, underlineThickness); @@ -466,6 +469,8 @@ void Text::ensureGeometryUpdate() const addLine(m_outlineVertices, x, y, m_outlineColor, strikeThroughOffset, underlineThickness, m_outlineThickness); } + prevChar = curChar; + // Handle special characters if ((curChar == L' ') || (curChar == L'\n') || (curChar == L'\t')) { From 0c4443a2c1cd63bb8f1634f1a5ea4bd27fc35188 Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Sun, 29 Jul 2018 09:25:48 +0200 Subject: [PATCH 17/39] Squash duplicated sf::Font glyphs to single chars Before this change, `sf::Font` always rendered/provided one character per Unicode codepoint, even if that character wasn't represented by the current font file or duplicated. This caused more texture space to be used than necessary, which is especially apparent, when trying to render a large amount of unhandled glyphs (the texture would literally fill up with empty squares representing missing characters). --- src/SFML/Graphics/Font.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index 45f6baf8..b6f5c604 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -71,10 +71,10 @@ namespace return output; } - // Combine outline thickness, boldness and codepoint into a single 64-bit key - sf::Uint64 combine(float outlineThickness, bool bold, sf::Uint32 codePoint) + // Combine outline thickness, boldness and font glyph index into a single 64-bit key + sf::Uint64 combine(float outlineThickness, bool bold, sf::Uint32 index) { - return (static_cast(reinterpret(outlineThickness)) << 32) | (static_cast(bold) << 31) | codePoint; + return (static_cast(reinterpret(outlineThickness)) << 32) | (static_cast(bold) << 31) | index; } } @@ -346,8 +346,8 @@ const Glyph& Font::getGlyph(Uint32 codePoint, unsigned int characterSize, bool b // Get the page corresponding to the character size GlyphTable& glyphs = m_pages[characterSize].glyphs; - // Build the key by combining the code point, bold flag, and outline thickness - Uint64 key = combine(outlineThickness, bold, codePoint); + // Build the key by combining the glyph index (based on code point), bold flag, and outline thickness + Uint64 key = combine(outlineThickness, bold, FT_Get_Char_Index(static_cast(m_face), codePoint)); // Search the glyph into the cache GlyphTable::const_iterator it = glyphs.find(key); From cf34f4ae101c571d27302849c6761e06aa9d0a65 Mon Sep 17 00:00:00 2001 From: Radek Dutkiewicz Date: Mon, 11 Jun 2018 13:00:21 +0100 Subject: [PATCH 18/39] Fixed glyph cropping on sub-pixel positioning of text Added 1 pixel padding for glyph uv's and increased glyph quads boundaries by 1 pixel so the glyphs aren't cropped when text is being scrolled with sub-pixel increments --- src/SFML/Graphics/Font.cpp | 1 + src/SFML/Graphics/Text.cpp | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index b6f5c604..cafba5ba 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -727,6 +727,7 @@ IntRect Font::findGlyphRect(Page& page, unsigned int width, unsigned int height) // Make the texture 2 times bigger Texture newTexture; newTexture.create(textureWidth * 2, textureHeight * 2); + newTexture.setSmooth(true); newTexture.update(page.texture); page.texture.swap(newTexture); } diff --git a/src/SFML/Graphics/Text.cpp b/src/SFML/Graphics/Text.cpp index fae7d9ac..66875513 100644 --- a/src/SFML/Graphics/Text.cpp +++ b/src/SFML/Graphics/Text.cpp @@ -50,15 +50,17 @@ namespace // Add a glyph quad to the vertex array void addGlyphQuad(sf::VertexArray& vertices, sf::Vector2f position, const sf::Color& color, const sf::Glyph& glyph, float italicShear, float outlineThickness = 0) { - float left = glyph.bounds.left; - float top = glyph.bounds.top; - float right = glyph.bounds.left + glyph.bounds.width; - float bottom = glyph.bounds.top + glyph.bounds.height; + float padding = 1.0; - float u1 = static_cast(glyph.textureRect.left); - float v1 = static_cast(glyph.textureRect.top); - float u2 = static_cast(glyph.textureRect.left + glyph.textureRect.width); - float v2 = static_cast(glyph.textureRect.top + glyph.textureRect.height); + float left = glyph.bounds.left - padding; + float top = glyph.bounds.top - padding; + float right = glyph.bounds.left + glyph.bounds.width + padding; + float bottom = glyph.bounds.top + glyph.bounds.height + padding; + + float u1 = static_cast(glyph.textureRect.left) - padding; + float v1 = static_cast(glyph.textureRect.top) - padding; + float u2 = static_cast(glyph.textureRect.left + glyph.textureRect.width) + padding; + float v2 = static_cast(glyph.textureRect.top + glyph.textureRect.height) + padding; vertices.append(sf::Vertex(sf::Vector2f(position.x + left - italicShear * top - outlineThickness, position.y + top - outlineThickness), color, sf::Vector2f(u1, v1))); vertices.append(sf::Vertex(sf::Vector2f(position.x + right - italicShear * top - outlineThickness, position.y + top - outlineThickness), color, sf::Vector2f(u2, v1))); From 0423bc4013b4d6571db2aeaaeda50969653fc730 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Thu, 5 Jul 2018 12:10:39 +0200 Subject: [PATCH 19/39] Reduced context locking&unlocking while creating textures --- src/SFML/Graphics/Texture.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/SFML/Graphics/Texture.cpp b/src/SFML/Graphics/Texture.cpp index faeef7d7..fd94acf1 100644 --- a/src/SFML/Graphics/Texture.cpp +++ b/src/SFML/Graphics/Texture.cpp @@ -129,6 +129,11 @@ bool Texture::create(unsigned int width, unsigned int height) return false; } + TransientContextLock lock; + + // Make sure that extensions are initialized + priv::ensureExtensionsInit(); + // Compute the internal texture dimensions depending on NPOT textures support Vector2u actualSize(getValidSize(width), getValidSize(height)); @@ -150,8 +155,6 @@ bool Texture::create(unsigned int width, unsigned int height) m_pixelsFlipped = false; m_fboAttachment = false; - TransientContextLock lock; - // Create the OpenGL texture if it doesn't exist yet if (!m_texture) { @@ -160,9 +163,6 @@ bool Texture::create(unsigned int width, unsigned int height) m_texture = static_cast(texture); } - // Make sure that extensions are initialized - priv::ensureExtensionsInit(); - // Make sure that the current texture binding will be preserved priv::TextureSaver save; @@ -851,11 +851,6 @@ unsigned int Texture::getNativeHandle() const //////////////////////////////////////////////////////////// unsigned int Texture::getValidSize(unsigned int size) { - TransientContextLock lock; - - // Make sure that extensions are initialized - priv::ensureExtensionsInit(); - if (GLEXT_texture_non_power_of_two) { // If hardware supports NPOT textures, then just return the unmodified size From 37aee610c8663db6ee7c10d01a4e7e5cfaa86c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Thu, 9 Aug 2018 22:20:35 +0200 Subject: [PATCH 20/39] Fixed the installation of pkg-config files * Removed duplicated CMake code * Made it possible to manually specify the pkg-config path * Install pkg-config files by default on Linux and BSD systems --- CMakeLists.txt | 39 ++++++++++++--------------------------- cmake/Config.cmake | 15 +++++---------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb30b46c..8de83b3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,30 +269,6 @@ if(SFML_OS_MACOSX) set(XCODE_TEMPLATES_ARCH "\$(NATIVE_ARCH_ACTUAL)") endif() -if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_OPENBSD) - set(PKGCONFIG_DIR lib${LIB_SUFFIX}/pkgconfig) - if(SFML_OS_FREEBSD OR SFML_OS_OPENBSD) - set(PKGCONFIG_DIR libdata/pkgconfig) - endif() - if(BUILD_SHARED_LIBS) - sfml_set_option(SFML_INSTALL_PKGCONFIG_FILES FALSE BOOL "TRUE to automatically install pkg-config files so other projects can find SFML") - if(SFML_INSTALL_PKGCONFIG_FILES) - foreach(sfml_module IN ITEMS all system window graphics audio network) - CONFIGURE_FILE( - "tools/pkg-config/sfml-${sfml_module}.pc.in" - "tools/pkg-config/sfml-${sfml_module}.pc" - @ONLY) - INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/pkg-config/sfml-${sfml_module}.pc" - DESTINATION "${CMAKE_INSTALL_PREFIX}/${PKGCONFIG_DIR}") - endforeach() - endif() - else() - if(SFML_INSTALL_PKGCONFIG_FILES) - message(WARNING "No pkg-config files are provided for the static SFML libraries (SFML_INSTALL_PKGCONFIG_FILES will be ignored).") - endif() - endif() -endif() - # enable project folders set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake") @@ -306,16 +282,25 @@ if(SFML_BUILD_DOC) add_subdirectory(doc) endif() -sfml_set_option(SFML_INSTALL_PKGCONFIG_FILES FALSE BOOL "TRUE to automatically install pkg-config files so other projects can find SFML") +# on Linux and BSD-like OS, install pkg-config files by default +set(SFML_INSTALL_PKGCONFIG_DEFAULT FALSE) + +if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_OPENBSD) + set(SFML_INSTALL_PKGCONFIG_DEFAULT TRUE) +endif() + +sfml_set_option(SFML_INSTALL_PKGCONFIG_FILES ${SFML_INSTALL_PKGCONFIG_DEFAULT} BOOL "TRUE to automatically install pkg-config files so other projects can find SFML") + +if(SFML_INSTALL_PKGCONFIG_FILES) + sfml_set_option(SFML_PKGCONFIG_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/${SFML_PKGCONFIG_DIR}" PATH "Install directory for SFML's pkg-config .pc files") -if(SFML_OS_SUPPORTS_PKGCONFIG OR SFML_INSTALL_PKGCONFIG_FILES) foreach(sfml_module IN ITEMS all system window graphics audio network) CONFIGURE_FILE( "tools/pkg-config/sfml-${sfml_module}.pc.in" "tools/pkg-config/sfml-${sfml_module}.pc" @ONLY) INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/tools/pkg-config/sfml-${sfml_module}.pc" - DESTINATION "${CMAKE_INSTALL_PREFIX}/${SFML_OS_PKGCONFIG_DIR}") + DESTINATION "${SFML_PKGCONFIG_INSTALL_PREFIX}") endforeach() endif() diff --git a/cmake/Config.cmake b/cmake/Config.cmake index 82a094cd..0a286602 100644 --- a/cmake/Config.cmake +++ b/cmake/Config.cmake @@ -69,17 +69,12 @@ else() return() endif() -# check if OS or package system supports pkg-config +# set pkgconfig install directory # this could be e.g. macports on mac or msys2 on windows etc. -find_package(PkgConfig QUIET) -if(PKG_CONFIG_EXECUTABLE) - if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig") - set(SFML_OS_SUPPORTS_PKGCONFIG ON) - set(SFML_OS_PKGCONFIG_DIR "/lib${LIB_SUFFIX}/pkgconfig") - elseif(EXISTS "${CMAKE_INSTALL_PREFIX}/libdata/pkgconfig") - set(SFML_OS_SUPPORTS_PKGCONFIG ON) - set(SFML_OS_PKGCONFIG_DIR "/libdata/pkgconfig") - endif() +set(SFML_PKGCONFIG_DIR "/lib${LIB_SUFFIX}/pkgconfig") + +if(SFML_OS_FREEBSD OR SFML_OS_OPENBSD) + set(SFML_PKGCONFIG_DIR "/libdata/pkgconfig") endif() # detect the compiler and its version From 40ddcac2039ab2407b417941673587185a7f7691 Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Thu, 9 Aug 2018 15:32:26 -0700 Subject: [PATCH 21/39] Removed unnecessary cmake osx deployment target value --- CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8de83b3a..9eb250ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,6 @@ endif() if(NOT CMAKE_OSX_ARCHITECTURES) set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "macOS architecture to build; 64-bit is expected" FORCE) endif() -if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "macOS deployement target; 10.7+ is expected" FORCE) -endif() if(NOT CMAKE_OSX_SYSROOT) # query the path to the default SDK, will fail on non-macOS, but it's okay. execute_process(COMMAND xcodebuild -sdk macosx -version Path @@ -260,11 +257,6 @@ if(SFML_OS_MACOSX) message(FATAL_ERROR "Only 64-bit architecture is supported") endif() - # Ensure macOS 10.7+ is used - if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS "10.7") - message(FATAL_ERROR "macOS 10.7 or greater is required for the deployment target.") - endif() - # configure Xcode templates set(XCODE_TEMPLATES_ARCH "\$(NATIVE_ARCH_ACTUAL)") endif() From 21c6c64ecd24f1797ef7b1c1670ce8cfcf6b43cc Mon Sep 17 00:00:00 2001 From: Kwasior Date: Tue, 14 Aug 2018 14:59:57 +0200 Subject: [PATCH 22/39] Fix audio components linking order --- cmake/SFMLConfigDependencies.cmake.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/SFMLConfigDependencies.cmake.in b/cmake/SFMLConfigDependencies.cmake.in index 97f33c01..1028110f 100644 --- a/cmake/SFMLConfigDependencies.cmake.in +++ b/cmake/SFMLConfigDependencies.cmake.in @@ -70,12 +70,12 @@ if(SFML_STATIC_LIBRARIES) list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT_INDEX) if(FIND_SFML_AUDIO_COMPONENT_INDEX GREATER -1) sfml_bind_dependency(TARGET OpenAL FRIENDLY_NAME "OpenAL" SEARCH_NAMES "OpenAL" "openal" "openal32") - sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Ogg" SEARCH_NAMES "ogg") - sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Vorbis" SEARCH_NAMES "vorbis") if (NOT FIND_SFML_OS_IOS) sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisFile" SEARCH_NAMES "vorbisfile") sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "VorbisEnc" SEARCH_NAMES "vorbisenc") endif() + sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Vorbis" SEARCH_NAMES "vorbis") + sfml_bind_dependency(TARGET Vorbis FRIENDLY_NAME "Ogg" SEARCH_NAMES "ogg") sfml_bind_dependency(TARGET FLAC FRIENDLY_NAME "FLAC" SEARCH_NAMES "FLAC") endif() From 254a4703469488f76450e2fb5f8445e202aeeabe Mon Sep 17 00:00:00 2001 From: Elias Daler Date: Tue, 14 Aug 2018 00:06:31 +0300 Subject: [PATCH 23/39] Fix CMP0072 CMake warning - also allow user to set OpenGL_GL_PREFERENCE --- src/SFML/Window/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 916c1dcd..1fe8b5a4 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -235,6 +235,13 @@ if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OPENBSD) target_link_libraries(sfml-window PRIVATE X11) endif() +# CMake 3.11 and later prefer to choose GLVND, but we choose legacy OpenGL for backward compability +# (unless the OpenGL_GL_PREFERENCE was explicitly set) +# See CMP0072 for more details (cmake --help-policy CMP0072) +if ((NOT ${CMAKE_VERSION} VERSION_LESS 3.11) AND (NOT OpenGL_GL_PREFERENCE)) + set(OpenGL_GL_PREFERENCE "LEGACY") +endif() + if(SFML_OPENGL_ES) if(SFML_OS_IOS) target_link_libraries(sfml-window PRIVATE "-framework OpenGLES") @@ -242,7 +249,7 @@ if(SFML_OPENGL_ES) target_link_libraries(sfml-window PRIVATE EGL GLESv1_CM) endif() else() - sfml_find_package(OpenGL INCLUDE "OPENGL_INCLUDE_DIR" LINK "OPENGL_gl_LIBRARY") + sfml_find_package(OpenGL INCLUDE "OPENGL_INCLUDE_DIR" LINK "OPENGL_LIBRARIES") target_link_libraries(sfml-window PRIVATE OpenGL) endif() From 7823588b1b3ea2572d74df98d1edda5f3053147f Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Mon, 27 Aug 2018 13:36:57 +0100 Subject: [PATCH 24/39] Remove reference to unused CMAKE_OSX_DEPLOYMENT_TARGET in cocoa example --- examples/cocoa/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cocoa/CMakeLists.txt b/examples/cocoa/CMakeLists.txt index ff63cc07..dfa46be5 100644 --- a/examples/cocoa/CMakeLists.txt +++ b/examples/cocoa/CMakeLists.txt @@ -20,7 +20,7 @@ function(compile_xib) endif() # Default args taken from Xcode 9 when it generates a nib from a xib - set(DEFAULT_ARGS --errors --warnings --notices --module cocoa --auto-activate-custom-fonts --target-device mac --minimum-deployment-target ${CMAKE_OSX_DEPLOYMENT_TARGET} --output-format human-readable-text) + set(DEFAULT_ARGS --errors --warnings --notices --module cocoa --auto-activate-custom-fonts --target-device mac --output-format human-readable-text) add_custom_command(OUTPUT "${THIS_OUTPUT}" COMMAND "${IBTOOL}" ${DEFAULT_ARGS} "${THIS_INPUT}" --compile "${THIS_OUTPUT}" From 9c2e7cbb51e2b31488f562b86abfd488d47a0c43 Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Tue, 10 Apr 2018 20:52:38 -0700 Subject: [PATCH 25/39] Implemented extra cursors on macOS --- include/SFML/Window/Cursor.hpp | 33 +++++++++++++++++-------------- src/SFML/Window/OSX/CursorImpl.mm | 22 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp index 30aebd40..bf7bb0b6 100644 --- a/include/SFML/Window/Cursor.hpp +++ b/include/SFML/Window/Cursor.hpp @@ -53,21 +53,24 @@ public: /// Refer to the following table to determine which cursor /// is available on which platform. /// - /// Type | Linux | Mac OS X | Windows | - /// ------------------------------------|:-----:|:--------:|:--------:| - /// sf::Cursor::Arrow | yes | yes | yes | - /// sf::Cursor::ArrowWait | no | no | yes | - /// sf::Cursor::Wait | yes | no | yes | - /// sf::Cursor::Text | yes | yes | yes | - /// sf::Cursor::Hand | yes | yes | yes | - /// sf::Cursor::SizeHorizontal | yes | yes | yes | - /// sf::Cursor::SizeVertical | yes | yes | yes | - /// sf::Cursor::SizeTopLeftBottomRight | no | no | yes | - /// sf::Cursor::SizeBottomLeftTopRight | no | no | yes | - /// sf::Cursor::SizeAll | yes | no | yes | - /// sf::Cursor::Cross | yes | yes | yes | - /// sf::Cursor::Help | yes | no | yes | - /// sf::Cursor::NotAllowed | yes | yes | yes | + /// Type | Linux | Mac OS X | Windows + /// ------------------------------------|:-----:|:--------:|:--------: + /// sf::Cursor::Arrow | yes | yes | yes + /// sf::Cursor::ArrowWait | no | no | yes + /// sf::Cursor::Wait | yes | no | yes + /// sf::Cursor::Text | yes | yes | yes + /// sf::Cursor::Hand | yes | yes | yes + /// sf::Cursor::SizeHorizontal | yes | yes | yes + /// sf::Cursor::SizeVertical | yes | yes | yes + /// sf::Cursor::SizeTopLeftBottomRight | no | yes* | yes + /// sf::Cursor::SizeBottomLeftTopRight | no | yes* | yes + /// sf::Cursor::SizeAll | yes | no | yes + /// sf::Cursor::Cross | yes | yes | yes + /// sf::Cursor::Help | yes | yes* | yes + /// sf::Cursor::NotAllowed | yes | yes | yes + /// + /// * These cursor types are undocumented so may not + /// be available on all versions, but have been tested on 10.13 /// //////////////////////////////////////////////////////////// enum Type diff --git a/src/SFML/Window/OSX/CursorImpl.mm b/src/SFML/Window/OSX/CursorImpl.mm index 5f413763..c5242505 100644 --- a/src/SFML/Window/OSX/CursorImpl.mm +++ b/src/SFML/Window/OSX/CursorImpl.mm @@ -65,6 +65,16 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot return m_cursor != nil; } +//////////////////////////////////////////////////////////// +bool loadFromSelector(SEL selector, NSCursorRef& cursor) +{ + if ([NSCursor respondsToSelector:selector]) + { + cursor = [NSCursor performSelector:selector]; + return true; + } + return false; +} //////////////////////////////////////////////////////////// bool CursorImpl::loadFromSystem(Cursor::Type type) @@ -80,6 +90,18 @@ bool CursorImpl::loadFromSystem(Cursor::Type type) case Cursor::SizeVertical: m_cursor = [NSCursor resizeUpDownCursor]; break; case Cursor::Cross: m_cursor = [NSCursor crosshairCursor]; break; case Cursor::NotAllowed: m_cursor = [NSCursor operationNotAllowedCursor]; break; + + // These cursor types are undocumented, may not be available on some platforms + case Cursor::SizeBottomLeftTopRight: + return loadFromSelector(@selector(_windowResizeNorthEastSouthWestCursor), m_cursor); + case Cursor::SizeTopLeftBottomRight: + return loadFromSelector(@selector(_windowResizeNorthWestSouthEastCursor), m_cursor); + case Cursor::SizeAll: + return loadFromSelector(@selector(_moveCursor), m_cursor); + case Cursor::Wait: + return loadFromSelector(@selector(_waitCursor), m_cursor); + case Cursor::Help: + return loadFromSelector(@selector(_helpCursor), m_cursor); } // Since we didn't allocate the cursor ourself, we have to retain it From 9f7d8101a90d584718c82aabaefa5ab566361a85 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Fri, 20 Apr 2018 07:50:14 +0200 Subject: [PATCH 26/39] Improved macOS implementation for Cursor - remove Wait and SizeAll cursors as they don't look nice (Wait is not spining and produces a broken rendering, SizeAll is a simple white cursor.) - fix memory management for NSCursor. - ignore selector warnings. --- include/SFML/Window/Cursor.hpp | 30 ++++++++--------- src/SFML/Window/OSX/CursorImpl.mm | 56 ++++++++++++++++++------------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/include/SFML/Window/Cursor.hpp b/include/SFML/Window/Cursor.hpp index bf7bb0b6..9daa13bd 100644 --- a/include/SFML/Window/Cursor.hpp +++ b/include/SFML/Window/Cursor.hpp @@ -53,21 +53,21 @@ public: /// Refer to the following table to determine which cursor /// is available on which platform. /// - /// Type | Linux | Mac OS X | Windows - /// ------------------------------------|:-----:|:--------:|:--------: - /// sf::Cursor::Arrow | yes | yes | yes - /// sf::Cursor::ArrowWait | no | no | yes - /// sf::Cursor::Wait | yes | no | yes - /// sf::Cursor::Text | yes | yes | yes - /// sf::Cursor::Hand | yes | yes | yes - /// sf::Cursor::SizeHorizontal | yes | yes | yes - /// sf::Cursor::SizeVertical | yes | yes | yes - /// sf::Cursor::SizeTopLeftBottomRight | no | yes* | yes - /// sf::Cursor::SizeBottomLeftTopRight | no | yes* | yes - /// sf::Cursor::SizeAll | yes | no | yes - /// sf::Cursor::Cross | yes | yes | yes - /// sf::Cursor::Help | yes | yes* | yes - /// sf::Cursor::NotAllowed | yes | yes | yes + /// Type | Linux | Mac OS X | Windows | + /// ------------------------------------|:-----:|:--------:|:--------:| + /// sf::Cursor::Arrow | yes | yes | yes | + /// sf::Cursor::ArrowWait | no | no | yes | + /// sf::Cursor::Wait | yes | no | yes | + /// sf::Cursor::Text | yes | yes | yes | + /// sf::Cursor::Hand | yes | yes | yes | + /// sf::Cursor::SizeHorizontal | yes | yes | yes | + /// sf::Cursor::SizeVertical | yes | yes | yes | + /// sf::Cursor::SizeTopLeftBottomRight | no | yes* | yes | + /// sf::Cursor::SizeBottomLeftTopRight | no | yes* | yes | + /// sf::Cursor::SizeAll | yes | no | yes | + /// sf::Cursor::Cross | yes | yes | yes | + /// sf::Cursor::Help | yes | yes* | yes | + /// sf::Cursor::NotAllowed | yes | yes | yes | /// /// * These cursor types are undocumented so may not /// be available on all versions, but have been tested on 10.13 diff --git a/src/SFML/Window/OSX/CursorImpl.mm b/src/SFML/Window/OSX/CursorImpl.mm index c5242505..ed905ef5 100644 --- a/src/SFML/Window/OSX/CursorImpl.mm +++ b/src/SFML/Window/OSX/CursorImpl.mm @@ -32,6 +32,21 @@ #import #import +namespace +{ + +//////////////////////////////////////////////////////////// +NSCursor* loadFromSelector(SEL selector) +{ + // The caller is responsible for retaining the cursor. + if ([NSCursor respondsToSelector:selector]) + return [NSCursor performSelector:selector]; + else + return nil; +} + +} + namespace sf { namespace priv @@ -56,6 +71,8 @@ CursorImpl::~CursorImpl() //////////////////////////////////////////////////////////// bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hotspot) { + [m_cursor release]; + NSSize nssize = NSMakeSize(size.x, size.y); NSImage* image = [NSImage imageWithRawData:pixels andSize:nssize]; NSPoint nshotspot = NSMakePoint(hotspot.x, hotspot.y); @@ -65,20 +82,11 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot return m_cursor != nil; } -//////////////////////////////////////////////////////////// -bool loadFromSelector(SEL selector, NSCursorRef& cursor) -{ - if ([NSCursor respondsToSelector:selector]) - { - cursor = [NSCursor performSelector:selector]; - return true; - } - return false; -} - //////////////////////////////////////////////////////////// bool CursorImpl::loadFromSystem(Cursor::Type type) { + [m_cursor release]; + switch (type) { default: return false; @@ -92,24 +100,26 @@ bool CursorImpl::loadFromSystem(Cursor::Type type) case Cursor::NotAllowed: m_cursor = [NSCursor operationNotAllowedCursor]; break; // These cursor types are undocumented, may not be available on some platforms +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" case Cursor::SizeBottomLeftTopRight: - return loadFromSelector(@selector(_windowResizeNorthEastSouthWestCursor), m_cursor); + m_cursor = loadFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)); + break; + case Cursor::SizeTopLeftBottomRight: - return loadFromSelector(@selector(_windowResizeNorthWestSouthEastCursor), m_cursor); - case Cursor::SizeAll: - return loadFromSelector(@selector(_moveCursor), m_cursor); - case Cursor::Wait: - return loadFromSelector(@selector(_waitCursor), m_cursor); + m_cursor = loadFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)); + break; + case Cursor::Help: - return loadFromSelector(@selector(_helpCursor), m_cursor); + m_cursor = loadFromSelector(@selector(_helpCursor)); + break; +#pragma clang diagnostic pop } - // Since we didn't allocate the cursor ourself, we have to retain it - // in order to not break the retain count. - [m_cursor retain]; + if (m_cursor) + [m_cursor retain]; - // For all non-default cases, it was a success. - return true; + return m_cursor != nil; } From d8952f28eb12b0bc0823584e41462947e73559fa Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Thu, 23 Aug 2018 20:00:44 +0100 Subject: [PATCH 27/39] Disable autocorrect on iOS for issue #1473 --- src/SFML/Window/iOS/SFView.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SFML/Window/iOS/SFView.mm b/src/SFML/Window/iOS/SFView.mm index 063c61a3..940d0a8e 100644 --- a/src/SFML/Window/iOS/SFView.mm +++ b/src/SFML/Window/iOS/SFView.mm @@ -202,5 +202,11 @@ return self; } +//////////////////////////////////////////////////////////// +- (UITextAutocorrectionType) autocorrectionType +{ + return UITextAutocorrectionTypeNo; +} + @end From e4d3a536a20327d78b450bee91b9e2e9f23bebb7 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 11 Aug 2017 11:36:16 -0700 Subject: [PATCH 28/39] Fix Deadlock in Android Main Cleanup --- src/SFML/Main/MainAndroid.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/SFML/Main/MainAndroid.cpp b/src/SFML/Main/MainAndroid.cpp index fe67bbad..5e621339 100644 --- a/src/SFML/Main/MainAndroid.cpp +++ b/src/SFML/Main/MainAndroid.cpp @@ -93,6 +93,13 @@ static void initializeMain(ActivityStates* states) ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); states->looper = looper; + /** + * Acquire increments a reference counter on the looper. This keeps android + * from collecting it before the activity thread has a chance to detach its + * input queue. + */ + ALooper_acquire(states->looper); + // Get the default configuration states->config = AConfiguration_new(); AConfiguration_fromAssetManager(states->config, states->activity->assetManager); @@ -338,7 +345,7 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind // Wait for the event to be taken into account by SFML states->updated = false; - while(!states->updated) + while(!(states->updated | states->terminated)) { states->mutex.unlock(); sf::sleep(sf::milliseconds(10)); @@ -363,7 +370,7 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* wi // Wait for the event to be taken into account by SFML states->updated = false; - while(!states->updated) + while(!(states->updated | states->terminated)) { states->mutex.unlock(); sf::sleep(sf::milliseconds(10)); @@ -410,8 +417,10 @@ static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { sf::Lock lock(states->mutex); - states->inputQueue = NULL; AInputQueue_detachLooper(queue); + states->inputQueue = NULL; + + ALooper_release(states->looper); } } @@ -542,7 +551,7 @@ JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity, void* savedSt // Wait for the main thread to be initialized states->mutex.lock(); - while (!states->initialized) + while (!(states->initialized | states->terminated)) { states->mutex.unlock(); sf::sleep(sf::milliseconds(20)); From 53e1bae7cee004a2186fd7d1159d42b1d190ec85 Mon Sep 17 00:00:00 2001 From: Christian Widmer Date: Thu, 16 Aug 2018 02:04:12 +0200 Subject: [PATCH 29/39] Window/Unix: Fix compilation with glxext header versions >=20180525 When mesa updated their headers, they changed the include guard from __glxext_h_ to __glx_glxext_h_, which breaks compilation due to conflicting declarations. This commit modifies the preprocessor directives to allow for compilation with older and newer mesa header versions. Fixes: #1472 --- src/SFML/Window/Unix/GlxExtensions.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SFML/Window/Unix/GlxExtensions.hpp b/src/SFML/Window/Unix/GlxExtensions.hpp index abbb132a..fb2c7da8 100644 --- a/src/SFML/Window/Unix/GlxExtensions.hpp +++ b/src/SFML/Window/Unix/GlxExtensions.hpp @@ -25,11 +25,12 @@ #ifndef SF_POINTER_C_GENERATED_HEADER_GLXWIN_HPP #define SF_POINTER_C_GENERATED_HEADER_GLXWIN_HPP -#ifdef __glxext_h_ +#if defined(__glxext_h_) || defined(__glx_glxext_h_) #error Attempt to include glx_exts after including glxext.h #endif #define __glxext_h_ +#define __glx_glxext_h_ #include #include From c2008b2fb4ac0bcb31a1090e7aaa6bbccfd8bf9e Mon Sep 17 00:00:00 2001 From: Bloodsword Date: Wed, 1 Nov 2017 19:34:45 +0100 Subject: [PATCH 30/39] Use XRRSetCrtcConfig instead of XRRSetScreenConfig, in order to fix issue #1226. It should also fix issue #1224. --- src/SFML/Window/Unix/WindowImplX11.cpp | 313 ++++++++++++++++++++----- src/SFML/Window/Unix/WindowImplX11.hpp | 34 +++ 2 files changed, 292 insertions(+), 55 deletions(-) diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index ee5bf356..da697505 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -174,7 +174,7 @@ namespace if (result != Success || actualType != XA_WINDOW || numItems != 1) { - if(result == Success) + if (result == Success) XFree(data); sf::priv::CloseDisplay(display); @@ -206,7 +206,7 @@ namespace if (result != Success || actualType != XA_WINDOW || numItems != 1) { - if(result == Success) + if (result == Success) XFree(data); sf::priv::CloseDisplay(display); @@ -270,7 +270,7 @@ namespace windowManagerName = sf::String::fromUtf8(begin, end); } - if(result == Success) + if (result == Success) XFree(data); sf::priv::CloseDisplay(display); @@ -487,6 +487,7 @@ m_inputMethod (NULL), m_inputContext (NULL), m_isExternal (true), m_oldVideoMode (0), +m_oldRRCrtc (0), m_hiddenCursor (0), m_lastCursor (None), m_keyRepeat (true), @@ -535,6 +536,7 @@ m_inputMethod (NULL), m_inputContext (NULL), m_isExternal (false), m_oldVideoMode (0), +m_oldRRCrtc (0), m_hiddenCursor (0), m_lastCursor (None), m_keyRepeat (true), @@ -556,8 +558,17 @@ m_lastInputTime (0) m_screen = DefaultScreen(m_display); // Compute position and size - int left = m_fullscreen ? 0 : (DisplayWidth(m_display, m_screen) - mode.width) / 2; - int top = m_fullscreen ? 0 : (DisplayHeight(m_display, m_screen) - mode.height) / 2; + Vector2i windowPosition; + if(m_fullscreen) + { + windowPosition = getPrimaryMonitorPosition(); + } + else + { + windowPosition.x = (DisplayWidth(m_display, m_screen) - mode.width) / 2; + windowPosition.y = (DisplayWidth(m_display, m_screen) - mode.height) / 2; + } + int width = mode.width; int height = mode.height; @@ -572,7 +583,7 @@ m_lastInputTime (0) m_window = XCreateWindow(m_display, DefaultRootWindow(m_display), - left, top, + windowPosition.x, windowPosition.y, width, height, 0, visualInfo.depth, @@ -669,9 +680,11 @@ m_lastInputTime (0) { m_useSizeHints = true; XSizeHints* sizeHints = XAllocSizeHints(); - sizeHints->flags = PMinSize | PMaxSize; + sizeHints->flags = PMinSize | PMaxSize | USPosition; sizeHints->min_width = sizeHints->max_width = width; sizeHints->min_height = sizeHints->max_height = height; + sizeHints->x = windowPosition.x; + sizeHints->y = windowPosition.y; XSetWMNormalHints(m_display, m_window, sizeHints); XFree(sizeHints); } @@ -708,7 +721,15 @@ m_lastInputTime (0) // Set fullscreen video mode and switch to fullscreen if necessary if (m_fullscreen) { - setPosition(Vector2i(0, 0)); + // Disable hint for min and max size, + // otherwise some windows managers will not remove window decorations + XSizeHints *sizeHints = XAllocSizeHints(); + long flags = 0; + XGetWMNormalHints(m_display, m_window, sizeHints, &flags); + sizeHints->flags &= ~(PMinSize | PMaxSize); + XSetWMNormalHints(m_display, m_window, sizeHints); + XFree(sizeHints); + setVideoMode(mode); switchToFullscreen(); } @@ -722,11 +743,11 @@ WindowImplX11::~WindowImplX11() cleanup(); // Destroy icon pixmap - if(m_iconPixmap) + if (m_iconPixmap) XFreePixmap(m_display, m_iconPixmap); // Destroy icon mask pixmap - if(m_iconMaskPixmap) + if (m_iconMaskPixmap) XFreePixmap(m_display, m_iconMaskPixmap); // Destroy the cursor @@ -960,10 +981,10 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8 return; } - if(m_iconPixmap) + if (m_iconPixmap) XFreePixmap(m_display, m_iconPixmap); - if(m_iconMaskPixmap) + if (m_iconMaskPixmap) XFreePixmap(m_display, m_iconMaskPixmap); m_iconPixmap = XCreatePixmap(m_display, RootWindow(m_display, m_screen), width, height, defDepth); @@ -1240,53 +1261,99 @@ void WindowImplX11::setVideoMode(const VideoMode& mode) return; // Check if the XRandR extension is present - int version; - if (!XQueryExtension(m_display, "RANDR", &version, &version, &version)) + int xRandRMajor, xRandRMinor; + if (!checkXRandR(xRandRMajor, xRandRMinor)) { // XRandR extension is not supported: we cannot use fullscreen mode err() << "Fullscreen is not supported, switching to window mode" << std::endl; return; } - // Get the current configuration - XRRScreenConfiguration* config = XRRGetScreenInfo(m_display, RootWindow(m_display, m_screen)); + // Get root window + ::Window rootWindow = RootWindow(m_display, m_screen); - if (!config) + // Get the screen resources + XRRScreenResources* res = XRRGetScreenResources(m_display, rootWindow); + if (!res) { - // Failed to get the screen configuration - err() << "Failed to get the current screen configuration for fullscreen mode, switching to window mode" << std::endl; + err() << "Failed to get the current screen resources for fullscreen mode, switching to window mode" << std::endl; + return; + } + + RROutput output = getOutputPrimary(rootWindow, res, xRandRMajor, xRandRMinor); + + // Get output info from output + XRROutputInfo* outputInfo = XRRGetOutputInfo(m_display, res, output); + if (!outputInfo || outputInfo->connection == RR_Disconnected) + { + XRRFreeScreenResources(res); + + // If outputInfo->connection == RR_Disconnected, free output info + if (outputInfo) + XRRFreeOutputInfo(outputInfo); + + err() << "Failed to get output info for fullscreen mode, switching to window mode" << std::endl; + return; + } + + // Retreive current RRMode, screen position and rotation + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, outputInfo->crtc); + if (!crtcInfo) + { + XRRFreeScreenResources(res); + XRRFreeOutputInfo(outputInfo); + err() << "Failed to get crtc info for fullscreen mode, switching to window mode" << std::endl; + return; + } + + // Find RRMode to set + bool modeFound = false; + RRMode xRandMode; + + for (int i = 0; (i < res->nmode) && !modeFound; i++) + { + if (crtcInfo->rotation == RR_Rotate_90 || crtcInfo->rotation == RR_Rotate_270) + std::swap(res->modes[i].height, res->modes[i].width); + + // Check if screen size match + if (res->modes[i].width == static_cast(mode.width) && + res->modes[i].height == static_cast(mode.height)) + { + xRandMode = res->modes[i].id; + modeFound = true; + } + } + + if (!modeFound) + { + XRRFreeScreenResources(res); + XRRFreeOutputInfo(outputInfo); + err() << "Failed to find a matching RRMode for fullscreen mode, switching to window mode" << std::endl; return; } // Save the current video mode before we switch to fullscreen - Rotation currentRotation; - m_oldVideoMode = XRRConfigCurrentConfiguration(config, ¤tRotation); + m_oldVideoMode = crtcInfo->mode; + m_oldRRCrtc = outputInfo->crtc; - // Get the available screen sizes - int nbSizes; - XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes); + // Switch to fullscreen mode + XRRSetCrtcConfig(m_display, + res, + outputInfo->crtc, + CurrentTime, + crtcInfo->x, + crtcInfo->y, + xRandMode, + crtcInfo->rotation, + &output, + 1); - // Search for a matching size - for (int i = 0; (sizes && i < nbSizes); ++i) - { - XRRConfigRotations(config, ¤tRotation); + // Set "this" as the current fullscreen window + fullscreenWindow = this; - if (currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270) - std::swap(sizes[i].height, sizes[i].width); - - if ((sizes[i].width == static_cast(mode.width)) && (sizes[i].height == static_cast(mode.height))) - { - // Switch to fullscreen mode - XRRSetScreenConfig(m_display, config, RootWindow(m_display, m_screen), i, currentRotation, CurrentTime); - - // Set "this" as the current fullscreen window - fullscreenWindow = this; - break; - } - } - - // Free the configuration instance - XRRFreeScreenConfigInfo(config); + XRRFreeScreenResources(res); + XRRFreeOutputInfo(outputInfo); + XRRFreeCrtcInfo(crtcInfo); } @@ -1295,19 +1362,55 @@ void WindowImplX11::resetVideoMode() { if (fullscreenWindow == this) { - // Get current screen info - XRRScreenConfiguration* config = XRRGetScreenInfo(m_display, RootWindow(m_display, m_screen)); - if (config) + // Try to set old configuration + // Check if the XRandR extension + int xRandRMajor, xRandRMinor; + if (checkXRandR(xRandRMajor, xRandRMinor)) { - // Get the current rotation - Rotation currentRotation; - XRRConfigCurrentConfiguration(config, ¤tRotation); + XRRScreenResources* res = XRRGetScreenResources(m_display, DefaultRootWindow(m_display)); + if (!res) + { + err() << "Failed to get the current screen resources to reset the video mode" << std::endl; + return; + } - // Reset the video mode - XRRSetScreenConfig(m_display, config, RootWindow(m_display, m_screen), m_oldVideoMode, currentRotation, CurrentTime); + // Retreive current screen position and rotation + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, m_oldRRCrtc); + if (!crtcInfo) + { + XRRFreeScreenResources(res); + err() << "Failed to get crtc info to reset the video mode" << std::endl; + return; + } - // Free the configuration instance - XRRFreeScreenConfigInfo(config); + RROutput output; + + // if version >= 1.3 get the primary screen else take the first screen + if ((xRandRMajor == 1 && xRandRMinor >= 3) || xRandRMajor > 1) + { + output = XRRGetOutputPrimary(m_display, DefaultRootWindow(m_display)); + + // Check if returned output is valid, otherwise use the first screen + if (output == None) + output = res->outputs[0]; + } + else{ + output = res->outputs[0]; + } + + XRRSetCrtcConfig(m_display, + res, + m_oldRRCrtc, + CurrentTime, + crtcInfo->x, + crtcInfo->y, + m_oldVideoMode, + crtcInfo->rotation, + &output, + 1); + + XRRFreeCrtcInfo(crtcInfo); + XRRFreeScreenResources(res); } // Reset the fullscreen window @@ -1503,7 +1606,7 @@ void WindowImplX11::updateLastInputTime(::Time time) { Atom netWmUserTime = getAtom("_NET_WM_USER_TIME", true); - if(netWmUserTime) + if (netWmUserTime) { XChangeProperty(m_display, m_window, @@ -1973,6 +2076,106 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) return true; } + +//////////////////////////////////////////////////////////// +bool WindowImplX11::checkXRandR(int& xRandRMajor, int& xRandRMinor) +{ + // Check if the XRandR extension is present + int version; + if (!XQueryExtension(m_display, "RANDR", &version, &version, &version)) + { + err() << "XRandR extension is not supported" << std::endl; + return false; + } + + // Check XRandR version, 1.2 required + if (!XRRQueryVersion(m_display, &xRandRMajor, &xRandRMinor) || xRandRMajor < 1 || (xRandRMajor == 1 && xRandRMinor < 2 )) + { + err() << "XRandR is too old" << std::endl; + return false; + } + + return true; +} + + +//////////////////////////////////////////////////////////// +RROutput WindowImplX11::getOutputPrimary(::Window& rootWindow, XRRScreenResources* res, int xRandRMajor, int xRandRMinor) +{ + // if xRandR version >= 1.3 get the primary screen else take the first screen + if ((xRandRMajor == 1 && xRandRMinor >= 3) || xRandRMajor > 1) + { + RROutput output = XRRGetOutputPrimary(m_display, rootWindow); + + // Check if returned output is valid, otherwise use the first screen + if (output == None) + return res->outputs[0]; + else + return output; + } + + // xRandr version can't get the primary screen, use the first screen + return res->outputs[0]; +} + + +//////////////////////////////////////////////////////////// +Vector2i WindowImplX11::getPrimaryMonitorPosition() +{ + Vector2i monitorPosition; + + // Get root window + ::Window rootWindow = RootWindow(m_display, m_screen); + + // Get the screen resources + XRRScreenResources* res = XRRGetScreenResources(m_display, rootWindow); + if (!res) + { + err() << "Failed to get the current screen resources for.primary monitor position" << std::endl; + return monitorPosition; + } + + // Get xRandr version + int xRandRMajor, xRandRMinor; + if (!checkXRandR(xRandRMajor, xRandRMinor)) + xRandRMajor = xRandRMinor = 0; + + RROutput output = getOutputPrimary(rootWindow, res, xRandRMajor, xRandRMinor); + + // Get output info from output + XRROutputInfo* outputInfo = XRRGetOutputInfo(m_display, res, output); + if (!outputInfo || outputInfo->connection == RR_Disconnected) + { + XRRFreeScreenResources(res); + + // If outputInfo->connection == RR_Disconnected, free output info + if (outputInfo) + XRRFreeOutputInfo(outputInfo); + + err() << "Failed to get output info for.primary monitor position" << std::endl; + return monitorPosition; + } + + // Retreive current RRMode, screen position and rotation + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, outputInfo->crtc); + if (!crtcInfo) + { + XRRFreeScreenResources(res); + XRRFreeOutputInfo(outputInfo); + err() << "Failed to get crtc info for.primary monitor position" << std::endl; + return monitorPosition; + } + + monitorPosition.x = crtcInfo->x; + monitorPosition.y = crtcInfo->y; + + XRRFreeCrtcInfo(crtcInfo); + XRRFreeOutputInfo(outputInfo); + XRRFreeScreenResources(res); + + return monitorPosition; +} + } // namespace priv } // namespace sf diff --git a/src/SFML/Window/Unix/WindowImplX11.hpp b/src/SFML/Window/Unix/WindowImplX11.hpp index 0ff694b1..a025a1ae 100644 --- a/src/SFML/Window/Unix/WindowImplX11.hpp +++ b/src/SFML/Window/Unix/WindowImplX11.hpp @@ -34,6 +34,7 @@ #include // Prevent conflict with macro None from Xlib #include #include +#include namespace sf @@ -264,6 +265,38 @@ private: //////////////////////////////////////////////////////////// bool processEvent(XEvent& windowEvent); + //////////////////////////////////////////////////////////// + /// \brief Check if a valid version of XRandR extension is present + /// + /// \param xRandRMajor XRandR major version + /// \param xRandRMinor XRandR minor version + /// + /// \return True if a valid XRandR version found, false otherwise + /// + //////////////////////////////////////////////////////////// + bool checkXRandR(int& xRandRMajor, int& xRandRMinor); + + //////////////////////////////////////////////////////////// + /// \brief Get the RROutput of the primary monitor + /// + /// \param rootWindow the root window + /// \param res screen resources + /// \param xRandRMajor XRandR major version + /// \param xRandRMinor XRandR minor version + /// + /// \return RROutput of the primary monitor + /// + //////////////////////////////////////////////////////////// + RROutput getOutputPrimary(::Window& rootWindow, XRRScreenResources* res, int xRandRMajor, int xRandRMinor); + + //////////////////////////////////////////////////////////// + /// \brief Get coordinates of the primary monitor + /// + /// \return Position of the primary monitor + /// + //////////////////////////////////////////////////////////// + Vector2i getPrimaryMonitorPosition(); + //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// @@ -275,6 +308,7 @@ private: std::deque m_events; ///< Queue we use to store pending events for this window bool m_isExternal; ///< Tell whether the window has been created externally or by SFML int m_oldVideoMode; ///< Video mode in use before we switch to fullscreen + RRCrtc m_oldRRCrtc; ///< RRCrtc in use before we switch to fullscreen ::Cursor m_hiddenCursor; ///< As X11 doesn't provide cursor hiding, we must create a transparent one ::Cursor m_lastCursor; ///< Last cursor used -- this data is not owned by the window and is required to be always valid bool m_keyRepeat; ///< Is the KeyRepeat feature enabled? From 410c8aa5f58f9063c457716c0ca37e99112c0d1d Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Thu, 9 Aug 2018 13:03:14 +0200 Subject: [PATCH 31/39] Windows: Fixed swapped colors for custom cursors Previously the red and blue color channels were swapped, since Windows expects a different channel order for DIBs. This fixes issue #1464. --- src/SFML/Window/Win32/CursorImpl.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/SFML/Window/Win32/CursorImpl.cpp b/src/SFML/Window/Win32/CursorImpl.cpp index 28f42744..2bbaab5f 100755 --- a/src/SFML/Window/Win32/CursorImpl.cpp +++ b/src/SFML/Window/Win32/CursorImpl.cpp @@ -89,7 +89,15 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot } // Fill our bitmap with the cursor color data - std::memcpy(bitmapData, pixels, size.x * size.y * 4); + // We'll have to swap the red and blue channels here + Uint8* bitmapOffset = bitmapData; + for (std::size_t remaining = size.x * size.y; remaining; --remaining, pixels += 4) + { + *bitmapOffset++ = pixels[2]; // Blue + *bitmapOffset++ = pixels[1]; // Green + *bitmapOffset++ = pixels[0]; // Red + *bitmapOffset++ = pixels[3]; // Alpha + } // Create a dummy mask bitmap (it won't be used) HBITMAP mask = CreateBitmap(size.x, size.y, 1, 1, NULL); From 08eb31e3272c5de25a40995856009dad822c0169 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sat, 15 Sep 2018 21:36:53 +0200 Subject: [PATCH 32/39] Ensure the proper default framebuffer is bound when activating a RenderWindow. Fixes #1471. --- include/SFML/Graphics/RenderWindow.hpp | 7 +++++++ src/SFML/Graphics/RenderWindow.cpp | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/SFML/Graphics/RenderWindow.hpp b/include/SFML/Graphics/RenderWindow.hpp index 2b3b6bce..01f07828 100644 --- a/include/SFML/Graphics/RenderWindow.hpp +++ b/include/SFML/Graphics/RenderWindow.hpp @@ -177,6 +177,13 @@ protected: /// //////////////////////////////////////////////////////////// virtual void onResize(); + +private: + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + unsigned int m_defaultFrameBuffer; ///< Framebuffer to bind when targeting this window }; } // namespace sf diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 446e9060..42f4ffea 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -34,14 +34,16 @@ namespace sf { //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow() +RenderWindow::RenderWindow() : +m_defaultFrameBuffer(0) { // Nothing to do } //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) +RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) : +m_defaultFrameBuffer(0) { // Don't call the base class constructor because it contains virtual function calls create(mode, title, style, settings); @@ -49,7 +51,8 @@ RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, co //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) +RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) : +m_defaultFrameBuffer(0) { // Don't call the base class constructor because it contains virtual function calls create(handle, settings); @@ -83,7 +86,7 @@ bool RenderWindow::setActive(bool active) // try to draw to the default framebuffer of the RenderWindow if (active && result && priv::RenderTextureImplFBO::isAvailable()) { - priv::RenderTextureImplFBO::unbind(); + glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_defaultFrameBuffer)); return true; } @@ -108,6 +111,13 @@ Image RenderWindow::capture() const //////////////////////////////////////////////////////////// void RenderWindow::onCreate() { + if (priv::RenderTextureImplFBO::isAvailable()) + { + // Retrieve the framebuffer ID we have to bind when targeting the window for rendering + // We assume that this window's context is still active at this point + glCheck(glGetIntegerv(GLEXT_GL_FRAMEBUFFER_BINDING, reinterpret_cast(&m_defaultFrameBuffer))); + } + // Just initialize the render target part RenderTarget::initialize(); } From 95c9670d4c5d4f12b75143b35b8f69bafccae164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Mon, 1 Oct 2018 19:49:28 +0200 Subject: [PATCH 33/39] Fixed Windows cursor color conversion to be endian safe --- src/SFML/Window/Win32/CursorImpl.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/SFML/Window/Win32/CursorImpl.cpp b/src/SFML/Window/Win32/CursorImpl.cpp index 2bbaab5f..d1913d66 100755 --- a/src/SFML/Window/Win32/CursorImpl.cpp +++ b/src/SFML/Window/Win32/CursorImpl.cpp @@ -69,7 +69,7 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot bitmapHeader.bV5BlueMask = 0x000000ff; bitmapHeader.bV5AlphaMask = 0xff000000; - Uint8* bitmapData = NULL; + Uint32* bitmapData = NULL; HDC screenDC = GetDC(NULL); HBITMAP color = CreateDIBSection( @@ -90,13 +90,10 @@ bool CursorImpl::loadFromPixels(const Uint8* pixels, Vector2u size, Vector2u hot // Fill our bitmap with the cursor color data // We'll have to swap the red and blue channels here - Uint8* bitmapOffset = bitmapData; - for (std::size_t remaining = size.x * size.y; remaining; --remaining, pixels += 4) + Uint32* bitmapOffset = bitmapData; + for (std::size_t remaining = size.x * size.y; remaining > 0; --remaining, pixels += 4) { - *bitmapOffset++ = pixels[2]; // Blue - *bitmapOffset++ = pixels[1]; // Green - *bitmapOffset++ = pixels[0]; // Red - *bitmapOffset++ = pixels[3]; // Alpha + *bitmapOffset++ = (pixels[3] << 24) | (pixels[0] << 16) | (pixels[1] << 8) | pixels[2]; } // Create a dummy mask bitmap (it won't be used) From cc3c748ab2947925355513904b9d390457405675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Wed, 3 Oct 2018 22:02:16 +0200 Subject: [PATCH 34/39] Due to binary compatibility in a patch release the iOS fix needs to be reverted This reverts commit 08eb31e3272c5de25a40995856009dad822c0169. --- include/SFML/Graphics/RenderWindow.hpp | 7 ------- src/SFML/Graphics/RenderWindow.cpp | 18 ++++-------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/include/SFML/Graphics/RenderWindow.hpp b/include/SFML/Graphics/RenderWindow.hpp index 01f07828..2b3b6bce 100644 --- a/include/SFML/Graphics/RenderWindow.hpp +++ b/include/SFML/Graphics/RenderWindow.hpp @@ -177,13 +177,6 @@ protected: /// //////////////////////////////////////////////////////////// virtual void onResize(); - -private: - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - unsigned int m_defaultFrameBuffer; ///< Framebuffer to bind when targeting this window }; } // namespace sf diff --git a/src/SFML/Graphics/RenderWindow.cpp b/src/SFML/Graphics/RenderWindow.cpp index 42f4ffea..446e9060 100644 --- a/src/SFML/Graphics/RenderWindow.cpp +++ b/src/SFML/Graphics/RenderWindow.cpp @@ -34,16 +34,14 @@ namespace sf { //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow() : -m_defaultFrameBuffer(0) +RenderWindow::RenderWindow() { // Nothing to do } //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) : -m_defaultFrameBuffer(0) +RenderWindow::RenderWindow(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings) { // Don't call the base class constructor because it contains virtual function calls create(mode, title, style, settings); @@ -51,8 +49,7 @@ m_defaultFrameBuffer(0) //////////////////////////////////////////////////////////// -RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) : -m_defaultFrameBuffer(0) +RenderWindow::RenderWindow(WindowHandle handle, const ContextSettings& settings) { // Don't call the base class constructor because it contains virtual function calls create(handle, settings); @@ -86,7 +83,7 @@ bool RenderWindow::setActive(bool active) // try to draw to the default framebuffer of the RenderWindow if (active && result && priv::RenderTextureImplFBO::isAvailable()) { - glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, m_defaultFrameBuffer)); + priv::RenderTextureImplFBO::unbind(); return true; } @@ -111,13 +108,6 @@ Image RenderWindow::capture() const //////////////////////////////////////////////////////////// void RenderWindow::onCreate() { - if (priv::RenderTextureImplFBO::isAvailable()) - { - // Retrieve the framebuffer ID we have to bind when targeting the window for rendering - // We assume that this window's context is still active at this point - glCheck(glGetIntegerv(GLEXT_GL_FRAMEBUFFER_BINDING, reinterpret_cast(&m_defaultFrameBuffer))); - } - // Just initialize the render target part RenderTarget::initialize(); } From b47f738635ffda966528570a0ddbc1f9f7b3dd53 Mon Sep 17 00:00:00 2001 From: Maxime Alvarez Date: Fri, 10 Aug 2018 15:00:43 +0200 Subject: [PATCH 35/39] Fixed the error message when the wrong bitmap font size is selected --- src/SFML/Graphics/Font.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/SFML/Graphics/Font.cpp b/src/SFML/Graphics/Font.cpp index cafba5ba..308070a0 100644 --- a/src/SFML/Graphics/Font.cpp +++ b/src/SFML/Graphics/Font.cpp @@ -777,17 +777,22 @@ bool Font::setCurrentSize(unsigned int characterSize) const err() << "Failed to set bitmap font size to " << characterSize << std::endl; err() << "Available sizes are: "; for (int i = 0; i < face->num_fixed_sizes; ++i) - err() << face->available_sizes[i].height << " "; + { + const unsigned int size = (face->available_sizes[i].y_ppem + 32) >> 6; + err() << size << " "; + } err() << std::endl; } + else + { + err() << "Failed to set font size to " << characterSize << std::endl; + } } return result == FT_Err_Ok; } - else - { - return true; - } + + return true; } From 5189589ce2893bbf85822a975b7618f8ca2d326d Mon Sep 17 00:00:00 2001 From: Ceylo Date: Sun, 8 Apr 2018 23:21:54 +0200 Subject: [PATCH 36/39] Modernize iOS toolchain: remove BUILD_ARM64, drop support for Xcode <4.3 and don't pretend defining official CMake variables --- cmake/Macros.cmake | 7 +- cmake/toolchains/iOS.toolchain.cmake | 97 ++++++++++------------------ examples/iOS/CMakeLists.txt | 2 +- 3 files changed, 41 insertions(+), 65 deletions(-) diff --git a/cmake/Macros.cmake b/cmake/Macros.cmake index 63490245..ecb37c8b 100644 --- a/cmake/Macros.cmake +++ b/cmake/Macros.cmake @@ -1,5 +1,10 @@ include(CMakeParseArguments) +# This little macro lets you set any Xcode specific property +macro (sfml_set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE) + set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE}) +endmacro () + # set the appropriate standard library on each platform for the given target # example: sfml_set_stdlib(sfml-system) function(sfml_set_stdlib target) @@ -14,7 +19,7 @@ function(sfml_set_stdlib target) if (SFML_OS_MACOSX) if (${CMAKE_GENERATOR} MATCHES "Xcode") - set_property(TARGET ${target} PROPERTY XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + sfml_set_xcode_property(${target} CLANG_CXX_LIBRARY "libc++") else() target_compile_options(${target} PRIVATE "-stdlib=libc++") target_link_libraries(${target} PRIVATE "-stdlib=libc++") diff --git a/cmake/toolchains/iOS.toolchain.cmake b/cmake/toolchains/iOS.toolchain.cmake index abbff038..c697857f 100644 --- a/cmake/toolchains/iOS.toolchain.cmake +++ b/cmake/toolchains/iOS.toolchain.cmake @@ -22,13 +22,13 @@ # OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. # SIMULATOR - used to build for the Simulator platforms, which have an x86_64 arch. # -# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder +# IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder # By default this location is automatcially chosen based on the IOS_PLATFORM value above. # If set manually, it will override the default location and force the user of a particular Developer Platform # -# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder -# By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. -# In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. +# IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder +# By default this location is automatcially chosen based on the IOS_DEVELOPER_ROOT value. +# In this case it will always be the most up-to-date SDK found in the IOS_DEVELOPER_ROOT path. # If set manually, this will force the use of a specific SDK version # Macros: @@ -58,8 +58,8 @@ if (CMAKE_UNAME) string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") endif (CMAKE_UNAME) -set(CMAKE_C_COMPILER /usr/bin/gcc CACHE FILEPATH "" FORCE) -set(CMAKE_CXX_COMPILER /usr/bin/g++ CACHE FILEPATH "" FORCE) +set(CMAKE_C_COMPILER /usr/bin/clang CACHE FILEPATH "" FORCE) +set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE FILEPATH "" FORCE) set(CMAKE_AR ar CACHE FILEPATH "" FORCE) # Skip the platform compiler checks for cross compiling @@ -105,64 +105,43 @@ endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) if (NOT DEFINED IOS_PLATFORM) set (IOS_PLATFORM "OS") endif (NOT DEFINED IOS_PLATFORM) -set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform") - -# Setup building for arm64 or not -if (NOT DEFINED BUILD_ARM64) - set (BUILD_ARM64 true) -endif (NOT DEFINED BUILD_ARM64) -set (BUILD_ARM64 ${BUILD_ARM64} CACHE STRING "Build arm64 arch or not") +set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform: OS or SIMULATOR") # Check the platform selection and setup for developer root -if (${IOS_PLATFORM} STREQUAL OS) - message (STATUS "Targeting iPhone platform") +if (IOS_PLATFORM STREQUAL OS) set (IOS_PLATFORM_LOCATION "iPhoneOS.platform") # This causes the installers to properly locate the output libraries set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") -elseif (${IOS_PLATFORM} STREQUAL SIMULATOR) - message (STATUS "Targeting iPhoneSimulator platform") - set (SIMULATOR true) +elseif (IOS_PLATFORM STREQUAL SIMULATOR) set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") # This causes the installers to properly locate the output libraries set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") +else () + message (FATAL_ERROR "Unsupported IOS_PLATFORM value '${IOS_PLATFORM}' selected. Please choose OS or SIMULATOR") +endif () -else (${IOS_PLATFORM} STREQUAL OS) - message (FATAL_ERROR "Unsupported IOS_PLATFORM value '${IOS_PLATFORM}' selected. Please choose OS or SIMULATOR") -endif (${IOS_PLATFORM} STREQUAL OS) +# Setup iOS developer location unless specified manually with IOS_DEVELOPER_ROOT +exec_program(/usr/bin/xcode-select ARGS -print-path OUTPUT_VARIABLE XCODE_DEVELOPER_DIR) +set (IOS_DEVELOPER_ROOT "${XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer" CACHE PATH "Location of iOS Platform") -# Setup iOS developer location unless specified manually with CMAKE_IOS_DEVELOPER_ROOT -# Note Xcode 4.3 changed the installation location, choose the most recent one available -exec_program(/usr/bin/xcode-select ARGS -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR) -set (XCODE_POST_43_ROOT "${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -set (XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) - if (EXISTS ${XCODE_POST_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT}) - elseif(EXISTS ${XCODE_PRE_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT}) - endif (EXISTS ${XCODE_POST_43_ROOT}) -endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) -set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform") - -# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT -if (NOT DEFINED CMAKE_IOS_SDK_ROOT) - file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*") - if (_CMAKE_IOS_SDKS) - list (SORT _CMAKE_IOS_SDKS) - list (REVERSE _CMAKE_IOS_SDKS) - list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT) - else (_CMAKE_IOS_SDKS) - message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.") - endif (_CMAKE_IOS_SDKS) - message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}") -endif (NOT DEFINED CMAKE_IOS_SDK_ROOT) -set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") +# Find and use the most recent iOS sdk unless specified manually with IOS_SDK_ROOT +if (NOT DEFINED IOS_SDK_ROOT) + file (GLOB _IOS_SDKS "${IOS_DEVELOPER_ROOT}/SDKs/*") + if (_IOS_SDKS) + list (SORT _IOS_SDKS) + list (REVERSE _IOS_SDKS) + list (GET _IOS_SDKS 0 IOS_SDK_ROOT) + else (_IOS_SDKS) + message (FATAL_ERROR "No iOS SDK's found in default search path ${IOS_DEVELOPER_ROOT}. Manually set IOS_SDK_ROOT or install the iOS SDK.") + endif (_IOS_SDKS) + message (STATUS "Toolchain using default iOS SDK: ${IOS_SDK_ROOT}") +endif (NOT DEFINED IOS_SDK_ROOT) +set (IOS_SDK_ROOT ${IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") # Set the sysroot default to the most recent SDK -set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") -message (STATUS "iOS sysroot=${CMAKE_OSX_SYSROOT}") +set (CMAKE_OSX_SYSROOT ${IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") # set the architecture for iOS if (${IOS_PLATFORM} STREQUAL OS) @@ -172,21 +151,19 @@ elseif (${IOS_PLATFORM} STREQUAL SIMULATOR) set (IOS_ARCH x86_64) endif (${IOS_PLATFORM} STREQUAL OS) -set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS" FORCE) -set (CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS ${IOS_ARCH}) -message (STATUS "iOS architecture=${IOS_ARCH}") +set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS" FORCE) # Set the find root to the iOS developer roots and to user defined paths -set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root") +set (CMAKE_FIND_ROOT_PATH ${IOS_DEVELOPER_ROOT} ${IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE STRING "iOS find search path root") # default to searching for frameworks first set (CMAKE_FIND_FRAMEWORK FIRST) # set up the default search directories for frameworks set (CMAKE_SYSTEM_FRAMEWORK_PATH - ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks - ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks - ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks + ${IOS_SDK_ROOT}/System/Library/Frameworks + ${IOS_SDK_ROOT}/System/Library/PrivateFrameworks + ${IOS_SDK_ROOT}/Developer/Library/Frameworks ) # only search the iOS sdks, not the remainder of the host filesystem @@ -195,12 +172,6 @@ set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -# This little macro lets you set any XCode specific property -macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE) - set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE}) -endmacro (set_xcode_property) - - # This macro lets you find executable programs on the host system macro (find_host_package) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) diff --git a/examples/iOS/CMakeLists.txt b/examples/iOS/CMakeLists.txt index 96450f42..24aca5f4 100644 --- a/examples/iOS/CMakeLists.txt +++ b/examples/iOS/CMakeLists.txt @@ -21,5 +21,5 @@ sfml_add_example(ios_demo GUI_APP "-framework OpenGLES") # The app needs an identifier and signing to work correctly -SET_XCODE_PROPERTY(ios_demo CODE_SIGN_IDENTITY "iPhone Developer") +sfml_set_xcode_property(ios_demo CODE_SIGN_IDENTITY "iPhone Developer") set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.sfml.ios_demo") From 43f57b2f25e2fee4fc0dcc5dd5f4884b277113f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Thu, 11 Oct 2018 21:50:38 +0200 Subject: [PATCH 37/39] Disabled the JNI part due to compatibility issues --- examples/android/app/src/main/jni/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/android/app/src/main/jni/main.cpp b/examples/android/app/src/main/jni/main.cpp index e5445b5b..edf67b45 100644 --- a/examples/android/app/src/main/jni/main.cpp +++ b/examples/android/app/src/main/jni/main.cpp @@ -6,7 +6,8 @@ // Do we want to showcase direct JNI/NDK interaction? // Undefine this to get real cross-platform code. -#define USE_JNI +// Uncomment this to try JNI access; this seems to be broken in latest NDKs +//#define USE_JNI #if defined(USE_JNI) // These headers are only needed for direct NDK/JDK interaction From 9fba1dff27520e9af464ebacf0c4b3ce23a2dd26 Mon Sep 17 00:00:00 2001 From: Jonny Paton Date: Mon, 27 Aug 2018 11:49:42 +0100 Subject: [PATCH 38/39] Add -ObjC flag to fix static linking on macOS --- src/SFML/Window/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 1fe8b5a4..98ea4394 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -229,6 +229,11 @@ sfml_add_library(sfml-window SOURCES ${SRC} ${PLATFORM_SRC}) target_link_libraries(sfml-window PUBLIC sfml-system) +# When static linking on macOS, we need to add this flag for objective C to work +if ((NOT BUILD_SHARED_LIBS) AND SFML_OS_MACOSX) + target_link_libraries(sfml-window PRIVATE -ObjC) +endif() + # find and setup usage for external libraries if(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OPENBSD) sfml_find_package(X11 INCLUDE "X11_INCLUDE_DIR" LINK "X11_X11_LIB" "X11_Xrandr_LIB") From 2f11710abc5aa478503a7ff3f9e654bd2078ebab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Tue, 2 Oct 2018 23:17:54 +0200 Subject: [PATCH 39/39] Updated the changelog and version number for 2.5.1 --- CMakeLists.txt | 2 +- changelog.md | 48 +++++++++++++++++++++++++++++++++++++++++ include/SFML/Config.hpp | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9eb250ef..e821a49b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake) # setup version numbers set(VERSION_MAJOR 2) set(VERSION_MINOR 5) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) # add an option for choosing the build type (shared or static) if(NOT (SFML_OS_IOS OR SFML_OS_ANDROID)) diff --git a/changelog.md b/changelog.md index c51ee3ab..6174a84f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,53 @@ # Changelog +## SFML 2.5.1 + +Also available on the website: https://www.sfml-dev.org/changelog.php#sfml-2.5.1 + +### General + + * Various CMake fixes (#1414, #1416, #1436, #1439, #1467, #1470) + * Fixed the installation of pkg-config files (#1466) + * Fixed two conversion warnings (#1454) + * [Android] Fixes all symbols in sfml-main are hidden (#1457, #1460) + * [Android] Fixed some `#define` flag problem (#1458) + * [Android] Fix deadlock in main cleanup (#1265) + * [iOS] Modernized toolchain file (#1411) + * [iOS] Check that `` is used (#1412) + * [macOS] Add `-ObjC` flag to fix static linking on macOS (#1485) + +### Window + +**Bugfixes** + + * [iOS] Use default supported rotations when none are specified (#1417) + * [iOS] Fixed autocomplete window overlaps keyboard (#1473, #1482) + * [Linux] Fixed dual monitor issue (#1226, #1238) + * [Linux] Fixed issue where fullscreen window didn't go over task bars on top and left on in Ubuntu (#1224) + * [Linux] Fixed the Unix clipboard implementation causing an abort due to internal data races in Xlib (#1437) + * [macOS] Added additional system cursors (#1401, #1413, #1425) + * [Windows] Fixed swapped colors for custom cursors (#1464, #1465, #1491) + +### Graphics + +**Bugfixes** + + * Fixed a bug in which a `sf::RenderTexture` would not be re-activated after being re-created (#1438) + * Fixed `sf::RenderTextureImplFBO`'s destructor incorrectly triggering deletion of other `sf::RenderTextureImplFBO`'s active FBOs (#1440) + * Fix `sf::RenderWindow::setActive` incorrectly trying to unbind an FBO during deactivation (#1442) + * Fixed `sf::RenderTexture::display()` dereferencing a NULL pointer when being called before `sf::RenderTexture::create()` (#1446) + * Fixed bug in `sf::Text` when applying an outline color/thickness (#1176) + * Squash duplicated `sf::Font` glyphs to single chars (#1461) + * Fixed two issues with glyph sub-pixel positioning (#1452) + * Reduced context locking & unlocking while creating textures (#1459) + * Fixed the error message when the wrong bitmap font size is selected (#1456, #1474, #1492) + +### Audio + +**Bugfixes** + + * Fixed performance issue with reading WAV files (#1450) + ## SFML 2.5.0 Also available on the website: https://www.sfml-dev.org/changelog.php#sfml-2.5.0 diff --git a/include/SFML/Config.hpp b/include/SFML/Config.hpp index aae5f548..40b677eb 100644 --- a/include/SFML/Config.hpp +++ b/include/SFML/Config.hpp @@ -31,7 +31,7 @@ //////////////////////////////////////////////////////////// #define SFML_VERSION_MAJOR 2 #define SFML_VERSION_MINOR 5 -#define SFML_VERSION_PATCH 0 +#define SFML_VERSION_PATCH 1 ////////////////////////////////////////////////////////////