diff --git a/src/SFML/Window/macOS/HIDInputManager.hpp b/src/SFML/Window/macOS/HIDInputManager.hpp index 8c7982b3d..3e3f573ba 100644 --- a/src/SFML/Window/macOS/HIDInputManager.hpp +++ b/src/SFML/Window/macOS/HIDInputManager.hpp @@ -30,6 +30,7 @@ //////////////////////////////////////////////////////////// #include #include +#include #include #include @@ -40,7 +41,7 @@ namespace sf::priv { -using IOHIDElements = std::vector; +using IOHIDElements = std::vector>; //////////////////////////////////////////////////////////// /// \brief sf::priv::InputImpl helper @@ -93,7 +94,7 @@ public: /// \return a retained CFDictionaryRef /// //////////////////////////////////////////////////////////// - static CFDictionaryRef copyDevicesMask(std::uint32_t page, std::uint32_t usage); + static CFPtr copyDevicesMask(std::uint32_t page, std::uint32_t usage); //////////////////////////////////////////////////////////// /// \brief Try to convert a character into a SFML key code @@ -243,10 +244,10 @@ private: /// /// \param page HID page like kHIDPage_GenericDesktop /// \param usage HID usage page like kHIDUsage_GD_Keyboard or kHIDUsage_GD_Mouse - /// \return a retained, non-empty CFSetRef of IOHIDDeviceRef or a null pointer + /// \return a retained, non-empty __CFSet pointer of IOHIDDeviceRef or a null pointer /// //////////////////////////////////////////////////////////// - CFSetRef copyDevices(std::uint32_t page, std::uint32_t usage); + CFPtr copyDevices(std::uint32_t page, std::uint32_t usage); //////////////////////////////////////////////////////////// /// \brief Check if a key is pressed @@ -286,8 +287,8 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - IOHIDManagerRef m_manager{}; ///< Underlying HID Manager - bool m_keysInitialized{}; ///< Has initializeKeyboard been called at least once? + CFPtr m_manager; ///< Underlying HID Manager + bool m_keysInitialized{}; ///< Has initializeKeyboard been called at least once? EnumArray m_keys; ///< All the keys on any connected keyboard EnumArray m_keyToScancodeMapping{}; ///< Mapping from Key to Scancode EnumArray m_scancodeToKeyMapping{}; ///< Mapping from Scancode to Key diff --git a/src/SFML/Window/macOS/HIDInputManager.mm b/src/SFML/Window/macOS/HIDInputManager.mm index bacedcb64..38bf8af30 100644 --- a/src/SFML/Window/macOS/HIDInputManager.mm +++ b/src/SFML/Window/macOS/HIDInputManager.mm @@ -70,23 +70,19 @@ long HIDInputManager::getLocationID(IOHIDDeviceRef device) //////////////////////////////////////////////////////////// -CFDictionaryRef HIDInputManager::copyDevicesMask(std::uint32_t page, std::uint32_t usage) +CFPtr HIDInputManager::copyDevicesMask(std::uint32_t page, std::uint32_t usage) { // Create the dictionary. - CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, - 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + auto dict = CFPtr( + CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); // Add the page value. - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); - CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), value); - CFRelease(value); + auto value = CFPtr(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page)); + CFDictionarySetValue(dict.get(), CFSTR(kIOHIDDeviceUsagePageKey), value.get()); // Add the usage value (which is only valid if page value exists). - value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); - CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), value); - CFRelease(value); + value = CFPtr(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage)); + CFDictionarySetValue(dict.get(), CFSTR(kIOHIDDeviceUsageKey), value.get()); return dict; } @@ -713,8 +709,8 @@ String HIDInputManager::getDescription(Keyboard::Scancode code) HIDInputManager::HIDInputManager() { // Create an HID Manager reference - m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - const IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone); + m_manager = CFPtr(IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); + const IOReturn openStatus = IOHIDManagerOpen(m_manager.get(), kIOHIDOptionsTypeNone); if (openStatus != kIOReturnSuccess) { @@ -753,7 +749,7 @@ void HIDInputManager::initializeKeyboard() // in approximately constant time. // Get only keyboards - CFSetRef underlying = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); + const auto underlying = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); if (underlying == nullptr) { err() << "No keyboard detected by the HID manager!" << std::endl; @@ -761,12 +757,10 @@ void HIDInputManager::initializeKeyboard() return; } - auto* const keyboards = static_cast(underlying); // Toll-Free Bridge - for (id keyboard in keyboards) // NOLINT(cppcoreguidelines-init-variables) + auto* const keyboards = static_cast(underlying.get()); // Toll-Free Bridge + for (id keyboard in keyboards) // NOLINT(cppcoreguidelines-init-variables) loadKeyboard(static_cast(keyboard)); - CFRelease(underlying); - //////////////////////////////////////////////////////////// // At this point m_keys is filled with as many IOHIDElementRef as possible } @@ -775,22 +769,20 @@ void HIDInputManager::initializeKeyboard() //////////////////////////////////////////////////////////// void HIDInputManager::loadKeyboard(IOHIDDeviceRef keyboard) { - CFArrayRef underlying = IOHIDDeviceCopyMatchingElements(keyboard, nullptr, kIOHIDOptionsTypeNone); - if ((underlying == nullptr) || (CFArrayGetCount(underlying) == 0)) + const auto underlying = CFPtr(IOHIDDeviceCopyMatchingElements(keyboard, nullptr, kIOHIDOptionsTypeNone)); + if ((underlying == nullptr) || (CFArrayGetCount(underlying.get()) == 0)) { err() << "Detected a keyboard without any keys." << std::endl; return; } - auto* const keys = static_cast(underlying); // Toll-Free Bridge - for (id key in keys) // NOLINT(cppcoreguidelines-init-variables) + auto* const keys = static_cast(underlying.get()); // Toll-Free Bridge + for (id key in keys) // NOLINT(cppcoreguidelines-init-variables) { auto* elem = static_cast(key); if (IOHIDElementGetUsagePage(elem) == kHIDPage_KeyboardOrKeypad) loadKey(elem); } - - CFRelease(underlying); } @@ -802,7 +794,7 @@ void HIDInputManager::loadKey(IOHIDElementRef key) if (code != Keyboard::Scan::Unknown) { CFRetain(key); - m_keys[code].push_back(key); + m_keys[code].emplace_back(key); } } @@ -815,13 +807,12 @@ void HIDInputManager::buildMappings() m_scancodeToKeyMapping.fill(Keyboard::Key::Unknown); // Get the current keyboard layout - TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource(); - const auto* layoutData = static_cast(TISGetInputSourceProperty(tis, kTISPropertyUnicodeKeyLayoutData)); + const auto tis = CFPtr(TISCopyCurrentKeyboardLayoutInputSource()); + const auto* layoutData = static_cast(TISGetInputSourceProperty(tis.get(), kTISPropertyUnicodeKeyLayoutData)); if (layoutData == nullptr) { err() << "Cannot get the keyboard layout\n"; - CFRelease(tis); return; } @@ -905,8 +896,6 @@ void HIDInputManager::buildMappings() m_keyToScancodeMapping[code] = scan; m_scancodeToKeyMapping[scan] = code; } - - CFRelease(tis); } @@ -925,46 +914,30 @@ void HIDInputManager::keyboardChanged(CFNotificationCenterRef /* center */, //////////////////////////////////////////////////////////// void HIDInputManager::freeUp() { - if (m_manager != nil) - CFRelease(m_manager); - - m_manager = nil; + m_manager.reset(); if (m_keysInitialized) - { for (auto& key : m_keys) - { - for (IOHIDElementRef iohidElementRef : key) - CFRelease(iohidElementRef); - key.clear(); - } - } m_keysInitialized = false; } //////////////////////////////////////////////////////////// -CFSetRef HIDInputManager::copyDevices(std::uint32_t page, std::uint32_t usage) +CFPtr HIDInputManager::copyDevices(std::uint32_t page, std::uint32_t usage) { // Filter and keep only the requested devices - CFDictionaryRef mask = copyDevicesMask(page, usage); + const auto mask = copyDevicesMask(page, usage); - IOHIDManagerSetDeviceMatching(m_manager, mask); + IOHIDManagerSetDeviceMatching(m_manager.get(), mask.get()); - CFRelease(mask); - mask = nil; - - CFSetRef devices = IOHIDManagerCopyDevices(m_manager); + auto devices = CFPtr(IOHIDManagerCopyDevices(m_manager.get())); if (devices == nullptr) return nullptr; // Is there at least one device? - if (CFSetGetCount(devices) < 1) - { - CFRelease(devices); + if (CFSetGetCount(devices.get()) < 1) return nullptr; - } return devices; } @@ -978,13 +951,12 @@ bool HIDInputManager::isPressed(IOHIDElements& elements) const { IOHIDValueRef value = nil; - IOHIDDeviceRef device = IOHIDElementGetDevice(*it); - IOHIDDeviceGetValue(device, *it, &value); + IOHIDDeviceRef device = IOHIDElementGetDevice(it->get()); + IOHIDDeviceGetValue(device, it->get(), &value); if (!value) { // This means some kind of error / disconnection so we remove this element from our database. - CFRelease(*it); it = elements.erase(it); } else diff --git a/src/SFML/Window/macOS/HIDJoystickManager.cpp b/src/SFML/Window/macOS/HIDJoystickManager.cpp index 3c05db8cc..f005dd979 100644 --- a/src/SFML/Window/macOS/HIDJoystickManager.cpp +++ b/src/SFML/Window/macOS/HIDJoystickManager.cpp @@ -61,10 +61,9 @@ unsigned int HIDJoystickManager::getJoystickCount() //////////////////////////////////////////////////////////// -CFSetRef HIDJoystickManager::copyJoysticks() +CFPtr HIDJoystickManager::copyJoysticks() { - CFSetRef devices = IOHIDManagerCopyDevices(m_manager); - return devices; + return CFPtr(IOHIDManagerCopyDevices(m_manager)); } @@ -73,17 +72,15 @@ HIDJoystickManager::HIDJoystickManager() { m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - CFDictionaryRef mask0 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); + const auto mask0 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick); - CFDictionaryRef mask1 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); + const auto mask1 = HIDInputManager::copyDevicesMask(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad); - std::array maskArray = {mask0, mask1}; - CFArrayRef mask = CFArrayCreate(nullptr, reinterpret_cast(maskArray.data()), maskArray.size(), nullptr); + std::array maskArray = {mask0.get(), mask1.get()}; + const auto mask = CFPtr( + CFArrayCreate(nullptr, reinterpret_cast(maskArray.data()), maskArray.size(), nullptr)); - IOHIDManagerSetDeviceMatchingMultiple(m_manager, mask); - CFRelease(mask); - CFRelease(mask1); - CFRelease(mask0); + IOHIDManagerSetDeviceMatchingMultiple(m_manager, mask.get()); IOHIDManagerRegisterDeviceMatchingCallback(m_manager, pluggedIn, this); diff --git a/src/SFML/Window/macOS/HIDJoystickManager.hpp b/src/SFML/Window/macOS/HIDJoystickManager.hpp index e4f442fa9..706d2913e 100644 --- a/src/SFML/Window/macOS/HIDJoystickManager.hpp +++ b/src/SFML/Window/macOS/HIDJoystickManager.hpp @@ -75,10 +75,10 @@ public: //////////////////////////////////////////////////////////// /// \brief Copy the devices associated with this HID manager /// - /// \return a retained CFSetRef of IOHIDDeviceRef or a null pointer + /// \return a retained __CFSet pointer of IOHIDDeviceRef or a null pointer /// //////////////////////////////////////////////////////////// - CFSetRef copyJoysticks(); + CFPtr copyJoysticks(); private: //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/macOS/InputImpl.mm b/src/SFML/Window/macOS/InputImpl.mm index 633553afa..2ca124a98 100644 --- a/src/SFML/Window/macOS/InputImpl.mm +++ b/src/SFML/Window/macOS/InputImpl.mm @@ -212,12 +212,12 @@ void setMousePosition(Vector2i position) const CGPoint pos = CGPointMake(position.x / scale, position.y / scale); // Place the cursor. - CGEventRef event = CGEventCreateMouseEvent(nullptr, - kCGEventMouseMoved, - pos, - /* we don't care about this: */ kCGMouseButtonLeft); - CGEventPost(kCGHIDEventTap, event); - CFRelease(event); + const auto event = CFPtr( + CGEventCreateMouseEvent(nullptr, + kCGEventMouseMoved, + pos, + /* we don't care about this: */ kCGMouseButtonLeft)); + CGEventPost(kCGHIDEventTap, event.get()); // This is a workaround to deprecated CGSetLocalEventsSuppressionInterval. } diff --git a/src/SFML/Window/macOS/JoystickImpl.cpp b/src/SFML/Window/macOS/JoystickImpl.cpp index e380306d4..75c7efe2c 100644 --- a/src/SFML/Window/macOS/JoystickImpl.cpp +++ b/src/SFML/Window/macOS/JoystickImpl.cpp @@ -132,15 +132,15 @@ bool JoystickImpl::isConnected(unsigned int index) if (connectedCount > openedCount) { // Get all devices - CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks(); + const auto devices = CFPtr(HIDJoystickManager::getInstance().copyJoysticks()); if (devices != nullptr) { - const CFIndex size = CFSetGetCount(devices); + const CFIndex size = CFSetGetCount(devices.get()); if (size > 0) { std::vector array(static_cast(size)); // array of IOHIDDeviceRef - CFSetGetValues(devices, array.data()); + CFSetGetValues(devices.get(), array.data()); // If there exists a device d s.t. there is no j s.t. // m_locationIDs[j] == d's location then we have a new device. @@ -166,8 +166,6 @@ bool JoystickImpl::isConnected(unsigned int index) } } } - - CFRelease(devices); } } } @@ -185,14 +183,14 @@ bool JoystickImpl::open(unsigned int index) const Location deviceLoc = m_locationIDs[index]; // The device we need to load // Get all devices - CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks(); + const auto devices = HIDJoystickManager::getInstance().copyJoysticks(); if (devices == nullptr) return false; // Get a usable copy of the joysticks devices. - const CFIndex joysticksCount = CFSetGetCount(devices); + const CFIndex joysticksCount = CFSetGetCount(devices.get()); std::vector devicesArray(static_cast(joysticksCount)); - CFSetGetValues(devices, devicesArray.data()); + CFSetGetValues(devices.get(), devicesArray.data()); // Get the desired joystick. IOHIDDeviceRef self = nil; @@ -204,33 +202,28 @@ bool JoystickImpl::open(unsigned int index) } if (self == nil) - { - CFRelease(devices); return false; - } m_identification.name = getDeviceString(self, CFSTR(kIOHIDProductKey), m_index); m_identification.vendorId = getDeviceUint(self, CFSTR(kIOHIDVendorIDKey), m_index); m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey), m_index); // Get a list of all elements attached to the device. - CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, nullptr, kIOHIDOptionsTypeNone); + const auto elements = CFPtr(IOHIDDeviceCopyMatchingElements(self, nullptr, kIOHIDOptionsTypeNone)); if (elements == nullptr) - { - CFRelease(devices); return false; - } // Go through all connected elements. - const CFIndex elementsCount = CFArrayGetCount(elements); + const CFIndex elementsCount = CFArrayGetCount(elements.get()); for (int i = 0; i < elementsCount; ++i) { - auto* element = static_cast(const_cast(CFArrayGetValueAtIndex(elements, i))); - switch (IOHIDElementGetUsagePage(element)) + auto element = std::shared_ptr(CFPtr( + static_cast(const_cast(CFArrayGetValueAtIndex(elements.get(), i))))); + switch (IOHIDElementGetUsagePage(element.get())) { case kHIDPage_GenericDesktop: - switch (IOHIDElementGetUsage(element)) + switch (IOHIDElementGetUsage(element.get())) { case kHIDUsage_GD_X: m_axis[Joystick::Axis::X] = element; @@ -263,8 +256,8 @@ bool JoystickImpl::open(unsigned int index) // We assume this model here as well. Hence, with 4 switches and intermediate // positions we have 8 values (0-7) plus the "null" state (8). { - const CFIndex min = IOHIDElementGetLogicalMin(element); - const CFIndex max = IOHIDElementGetLogicalMax(element); + const CFIndex min = IOHIDElementGetLogicalMin(element.get()); + const CFIndex max = IOHIDElementGetLogicalMax(element.get()); if (min != 0 || max != 7) { @@ -283,18 +276,18 @@ bool JoystickImpl::open(unsigned int index) // We assume a game pad is an application collection, meaning it doesn't hold // any values per say. They kind of "emit" the joystick's usages. // See ยง3.4.3 Usage Types (Collection) of HUT v1.12 - if (IOHIDElementGetCollectionType(element) != kIOHIDElementCollectionTypeApplication) + if (IOHIDElementGetCollectionType(element.get()) != kIOHIDElementCollectionTypeApplication) { sf::err() << std::hex << "Gamepage (vendor/product id: 0x" << m_identification.vendorId << "/0x" << m_identification.productId << ") is not an CA but a 0x" - << IOHIDElementGetCollectionType(element) << std::dec << std::endl; + << IOHIDElementGetCollectionType(element.get()) << std::dec << std::endl; } break; default: #ifdef SFML_DEBUG sf::err() << "Unexpected usage for element of Page Generic Desktop: 0x" << std::hex - << IOHIDElementGetUsage(element) << std::dec << std::endl; + << IOHIDElementGetUsage(element.get()) << std::dec << std::endl; #endif break; } @@ -315,24 +308,7 @@ bool JoystickImpl::open(unsigned int index) // HID Usage (assigned by manufacturer and/or a driver). std::sort(m_buttons.begin(), m_buttons.end(), - [](IOHIDElementRef b1, IOHIDElementRef b2) { return IOHIDElementGetUsage(b1) < IOHIDElementGetUsage(b2); }); - - // Retain all these objects for personal use - for (IOHIDElementRef iohidElementRef : m_buttons) - CFRetain(iohidElementRef); - - for (const auto& [axis, iohidElementRef] : m_axis) - CFRetain(iohidElementRef); - - if (m_hat != nullptr) - CFRetain(m_hat); - - // Note: we didn't retain element in the switch because we might have multiple - // Axis X (for example) and we want to keep only the last one. To prevent - // leaking we retain objects 'only' now. - - CFRelease(devices); - CFRelease(elements); + [](auto b1, auto b2) { return IOHIDElementGetUsage(b1.get()) < IOHIDElementGetUsage(b2.get()); }); return true; } @@ -343,20 +319,9 @@ void JoystickImpl::close() { const AutoreleasePool pool; - for (IOHIDElementRef iohidElementRef : m_buttons) - CFRelease(iohidElementRef); - m_buttons.clear(); - - for (const auto& [axis, iohidElementRef] : m_axis) - CFRelease(iohidElementRef); - m_axis.clear(); - - if (m_hat != nullptr) - CFRelease(m_hat); - - m_hat = nullptr; + m_hat.reset(); // And we unregister this joystick m_locationIDs[m_index] = 0; @@ -406,14 +371,14 @@ JoystickState JoystickImpl::update() const Location selfLoc = m_locationIDs[m_index]; // Get all devices - CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks(); + auto devices = HIDJoystickManager::getInstance().copyJoysticks(); if (devices == nullptr) return disconnectedState; // Get a usable copy of the joysticks devices. - const CFIndex joysticksCount = CFSetGetCount(devices); + const CFIndex joysticksCount = CFSetGetCount(devices.get()); std::vector devicesArray(static_cast(joysticksCount)); - CFSetGetValues(devices, devicesArray.data()); + CFSetGetValues(devices.get(), devicesArray.data()); // Search for it bool found = false; @@ -424,19 +389,15 @@ JoystickState JoystickImpl::update() found = true; } - // Release unused stuff - CFRelease(devices); - // If not found we consider it disconnected if (!found) return disconnectedState; // Update buttons' state - unsigned int i = 0; - for (auto it = m_buttons.begin(); it != m_buttons.end(); ++it, ++i) + for (std::size_t i = 0; i < m_buttons.size(); ++i) { IOHIDValueRef value = nil; - IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value); + IOHIDDeviceGetValue(IOHIDElementGetDevice(m_buttons[i].get()), m_buttons[i].get(), &value); // Check for plug out. if (!value) @@ -452,7 +413,7 @@ JoystickState JoystickImpl::update() for (const auto& [axis, iohidElementRef] : m_axis) { IOHIDValueRef value = nil; - IOHIDDeviceGetValue(IOHIDElementGetDevice(iohidElementRef), iohidElementRef, &value); + IOHIDDeviceGetValue(IOHIDElementGetDevice(iohidElementRef.get()), iohidElementRef.get(), &value); // Check for plug out. if (!value) @@ -470,8 +431,8 @@ JoystickState JoystickImpl::update() // This method might not be very accurate (the "0 position" can be // slightly shift with some device) but we don't care because most // of devices are so sensitive that this is not relevant. - const auto physicalMax = static_cast(IOHIDElementGetPhysicalMax(iohidElementRef)); - const auto physicalMin = static_cast(IOHIDElementGetPhysicalMin(iohidElementRef)); + const auto physicalMax = static_cast(IOHIDElementGetPhysicalMax(iohidElementRef.get())); + const auto physicalMin = static_cast(IOHIDElementGetPhysicalMin(iohidElementRef.get())); const double scaledMin = -100; const double scaledMax = 100; const double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical); @@ -489,7 +450,7 @@ JoystickState JoystickImpl::update() if (m_hat != nullptr) { IOHIDValueRef value = nil; - IOHIDDeviceGetValue(IOHIDElementGetDevice(m_hat), m_hat, &value); + IOHIDDeviceGetValue(IOHIDElementGetDevice(m_hat.get()), m_hat.get(), &value); // Check for plug out. if (!value) diff --git a/src/SFML/Window/macOS/JoystickImpl.hpp b/src/SFML/Window/macOS/JoystickImpl.hpp index 5a0ca4cff..d64d53a88 100644 --- a/src/SFML/Window/macOS/JoystickImpl.hpp +++ b/src/SFML/Window/macOS/JoystickImpl.hpp @@ -111,14 +111,14 @@ private: // Member data //////////////////////////////////////////////////////////// using Location = long; - using AxisMap = std::unordered_map; - using ButtonsVector = std::vector; + using AxisMap = std::unordered_map>; + using ButtonsVector = std::vector>; - AxisMap m_axis; ///< Axes (but not POV/Hat) of the joystick - IOHIDElementRef m_hat{}; ///< POV/Hat axis of the joystick - ButtonsVector m_buttons; ///< Buttons of the joystick - unsigned int m_index{}; ///< SFML index - Joystick::Identification m_identification; ///< Joystick identification + AxisMap m_axis; ///< Axes (but not POV/Hat) of the joystick + std::shared_ptr<__IOHIDElement> m_hat; ///< POV/Hat axis of the joystick + ButtonsVector m_buttons; ///< Buttons of the joystick + unsigned int m_index{}; ///< SFML index + Joystick::Identification m_identification; ///< Joystick identification // NOLINTNEXTLINE(readability-identifier-naming) static inline std::array m_locationIDs{}; ///< Global Joystick register diff --git a/src/SFML/Window/macOS/Utils.hpp b/src/SFML/Window/macOS/Utils.hpp new file mode 100644 index 000000000..4c443ac10 --- /dev/null +++ b/src/SFML/Window/macOS/Utils.hpp @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#pragma once + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include +#include + + +namespace sf::priv +{ +//////////////////////////////////////////////////////////// +/// \brief Class for freeing Core Foundation pointers +/// +//////////////////////////////////////////////////////////// +struct CFDeleter +{ + template + void operator()(T* data) const + { + CFRelease(data); + } +}; + +//////////////////////////////////////////////////////////// +/// \brief Class template for wrapping owning raw pointers from Core Foundation +/// +//////////////////////////////////////////////////////////// +template +using CFPtr = std::unique_ptr, CFDeleter>; +} // namespace sf::priv diff --git a/src/SFML/Window/macOS/VideoModeImpl.cpp b/src/SFML/Window/macOS/VideoModeImpl.cpp index f32b5b804..47798cd3d 100644 --- a/src/SFML/Window/macOS/VideoModeImpl.cpp +++ b/src/SFML/Window/macOS/VideoModeImpl.cpp @@ -27,6 +27,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include #include #include @@ -41,7 +42,7 @@ namespace sf::priv std::vector VideoModeImpl::getFullscreenModes() { // Retrieve all modes available for main screen only. - CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), nullptr); + const auto cgmodes = CFPtr(CGDisplayCopyAllDisplayModes(CGMainDisplayID(), nullptr)); if (cgmodes == nullptr) { @@ -53,10 +54,10 @@ std::vector VideoModeImpl::getFullscreenModes() std::vector modes = {desktop}; // Loop on each mode and convert it into a sf::VideoMode object. - const CFIndex modesCount = CFArrayGetCount(cgmodes); + const CFIndex modesCount = CFArrayGetCount(cgmodes.get()); for (CFIndex i = 0; i < modesCount; ++i) { - auto* cgmode = static_cast(const_cast(CFArrayGetValueAtIndex(cgmodes, i))); + auto* cgmode = static_cast(const_cast(CFArrayGetValueAtIndex(cgmodes.get(), i))); const VideoMode mode = convertCGModeToSFMode(cgmode); @@ -69,9 +70,6 @@ std::vector VideoModeImpl::getFullscreenModes() modes.push_back(mode); } - // Clean up memory. - CFRelease(cgmodes); - return modes; } diff --git a/src/SFML/Window/macOS/cg_sf_conversion.mm b/src/SFML/Window/macOS/cg_sf_conversion.mm index 7c9f39d37..352676bfd 100644 --- a/src/SFML/Window/macOS/cg_sf_conversion.mm +++ b/src/SFML/Window/macOS/cg_sf_conversion.mm @@ -27,6 +27,7 @@ // Headers //////////////////////////////////////////////////////////// #import +#include #include #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -37,21 +38,16 @@ namespace sf::priv //////////////////////////////////////////////////////////// unsigned int modeBitsPerPixel(CGDisplayModeRef mode) { - unsigned int bpp = 0; // no match - // Compare encoding. - CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); - if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - bpp = 32; - else if (CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - bpp = 16; - else if (CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - bpp = 8; + const auto pixEnc = CFPtr(CGDisplayModeCopyPixelEncoding(mode)); + if (CFStringCompare(pixEnc.get(), CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + return 32; + if (CFStringCompare(pixEnc.get(), CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + return 16; + if (CFStringCompare(pixEnc.get(), CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + return 8; - // Clean up memory. - CFRelease(pixEnc); - - return bpp; + return 0; }