Modernize memory management of X11 types
This commit is contained in:
parent
b391be2316
commit
27542637aa
@ -123,6 +123,7 @@ elseif(SFML_OS_LINUX OR SFML_OS_FREEBSD OR SFML_OS_OPENBSD OR SFML_OS_NETBSD)
|
|||||||
${SRCROOT}/Unix/SensorImpl.hpp
|
${SRCROOT}/Unix/SensorImpl.hpp
|
||||||
${SRCROOT}/Unix/Display.cpp
|
${SRCROOT}/Unix/Display.cpp
|
||||||
${SRCROOT}/Unix/Display.hpp
|
${SRCROOT}/Unix/Display.hpp
|
||||||
|
${SRCROOT}/Unix/Utils.hpp
|
||||||
${SRCROOT}/Unix/VideoModeImpl.cpp
|
${SRCROOT}/Unix/VideoModeImpl.cpp
|
||||||
${SRCROOT}/Unix/VulkanImplX11.cpp
|
${SRCROOT}/Unix/VulkanImplX11.cpp
|
||||||
${SRCROOT}/Unix/VulkanImplX11.hpp
|
${SRCROOT}/Unix/VulkanImplX11.hpp
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
#include <SFML/System/Android/Activity.hpp>
|
#include <SFML/System/Android/Activity.hpp>
|
||||||
#endif
|
#endif
|
||||||
#if defined(SFML_SYSTEM_LINUX) && !defined(SFML_USE_DRM)
|
#if defined(SFML_SYSTEM_LINUX) && !defined(SFML_USE_DRM)
|
||||||
|
#include <SFML/Window/Unix/Utils.hpp>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -424,10 +426,8 @@ XVisualInfo EglContext::selectBestVisual(::Display* XDisplay, unsigned int bitsP
|
|||||||
vTemplate.visualid = static_cast<VisualID>(nativeVisualId);
|
vTemplate.visualid = static_cast<VisualID>(nativeVisualId);
|
||||||
|
|
||||||
// Get X11 visuals compatible with this EGL config
|
// Get X11 visuals compatible with this EGL config
|
||||||
XVisualInfo *availableVisuals, bestVisual;
|
int visualCount = 0;
|
||||||
int visualCount = 0;
|
auto availableVisuals = X11Ptr<XVisualInfo[]> XGetVisualInfo(XDisplay, VisualIDMask, &vTemplate, &visualCount));
|
||||||
|
|
||||||
availableVisuals = XGetVisualInfo(XDisplay, VisualIDMask, &vTemplate, &visualCount);
|
|
||||||
|
|
||||||
if (visualCount == 0)
|
if (visualCount == 0)
|
||||||
{
|
{
|
||||||
@ -438,10 +438,7 @@ XVisualInfo EglContext::selectBestVisual(::Display* XDisplay, unsigned int bitsP
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pick up the best one
|
// Pick up the best one
|
||||||
bestVisual = availableVisuals[0];
|
return availableVisuals[0];
|
||||||
XFree(availableVisuals);
|
|
||||||
|
|
||||||
return bestVisual;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/Unix/CursorImpl.hpp>
|
#include <SFML/Window/Unix/CursorImpl.hpp>
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
|
#include <SFML/Window/Unix/Utils.hpp>
|
||||||
|
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
@ -39,6 +40,15 @@
|
|||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XcursorImage>
|
||||||
|
{
|
||||||
|
void operator()(XcursorImage* cursorImage) const
|
||||||
|
{
|
||||||
|
XcursorImageDestroy(cursorImage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
CursorImpl::CursorImpl() : m_display(openDisplay())
|
CursorImpl::CursorImpl() : m_display(openDisplay())
|
||||||
@ -71,9 +81,9 @@ bool CursorImpl::loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vecto
|
|||||||
bool CursorImpl::loadFromPixelsARGB(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot)
|
bool CursorImpl::loadFromPixelsARGB(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot)
|
||||||
{
|
{
|
||||||
// Create cursor image, convert from RGBA to ARGB.
|
// Create cursor image, convert from RGBA to ARGB.
|
||||||
XcursorImage* cursorImage = XcursorImageCreate(static_cast<int>(size.x), static_cast<int>(size.y));
|
auto cursorImage = X11Ptr<XcursorImage>(XcursorImageCreate(static_cast<int>(size.x), static_cast<int>(size.y)));
|
||||||
cursorImage->xhot = hotspot.x;
|
cursorImage->xhot = hotspot.x;
|
||||||
cursorImage->yhot = hotspot.y;
|
cursorImage->yhot = hotspot.y;
|
||||||
|
|
||||||
const std::size_t numPixels = static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y);
|
const std::size_t numPixels = static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y);
|
||||||
for (std::size_t pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex)
|
for (std::size_t pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex)
|
||||||
@ -84,10 +94,7 @@ bool CursorImpl::loadFromPixelsARGB(const std::uint8_t* pixels, Vector2u size, V
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the cursor.
|
// Create the cursor.
|
||||||
m_cursor = XcursorImageLoadCursor(m_display, cursorImage);
|
m_cursor = XcursorImageLoadCursor(m_display, cursorImage.get());
|
||||||
|
|
||||||
// Free the resources
|
|
||||||
XcursorImageDestroy(cursorImage);
|
|
||||||
|
|
||||||
// We assume everything went fine...
|
// We assume everything went fine...
|
||||||
return true;
|
return true;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
#include <SFML/Window/Unix/GlxContext.hpp>
|
#include <SFML/Window/Unix/GlxContext.hpp>
|
||||||
|
#include <SFML/Window/Unix/Utils.hpp>
|
||||||
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
||||||
|
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
@ -314,14 +315,14 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
|
|||||||
const int screen = DefaultScreen(display);
|
const int screen = DefaultScreen(display);
|
||||||
|
|
||||||
// Retrieve all the visuals
|
// Retrieve all the visuals
|
||||||
int count;
|
int count;
|
||||||
XVisualInfo* visuals = XGetVisualInfo(display, 0, nullptr, &count);
|
auto visuals = X11Ptr<XVisualInfo[]>(XGetVisualInfo(display, 0, nullptr, &count));
|
||||||
if (visuals)
|
if (visuals)
|
||||||
{
|
{
|
||||||
// Evaluate all the returned visuals, and pick the best one
|
// Evaluate all the returned visuals, and pick the best one
|
||||||
int bestScore = 0x7FFFFFFF;
|
int bestScore = 0x7FFFFFFF;
|
||||||
XVisualInfo bestVisual = XVisualInfo();
|
XVisualInfo bestVisual = XVisualInfo();
|
||||||
for (int i = 0; i < count; ++i)
|
for (std::size_t i = 0; i < static_cast<std::size_t>(count); ++i)
|
||||||
{
|
{
|
||||||
// Filter by screen
|
// Filter by screen
|
||||||
if (visuals[i].screen != screen)
|
if (visuals[i].screen != screen)
|
||||||
@ -392,9 +393,6 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the array of visuals
|
|
||||||
XFree(visuals);
|
|
||||||
|
|
||||||
return bestVisual;
|
return bestVisual;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -459,17 +457,15 @@ void GlxContext::updateSettingsFromWindow()
|
|||||||
|
|
||||||
// Get its visuals
|
// Get its visuals
|
||||||
XVisualInfo tpl;
|
XVisualInfo tpl;
|
||||||
tpl.screen = DefaultScreen(m_display);
|
tpl.screen = DefaultScreen(m_display);
|
||||||
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
||||||
int nbVisuals = 0;
|
int nbVisuals = 0;
|
||||||
XVisualInfo* visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
|
auto visualInfo = X11Ptr<XVisualInfo>(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals));
|
||||||
|
|
||||||
if (!visualInfo)
|
if (!visualInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updateSettingsFromVisualInfo(visualInfo);
|
updateSettingsFromVisualInfo(visualInfo.get());
|
||||||
|
|
||||||
XFree(visualInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -499,12 +495,13 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne
|
|||||||
// We don't supply attributes to match against, since
|
// We don't supply attributes to match against, since
|
||||||
// the visual we are matching against was already
|
// the visual we are matching against was already
|
||||||
// deemed suitable in selectBestVisual()
|
// deemed suitable in selectBestVisual()
|
||||||
int nbConfigs = 0;
|
int nbConfigs = 0;
|
||||||
GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs);
|
auto configs = X11Ptr<GLXFBConfig[]>(
|
||||||
|
glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs));
|
||||||
|
|
||||||
for (int i = 0; configs && (i < nbConfigs); ++i)
|
for (std::size_t i = 0; configs && (i < static_cast<std::size_t>(nbConfigs)); ++i)
|
||||||
{
|
{
|
||||||
XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]);
|
auto visual = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, configs[i]));
|
||||||
|
|
||||||
if (!visual)
|
if (!visual)
|
||||||
continue;
|
continue;
|
||||||
@ -512,11 +509,8 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne
|
|||||||
if (visual->visualid == visualInfo.visualid)
|
if (visual->visualid == visualInfo.visualid)
|
||||||
{
|
{
|
||||||
config = &configs[i];
|
config = &configs[i];
|
||||||
XFree(visual);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(visual);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config)
|
if (config)
|
||||||
@ -528,13 +522,8 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne
|
|||||||
|
|
||||||
updateSettingsFromVisualInfo(&visualInfo);
|
updateSettingsFromVisualInfo(&visualInfo);
|
||||||
|
|
||||||
XFree(configs);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configs)
|
|
||||||
XFree(configs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,7 +572,7 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
// Get a working copy of the context settings
|
// Get a working copy of the context settings
|
||||||
const ContextSettings settings = m_settings;
|
const ContextSettings settings = m_settings;
|
||||||
|
|
||||||
XVisualInfo* visualInfo = nullptr;
|
X11Ptr<XVisualInfo> visualInfo;
|
||||||
|
|
||||||
if (m_pbuffer)
|
if (m_pbuffer)
|
||||||
{
|
{
|
||||||
@ -593,14 +582,11 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
|
|
||||||
int attributes[] = {GLX_FBCONFIG_ID, static_cast<int>(fbConfigId), 0, 0};
|
int attributes[] = {GLX_FBCONFIG_ID, static_cast<int>(fbConfigId), 0, 0};
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
GLXFBConfig* fbconfig = glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count);
|
auto fbconfig = X11Ptr<GLXFBConfig>(glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count));
|
||||||
|
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
visualInfo = glXGetVisualFromFBConfig(m_display, *fbconfig);
|
visualInfo = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, *fbconfig));
|
||||||
|
|
||||||
if (fbconfig)
|
|
||||||
XFree(fbconfig);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -617,7 +603,7 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
tpl.screen = DefaultScreen(m_display);
|
tpl.screen = DefaultScreen(m_display);
|
||||||
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
|
||||||
int nbVisuals = 0;
|
int nbVisuals = 0;
|
||||||
visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
|
visualInfo = X11Ptr<XVisualInfo>(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!visualInfo)
|
if (!visualInfo)
|
||||||
@ -648,12 +634,12 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
// We don't supply attributes to match against, since
|
// We don't supply attributes to match against, since
|
||||||
// the visual we are matching against was already
|
// the visual we are matching against was already
|
||||||
// deemed suitable in selectBestVisual()
|
// deemed suitable in selectBestVisual()
|
||||||
int nbConfigs = 0;
|
int nbConfigs = 0;
|
||||||
GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs);
|
auto configs = X11Ptr<GLXFBConfig[]>(glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs));
|
||||||
|
|
||||||
for (int i = 0; configs && (i < nbConfigs); ++i)
|
for (std::size_t i = 0; configs && (i < static_cast<std::size_t>(nbConfigs)); ++i)
|
||||||
{
|
{
|
||||||
XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]);
|
auto visual = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, configs[i]));
|
||||||
|
|
||||||
if (!visual)
|
if (!visual)
|
||||||
continue;
|
continue;
|
||||||
@ -661,11 +647,8 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
if (visual->visualid == visualInfo->visualid)
|
if (visual->visualid == visualInfo->visualid)
|
||||||
{
|
{
|
||||||
config = &configs[i];
|
config = &configs[i];
|
||||||
XFree(visual);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree(visual);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config)
|
if (!config)
|
||||||
@ -753,9 +736,6 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configs)
|
|
||||||
XFree(configs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If glXCreateContextAttribsARB failed, use glXCreateContext
|
// If glXCreateContextAttribsARB failed, use glXCreateContext
|
||||||
@ -780,7 +760,7 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the context, using the target window's visual
|
// Create the context, using the target window's visual
|
||||||
m_context = glXCreateContext(m_display, visualInfo, toShare, true);
|
m_context = glXCreateContext(m_display, visualInfo.get(), toShare, true);
|
||||||
|
|
||||||
#if defined(GLX_DEBUGGING)
|
#if defined(GLX_DEBUGGING)
|
||||||
if (glxErrorOccurred)
|
if (glxErrorOccurred)
|
||||||
@ -790,9 +770,6 @@ void GlxContext::createContext(GlxContext* shared)
|
|||||||
|
|
||||||
if (!m_context)
|
if (!m_context)
|
||||||
err() << "Failed to create an OpenGL context for this window" << std::endl;
|
err() << "Failed to create an OpenGL context for this window" << std::endl;
|
||||||
|
|
||||||
// Free the visual info
|
|
||||||
XFree(visualInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
61
src/SFML/Window/Unix/Utils.hpp
Normal file
61
src/SFML/Window/Unix/Utils.hpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2023 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 <X11/Xlib.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf::priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Class template for freeing X11 pointers
|
||||||
|
///
|
||||||
|
/// Specialized elsewhere for types that are freed through
|
||||||
|
/// other means than XFree(). XFree() is the most common use
|
||||||
|
/// case though so it is the default.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
struct XDeleter
|
||||||
|
{
|
||||||
|
void operator()(T* data) const
|
||||||
|
{
|
||||||
|
XFree(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Class template for wrapping owning raw pointers from X11
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
using X11Ptr = std::unique_ptr<T, XDeleter<std::remove_all_extents_t<T>>>;
|
||||||
|
} // namespace sf::priv
|
@ -26,6 +26,7 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
|
#include <SFML/Window/Unix/Utils.hpp>
|
||||||
#include <SFML/Window/VideoModeImpl.hpp>
|
#include <SFML/Window/VideoModeImpl.hpp>
|
||||||
|
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
@ -39,6 +40,17 @@
|
|||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XRRScreenConfiguration>
|
||||||
|
{
|
||||||
|
void operator()(XRRScreenConfiguration* config) const
|
||||||
|
{
|
||||||
|
XRRFreeScreenConfigInfo(config);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
||||||
{
|
{
|
||||||
@ -56,21 +68,21 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
if (XQueryExtension(display, "RANDR", &version, &version, &version))
|
if (XQueryExtension(display, "RANDR", &version, &version, &version))
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
|
auto config = X11Ptr<XRRScreenConfiguration>(XRRGetScreenInfo(display, RootWindow(display, screen)));
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
int nbSizes;
|
int nbSizes;
|
||||||
XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes);
|
XRRScreenSize* sizes = XRRConfigSizes(config.get(), &nbSizes);
|
||||||
if (sizes && (nbSizes > 0))
|
if (sizes && (nbSizes > 0))
|
||||||
{
|
{
|
||||||
// Get the list of supported depths
|
// Get the list of supported depths
|
||||||
int nbDepths = 0;
|
int nbDepths = 0;
|
||||||
int* depths = XListDepths(display, screen, &nbDepths);
|
auto depths = X11Ptr<int[]>(XListDepths(display, screen, &nbDepths));
|
||||||
if (depths && (nbDepths > 0))
|
if (depths && (nbDepths > 0))
|
||||||
{
|
{
|
||||||
// Combine depths and sizes to fill the array of supported modes
|
// Combine depths and sizes to fill the array of supported modes
|
||||||
for (int i = 0; i < nbDepths; ++i)
|
for (std::size_t i = 0; i < static_cast<std::size_t>(nbDepths); ++i)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < nbSizes; ++j)
|
for (int j = 0; j < nbSizes; ++j)
|
||||||
{
|
{
|
||||||
@ -80,7 +92,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
static_cast<unsigned int>(depths[i]));
|
static_cast<unsigned int>(depths[i]));
|
||||||
|
|
||||||
Rotation currentRotation;
|
Rotation currentRotation;
|
||||||
XRRConfigRotations(config, ¤tRotation);
|
XRRConfigRotations(config.get(), ¤tRotation);
|
||||||
|
|
||||||
if (currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
|
if (currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
|
||||||
std::swap(mode.size.x, mode.size.y);
|
std::swap(mode.size.x, mode.size.y);
|
||||||
@ -90,14 +102,8 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
modes.push_back(mode);
|
modes.push_back(mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the array of depths
|
|
||||||
XFree(depths);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
XRRFreeScreenConfigInfo(config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -142,16 +148,16 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
if (XQueryExtension(display, "RANDR", &version, &version, &version))
|
if (XQueryExtension(display, "RANDR", &version, &version, &version))
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
|
auto config = X11Ptr<XRRScreenConfiguration>(XRRGetScreenInfo(display, RootWindow(display, screen)));
|
||||||
if (config)
|
if (config)
|
||||||
{
|
{
|
||||||
// Get the current video mode
|
// Get the current video mode
|
||||||
Rotation currentRotation;
|
Rotation currentRotation;
|
||||||
const int currentMode = XRRConfigCurrentConfiguration(config, ¤tRotation);
|
const int currentMode = XRRConfigCurrentConfiguration(config.get(), ¤tRotation);
|
||||||
|
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
int nbSizes;
|
int nbSizes;
|
||||||
XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes);
|
XRRScreenSize* sizes = XRRConfigSizes(config.get(), &nbSizes);
|
||||||
if (sizes && (nbSizes > 0))
|
if (sizes && (nbSizes > 0))
|
||||||
{
|
{
|
||||||
desktopMode = VideoMode({static_cast<unsigned int>(sizes[currentMode].width),
|
desktopMode = VideoMode({static_cast<unsigned int>(sizes[currentMode].width),
|
||||||
@ -159,14 +165,11 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
static_cast<unsigned int>(DefaultDepth(display, screen)));
|
static_cast<unsigned int>(DefaultDepth(display, screen)));
|
||||||
|
|
||||||
Rotation modeRotation;
|
Rotation modeRotation;
|
||||||
XRRConfigRotations(config, &modeRotation);
|
XRRConfigRotations(config.get(), &modeRotation);
|
||||||
|
|
||||||
if (modeRotation == RR_Rotate_90 || modeRotation == RR_Rotate_270)
|
if (modeRotation == RR_Rotate_90 || modeRotation == RR_Rotate_270)
|
||||||
std::swap(desktopMode.size.x, desktopMode.size.y);
|
std::swap(desktopMode.size.x, desktopMode.size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
XRRFreeScreenConfigInfo(config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
#include <SFML/Window/Unix/InputImpl.hpp>
|
#include <SFML/Window/Unix/InputImpl.hpp>
|
||||||
#include <SFML/Window/Unix/KeyboardImpl.hpp>
|
#include <SFML/Window/Unix/KeyboardImpl.hpp>
|
||||||
|
#include <SFML/Window/Unix/Utils.hpp>
|
||||||
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
||||||
|
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
@ -374,6 +375,50 @@ bool isWMAbsolutePositionGood()
|
|||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XImage>
|
||||||
|
{
|
||||||
|
void operator()(XImage* image) const
|
||||||
|
{
|
||||||
|
XDestroyImage(image);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XRRScreenResources>
|
||||||
|
{
|
||||||
|
void operator()(XRRScreenResources* res) const
|
||||||
|
{
|
||||||
|
XRRFreeScreenResources(res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XRROutputInfo>
|
||||||
|
{
|
||||||
|
void operator()(XRROutputInfo* outputInfo) const
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(outputInfo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <>
|
||||||
|
struct XDeleter<XRRCrtcInfo>
|
||||||
|
{
|
||||||
|
void operator()(XRRCrtcInfo* crtcInfo) const
|
||||||
|
{
|
||||||
|
XRRFreeCrtcInfo(crtcInfo);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11::WindowImplX11(WindowHandle handle) : m_isExternal(true)
|
WindowImplX11::WindowImplX11(WindowHandle handle) : m_isExternal(true)
|
||||||
{
|
{
|
||||||
@ -486,11 +531,10 @@ m_cursorGrabbed(m_fullscreen)
|
|||||||
setProtocols();
|
setProtocols();
|
||||||
|
|
||||||
// Set the WM initial state to the normal state
|
// Set the WM initial state to the normal state
|
||||||
XWMHints* xHints = XAllocWMHints();
|
XWMHints xHints{};
|
||||||
xHints->flags = StateHint;
|
xHints.flags = StateHint;
|
||||||
xHints->initial_state = NormalState;
|
xHints.initial_state = NormalState;
|
||||||
XSetWMHints(m_display, m_window, xHints);
|
XSetWMHints(m_display, m_window, &xHints);
|
||||||
XFree(xHints);
|
|
||||||
|
|
||||||
// If not in fullscreen, set the window's style (tell the window manager to
|
// If not in fullscreen, set the window's style (tell the window manager to
|
||||||
// change our window's decorations and functions according to the requested style)
|
// change our window's decorations and functions according to the requested style)
|
||||||
@ -565,19 +609,18 @@ m_cursorGrabbed(m_fullscreen)
|
|||||||
// This is a hack to force some windows managers to disable resizing
|
// This is a hack to force some windows managers to disable resizing
|
||||||
if (!(style & Style::Resize))
|
if (!(style & Style::Resize))
|
||||||
{
|
{
|
||||||
m_useSizeHints = true;
|
m_useSizeHints = true;
|
||||||
XSizeHints* sizeHints = XAllocSizeHints();
|
XSizeHints sizeHints{};
|
||||||
sizeHints->flags = PMinSize | PMaxSize | USPosition;
|
sizeHints.flags = PMinSize | PMaxSize | USPosition;
|
||||||
sizeHints->min_width = sizeHints->max_width = static_cast<int>(width);
|
sizeHints.min_width = sizeHints.max_width = static_cast<int>(width);
|
||||||
sizeHints->min_height = sizeHints->max_height = static_cast<int>(height);
|
sizeHints.min_height = sizeHints.max_height = static_cast<int>(height);
|
||||||
sizeHints->x = windowPosition.x;
|
sizeHints.x = windowPosition.x;
|
||||||
sizeHints->y = windowPosition.y;
|
sizeHints.y = windowPosition.y;
|
||||||
XSetWMNormalHints(m_display, m_window, sizeHints);
|
XSetWMNormalHints(m_display, m_window, &sizeHints);
|
||||||
XFree(sizeHints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the window's WM class (this can be used by window managers)
|
// Set the window's WM class (this can be used by window managers)
|
||||||
XClassHint* hint = XAllocClassHint();
|
XClassHint hint{};
|
||||||
|
|
||||||
// The instance name should be something unique to this invocation
|
// The instance name should be something unique to this invocation
|
||||||
// of the application but is rarely if ever used these days.
|
// of the application but is rarely if ever used these days.
|
||||||
@ -585,7 +628,7 @@ m_cursorGrabbed(m_fullscreen)
|
|||||||
std::string executableName = findExecutableName().string();
|
std::string executableName = findExecutableName().string();
|
||||||
std::vector<char> windowInstance(executableName.size() + 1, 0);
|
std::vector<char> windowInstance(executableName.size() + 1, 0);
|
||||||
std::copy(executableName.begin(), executableName.end(), windowInstance.begin());
|
std::copy(executableName.begin(), executableName.end(), windowInstance.begin());
|
||||||
hint->res_name = windowInstance.data();
|
hint.res_name = windowInstance.data();
|
||||||
|
|
||||||
// The class name identifies a class of windows that
|
// The class name identifies a class of windows that
|
||||||
// "are of the same type". We simply use the initial window name as
|
// "are of the same type". We simply use the initial window name as
|
||||||
@ -593,11 +636,9 @@ m_cursorGrabbed(m_fullscreen)
|
|||||||
std::string ansiTitle = title.toAnsiString();
|
std::string ansiTitle = title.toAnsiString();
|
||||||
std::vector<char> windowClass(ansiTitle.size() + 1, 0);
|
std::vector<char> windowClass(ansiTitle.size() + 1, 0);
|
||||||
std::copy(ansiTitle.begin(), ansiTitle.end(), windowClass.begin());
|
std::copy(ansiTitle.begin(), ansiTitle.end(), windowClass.begin());
|
||||||
hint->res_class = windowClass.data();
|
hint.res_class = windowClass.data();
|
||||||
|
|
||||||
XSetClassHint(m_display, m_window, hint);
|
XSetClassHint(m_display, m_window, &hint);
|
||||||
|
|
||||||
XFree(hint);
|
|
||||||
|
|
||||||
// Set the window's name
|
// Set the window's name
|
||||||
setTitle(title);
|
setTitle(title);
|
||||||
@ -610,12 +651,11 @@ m_cursorGrabbed(m_fullscreen)
|
|||||||
{
|
{
|
||||||
// Disable hint for min and max size,
|
// Disable hint for min and max size,
|
||||||
// otherwise some windows managers will not remove window decorations
|
// otherwise some windows managers will not remove window decorations
|
||||||
XSizeHints* sizeHints = XAllocSizeHints();
|
XSizeHints sizeHints{};
|
||||||
long flags = 0;
|
long flags = 0;
|
||||||
XGetWMNormalHints(m_display, m_window, sizeHints, &flags);
|
XGetWMNormalHints(m_display, m_window, &sizeHints, &flags);
|
||||||
sizeHints->flags &= ~(PMinSize | PMaxSize);
|
sizeHints.flags &= ~(PMinSize | PMaxSize);
|
||||||
XSetWMNormalHints(m_display, m_window, sizeHints);
|
XSetWMNormalHints(m_display, m_window, &sizeHints);
|
||||||
XFree(sizeHints);
|
|
||||||
|
|
||||||
setVideoMode(mode);
|
setVideoMode(mode);
|
||||||
switchToFullscreen();
|
switchToFullscreen();
|
||||||
@ -841,12 +881,11 @@ void WindowImplX11::setSize(const Vector2u& size)
|
|||||||
// If resizing is disable for the window we have to update the size hints (required by some window managers).
|
// If resizing is disable for the window we have to update the size hints (required by some window managers).
|
||||||
if (m_useSizeHints)
|
if (m_useSizeHints)
|
||||||
{
|
{
|
||||||
XSizeHints* sizeHints = XAllocSizeHints();
|
XSizeHints sizeHints{};
|
||||||
sizeHints->flags = PMinSize | PMaxSize;
|
sizeHints.flags = PMinSize | PMaxSize;
|
||||||
sizeHints->min_width = sizeHints->max_width = static_cast<int>(size.x);
|
sizeHints.min_width = sizeHints.max_width = static_cast<int>(size.x);
|
||||||
sizeHints->min_height = sizeHints->max_height = static_cast<int>(size.y);
|
sizeHints.min_height = sizeHints.max_height = static_cast<int>(size.y);
|
||||||
XSetWMNormalHints(m_display, m_window, sizeHints);
|
XSetWMNormalHints(m_display, m_window, &sizeHints);
|
||||||
XFree(sizeHints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XResizeWindow(m_display, m_window, size.x, size.y);
|
XResizeWindow(m_display, m_window, size.x, size.y);
|
||||||
@ -925,7 +964,7 @@ void WindowImplX11::setTitle(const String& title)
|
|||||||
void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels)
|
void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels)
|
||||||
{
|
{
|
||||||
// X11 wants BGRA pixels: swap red and blue channels
|
// X11 wants BGRA pixels: swap red and blue channels
|
||||||
// Note: this memory will be freed by XDestroyImage
|
// Note: this memory will be freed by X11Ptr<XImage> deleter
|
||||||
auto* iconPixels = static_cast<std::uint8_t*>(
|
auto* iconPixels = static_cast<std::uint8_t*>(
|
||||||
std::malloc(static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y) * 4));
|
std::malloc(static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y) * 4));
|
||||||
for (std::size_t i = 0; i < static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y); ++i)
|
for (std::size_t i = 0; i < static_cast<std::size_t>(size.x) * static_cast<std::size_t>(size.y); ++i)
|
||||||
@ -939,16 +978,8 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels)
|
|||||||
// Create the icon pixmap
|
// Create the icon pixmap
|
||||||
Visual* defVisual = DefaultVisual(m_display, m_screen);
|
Visual* defVisual = DefaultVisual(m_display, m_screen);
|
||||||
auto defDepth = static_cast<unsigned int>(DefaultDepth(m_display, m_screen));
|
auto defDepth = static_cast<unsigned int>(DefaultDepth(m_display, m_screen));
|
||||||
XImage* iconImage = XCreateImage(m_display,
|
auto iconImage = X11Ptr<XImage>(
|
||||||
defVisual,
|
XCreateImage(m_display, defVisual, defDepth, ZPixmap, 0, reinterpret_cast<char*>(iconPixels), size.x, size.y, 32, 0));
|
||||||
defDepth,
|
|
||||||
ZPixmap,
|
|
||||||
0,
|
|
||||||
reinterpret_cast<char*>(iconPixels),
|
|
||||||
size.x,
|
|
||||||
size.y,
|
|
||||||
32,
|
|
||||||
0);
|
|
||||||
if (!iconImage)
|
if (!iconImage)
|
||||||
{
|
{
|
||||||
err() << "Failed to set the window's icon" << std::endl;
|
err() << "Failed to set the window's icon" << std::endl;
|
||||||
@ -964,9 +995,8 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels)
|
|||||||
m_iconPixmap = XCreatePixmap(m_display, RootWindow(m_display, m_screen), size.x, size.y, defDepth);
|
m_iconPixmap = XCreatePixmap(m_display, RootWindow(m_display, m_screen), size.x, size.y, defDepth);
|
||||||
XGCValues values;
|
XGCValues values;
|
||||||
GC iconGC = XCreateGC(m_display, m_iconPixmap, 0, &values);
|
GC iconGC = XCreateGC(m_display, m_iconPixmap, 0, &values);
|
||||||
XPutImage(m_display, m_iconPixmap, iconGC, iconImage, 0, 0, 0, 0, size.x, size.y);
|
XPutImage(m_display, m_iconPixmap, iconGC, iconImage.get(), 0, 0, 0, 0, size.x, size.y);
|
||||||
XFreeGC(m_display, iconGC);
|
XFreeGC(m_display, iconGC);
|
||||||
XDestroyImage(iconImage);
|
|
||||||
|
|
||||||
// Create the mask pixmap (must have 1 bit depth)
|
// Create the mask pixmap (must have 1 bit depth)
|
||||||
const std::size_t pitch = (size.x + 7) / 8;
|
const std::size_t pitch = (size.x + 7) / 8;
|
||||||
@ -995,12 +1025,11 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels)
|
|||||||
1);
|
1);
|
||||||
|
|
||||||
// Send our new icon to the window through the WMHints
|
// Send our new icon to the window through the WMHints
|
||||||
XWMHints* hints = XAllocWMHints();
|
XWMHints hints{};
|
||||||
hints->flags = IconPixmapHint | IconMaskHint;
|
hints.flags = IconPixmapHint | IconMaskHint;
|
||||||
hints->icon_pixmap = m_iconPixmap;
|
hints.icon_pixmap = m_iconPixmap;
|
||||||
hints->icon_mask = m_iconMaskPixmap;
|
hints.icon_mask = m_iconMaskPixmap;
|
||||||
XSetWMHints(m_display, m_window, hints);
|
XSetWMHints(m_display, m_window, &hints);
|
||||||
XFree(hints);
|
|
||||||
|
|
||||||
// ICCCM wants BGRA pixels: swap red and blue channels
|
// ICCCM wants BGRA pixels: swap red and blue channels
|
||||||
// ICCCM also wants the first 2 unsigned 32-bit values to be width and height
|
// ICCCM also wants the first 2 unsigned 32-bit values to be width and height
|
||||||
@ -1170,14 +1199,13 @@ void WindowImplX11::requestFocus()
|
|||||||
{
|
{
|
||||||
// Otherwise: display urgency hint (flashing application logo)
|
// Otherwise: display urgency hint (flashing application logo)
|
||||||
// Ensure WM hints exist, allocate if necessary
|
// Ensure WM hints exist, allocate if necessary
|
||||||
XWMHints* hints = XGetWMHints(m_display, m_window);
|
auto hints = X11Ptr<XWMHints>(XGetWMHints(m_display, m_window));
|
||||||
if (hints == nullptr)
|
if (hints == nullptr)
|
||||||
hints = XAllocWMHints();
|
hints.reset(XAllocWMHints());
|
||||||
|
|
||||||
// Add urgency (notification) flag to hints
|
// Add urgency (notification) flag to hints
|
||||||
hints->flags |= XUrgencyHint;
|
hints->flags |= XUrgencyHint;
|
||||||
XSetWMHints(m_display, m_window, hints);
|
XSetWMHints(m_display, m_window, hints.get());
|
||||||
XFree(hints);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1265,35 +1293,27 @@ void WindowImplX11::setVideoMode(const VideoMode& mode)
|
|||||||
::Window rootWindow = RootWindow(m_display, m_screen);
|
::Window rootWindow = RootWindow(m_display, m_screen);
|
||||||
|
|
||||||
// Get the screen resources
|
// Get the screen resources
|
||||||
XRRScreenResources* res = XRRGetScreenResources(m_display, rootWindow);
|
auto res = X11Ptr<XRRScreenResources>(XRRGetScreenResources(m_display, rootWindow));
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
err() << "Failed to get the current screen resources 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RROutput output = getOutputPrimary(rootWindow, res, xRandRMajor, xRandRMinor);
|
RROutput output = getOutputPrimary(rootWindow, res.get(), xRandRMajor, xRandRMinor);
|
||||||
|
|
||||||
// Get output info from output
|
// Get output info from output
|
||||||
XRROutputInfo* outputInfo = XRRGetOutputInfo(m_display, res, output);
|
auto outputInfo = X11Ptr<XRROutputInfo>(XRRGetOutputInfo(m_display, res.get(), output));
|
||||||
if (!outputInfo || outputInfo->connection == RR_Disconnected)
|
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;
|
err() << "Failed to get output info for fullscreen mode, switching to window mode" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve current RRMode, screen position and rotation
|
// Retrieve current RRMode, screen position and rotation
|
||||||
XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, outputInfo->crtc);
|
auto crtcInfo = X11Ptr<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc));
|
||||||
if (!crtcInfo)
|
if (!crtcInfo)
|
||||||
{
|
{
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
XRRFreeOutputInfo(outputInfo);
|
|
||||||
err() << "Failed to get crtc info for fullscreen mode, switching to window mode" << std::endl;
|
err() << "Failed to get crtc info for fullscreen mode, switching to window mode" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1317,8 +1337,6 @@ void WindowImplX11::setVideoMode(const VideoMode& mode)
|
|||||||
|
|
||||||
if (!modeFound)
|
if (!modeFound)
|
||||||
{
|
{
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
XRRFreeOutputInfo(outputInfo);
|
|
||||||
err() << "Failed to find a matching RRMode for fullscreen mode, switching to window mode" << std::endl;
|
err() << "Failed to find a matching RRMode for fullscreen mode, switching to window mode" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1328,14 +1346,19 @@ void WindowImplX11::setVideoMode(const VideoMode& mode)
|
|||||||
m_oldRRCrtc = outputInfo->crtc;
|
m_oldRRCrtc = outputInfo->crtc;
|
||||||
|
|
||||||
// Switch to fullscreen mode
|
// Switch to fullscreen mode
|
||||||
XRRSetCrtcConfig(m_display, res, outputInfo->crtc, CurrentTime, crtcInfo->x, crtcInfo->y, xRandMode, crtcInfo->rotation, &output, 1);
|
XRRSetCrtcConfig(m_display,
|
||||||
|
res.get(),
|
||||||
|
outputInfo->crtc,
|
||||||
|
CurrentTime,
|
||||||
|
crtcInfo->x,
|
||||||
|
crtcInfo->y,
|
||||||
|
xRandMode,
|
||||||
|
crtcInfo->rotation,
|
||||||
|
&output,
|
||||||
|
1);
|
||||||
|
|
||||||
// Set "this" as the current fullscreen window
|
// Set "this" as the current fullscreen window
|
||||||
fullscreenWindow = this;
|
fullscreenWindow = this;
|
||||||
|
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
XRRFreeOutputInfo(outputInfo);
|
|
||||||
XRRFreeCrtcInfo(crtcInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1352,7 +1375,7 @@ void WindowImplX11::resetVideoMode()
|
|||||||
int xRandRMinor;
|
int xRandRMinor;
|
||||||
if (checkXRandR(xRandRMajor, xRandRMinor))
|
if (checkXRandR(xRandRMajor, xRandRMinor))
|
||||||
{
|
{
|
||||||
XRRScreenResources* res = XRRGetScreenResources(m_display, DefaultRootWindow(m_display));
|
auto res = X11Ptr<XRRScreenResources>(XRRGetScreenResources(m_display, DefaultRootWindow(m_display)));
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
err() << "Failed to get the current screen resources to reset the video mode" << std::endl;
|
err() << "Failed to get the current screen resources to reset the video mode" << std::endl;
|
||||||
@ -1360,10 +1383,9 @@ void WindowImplX11::resetVideoMode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve current screen position and rotation
|
// Retrieve current screen position and rotation
|
||||||
XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, m_oldRRCrtc);
|
auto crtcInfo = X11Ptr<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), m_oldRRCrtc));
|
||||||
if (!crtcInfo)
|
if (!crtcInfo)
|
||||||
{
|
{
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
err() << "Failed to get crtc info to reset the video mode" << std::endl;
|
err() << "Failed to get crtc info to reset the video mode" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1385,7 +1407,7 @@ void WindowImplX11::resetVideoMode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
XRRSetCrtcConfig(m_display,
|
XRRSetCrtcConfig(m_display,
|
||||||
res,
|
res.get(),
|
||||||
m_oldRRCrtc,
|
m_oldRRCrtc,
|
||||||
CurrentTime,
|
CurrentTime,
|
||||||
crtcInfo->x,
|
crtcInfo->x,
|
||||||
@ -1394,9 +1416,6 @@ void WindowImplX11::resetVideoMode()
|
|||||||
crtcInfo->rotation,
|
crtcInfo->rotation,
|
||||||
&output,
|
&output,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
XRRFreeCrtcInfo(crtcInfo);
|
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the fullscreen window
|
// Reset the fullscreen window
|
||||||
@ -1695,13 +1714,12 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
|||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
|
||||||
// If the window has been previously marked urgent (notification) as a result of a focus request, undo that
|
// If the window has been previously marked urgent (notification) as a result of a focus request, undo that
|
||||||
XWMHints* hints = XGetWMHints(m_display, m_window);
|
auto hints = X11Ptr<XWMHints>(XGetWMHints(m_display, m_window));
|
||||||
if (hints != nullptr)
|
if (hints != nullptr)
|
||||||
{
|
{
|
||||||
// Remove urgency (notification) flag from hints
|
// Remove urgency (notification) flag from hints
|
||||||
hints->flags &= ~XUrgencyHint;
|
hints->flags &= ~XUrgencyHint;
|
||||||
XSetWMHints(m_display, m_window, hints);
|
XSetWMHints(m_display, m_window, hints.get());
|
||||||
XFree(hints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -2117,7 +2135,7 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition()
|
|||||||
::Window rootWindow = RootWindow(m_display, m_screen);
|
::Window rootWindow = RootWindow(m_display, m_screen);
|
||||||
|
|
||||||
// Get the screen resources
|
// Get the screen resources
|
||||||
XRRScreenResources* res = XRRGetScreenResources(m_display, rootWindow);
|
auto res = X11Ptr<XRRScreenResources>(XRRGetScreenResources(m_display, rootWindow));
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
err() << "Failed to get the current screen resources for primary monitor position" << std::endl;
|
err() << "Failed to get the current screen resources for primary monitor position" << std::endl;
|
||||||
@ -2130,28 +2148,20 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition()
|
|||||||
if (!checkXRandR(xRandRMajor, xRandRMinor))
|
if (!checkXRandR(xRandRMajor, xRandRMinor))
|
||||||
xRandRMajor = xRandRMinor = 0;
|
xRandRMajor = xRandRMinor = 0;
|
||||||
|
|
||||||
const RROutput output = getOutputPrimary(rootWindow, res, xRandRMajor, xRandRMinor);
|
const RROutput output = getOutputPrimary(rootWindow, res.get(), xRandRMajor, xRandRMinor);
|
||||||
|
|
||||||
// Get output info from output
|
// Get output info from output
|
||||||
XRROutputInfo* outputInfo = XRRGetOutputInfo(m_display, res, output);
|
auto outputInfo = X11Ptr<XRROutputInfo>(XRRGetOutputInfo(m_display, res.get(), output));
|
||||||
if (!outputInfo || outputInfo->connection == RR_Disconnected)
|
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;
|
err() << "Failed to get output info for primary monitor position" << std::endl;
|
||||||
return monitorPosition;
|
return monitorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve current RRMode, screen position and rotation
|
// Retrieve current RRMode, screen position and rotation
|
||||||
XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(m_display, res, outputInfo->crtc);
|
auto crtcInfo = X11Ptr<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc));
|
||||||
if (!crtcInfo)
|
if (!crtcInfo)
|
||||||
{
|
{
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
XRRFreeOutputInfo(outputInfo);
|
|
||||||
err() << "Failed to get crtc info for primary monitor position" << std::endl;
|
err() << "Failed to get crtc info for primary monitor position" << std::endl;
|
||||||
return monitorPosition;
|
return monitorPosition;
|
||||||
}
|
}
|
||||||
@ -2159,10 +2169,6 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition()
|
|||||||
monitorPosition.x = crtcInfo->x;
|
monitorPosition.x = crtcInfo->x;
|
||||||
monitorPosition.y = crtcInfo->y;
|
monitorPosition.y = crtcInfo->y;
|
||||||
|
|
||||||
XRRFreeCrtcInfo(crtcInfo);
|
|
||||||
XRRFreeOutputInfo(outputInfo);
|
|
||||||
XRRFreeScreenResources(res);
|
|
||||||
|
|
||||||
return monitorPosition;
|
return monitorPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user