diff --git a/src/SFML/Window/Unix/ClipboardImpl.cpp b/src/SFML/Window/Unix/ClipboardImpl.cpp index f40ef419f..a2ac47988 100644 --- a/src/SFML/Window/Unix/ClipboardImpl.cpp +++ b/src/SFML/Window/Unix/ClipboardImpl.cpp @@ -87,10 +87,10 @@ ClipboardImpl::ClipboardImpl() 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); + m_window = XCreateSimpleWindow(m_display.get(), DefaultRootWindow(m_display.get()), 0, 0, 1, 1, 0, 0, 0); // Register the events we are interested in - XSelectInput(m_display, m_window, SelectionNotify | SelectionClear | SelectionRequest); + XSelectInput(m_display.get(), m_window, SelectionNotify | SelectionClear | SelectionRequest); } @@ -100,12 +100,9 @@ ClipboardImpl::~ClipboardImpl() // Destroy the window if (m_window) { - XDestroyWindow(m_display, m_window); - XFlush(m_display); + XDestroyWindow(m_display.get(), m_window); + XFlush(m_display.get()); } - - // Close the connection with the X server - closeDisplay(m_display); } @@ -122,7 +119,7 @@ ClipboardImpl& ClipboardImpl::getInstance() String ClipboardImpl::getStringImpl() { // Check if anybody owns the current selection - if (XGetSelectionOwner(m_display, m_clipboard) == None) + if (XGetSelectionOwner(m_display.get(), m_clipboard) == None) { m_clipboardContents.clear(); @@ -136,7 +133,12 @@ String ClipboardImpl::getStringImpl() // 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); + XConvertSelection(m_display.get(), + m_clipboard, + (m_utf8String != None) ? m_utf8String : XA_STRING, + m_targetProperty, + m_window, + CurrentTime); const Clock clock; @@ -158,10 +160,10 @@ 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); + XSetSelectionOwner(m_display.get(), m_clipboard, m_window, CurrentTime); // Check if setting the selection owner was successful - if (XGetSelectionOwner(m_display, m_clipboard) != m_window) + if (XGetSelectionOwner(m_display.get(), m_clipboard) != m_window) err() << "Cannot set clipboard string: Unable to get ownership of X selection" << std::endl; } @@ -172,7 +174,7 @@ 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))) + while (XCheckIfEvent(m_display.get(), &event, &checkEvent, reinterpret_cast(m_window))) m_events.push_back(event); // Handle the events for this window that we just picked out @@ -222,7 +224,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // The selection owner should have wrote the selection // data to the specified window property - const int result = XGetWindowProperty(m_display, + const int result = XGetWindowProperty(m_display.get(), m_window, m_targetProperty, 0, @@ -257,7 +259,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) XFree(data); // The selection requestor must always delete the property themselves - XDeleteProperty(m_display, m_window, m_targetProperty); + XDeleteProperty(m_display.get(), m_window, m_targetProperty); } m_requestResponded = true; @@ -292,7 +294,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) if (m_utf8String != None) targets.push_back(m_utf8String); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), selectionRequestEvent.requestor, selectionRequestEvent.property, XA_ATOM, @@ -304,7 +306,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // Notify the requestor that they can read the targets from their window property selectionEvent.target = m_targets; - XSendEvent(m_display, + XSendEvent(m_display.get(), selectionRequestEvent.requestor, True, NoEventMask, @@ -318,7 +320,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // Respond to a request for conversion to a Latin-1 string const std::string data = m_clipboardContents.toAnsiString(); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), selectionRequestEvent.requestor, selectionRequestEvent.property, XA_STRING, @@ -330,7 +332,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // Notify the requestor that they can read the data from their window property selectionEvent.target = XA_STRING; - XSendEvent(m_display, + XSendEvent(m_display.get(), selectionRequestEvent.requestor, True, NoEventMask, @@ -345,7 +347,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // or an encoding of our choosing (we always choose UTF-8) const std::basic_string data = m_clipboardContents.toUtf8(); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), selectionRequestEvent.requestor, selectionRequestEvent.property, m_utf8String, @@ -357,7 +359,7 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) // Notify the requestor that they can read the data from their window property selectionEvent.target = m_utf8String; - XSendEvent(m_display, + XSendEvent(m_display.get(), selectionRequestEvent.requestor, True, NoEventMask, @@ -371,7 +373,11 @@ void ClipboardImpl::processEvent(XEvent& windowEvent) selectionEvent.target = selectionRequestEvent.target; selectionEvent.property = None; - XSendEvent(m_display, selectionRequestEvent.requestor, True, NoEventMask, reinterpret_cast(&selectionEvent)); + XSendEvent(m_display.get(), + selectionRequestEvent.requestor, + True, + NoEventMask, + reinterpret_cast(&selectionEvent)); break; } diff --git a/src/SFML/Window/Unix/ClipboardImpl.hpp b/src/SFML/Window/Unix/ClipboardImpl.hpp index c4be0e190..123ba59bf 100644 --- a/src/SFML/Window/Unix/ClipboardImpl.hpp +++ b/src/SFML/Window/Unix/ClipboardImpl.hpp @@ -34,6 +34,7 @@ #include #include +#include namespace sf::priv @@ -134,16 +135,16 @@ private: //////////////////////////////////////////////////////////// // 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 + ::Window m_window{}; ///< X identifier defining our window + std::shared_ptr<::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 sf::priv diff --git a/src/SFML/Window/Unix/CursorImpl.cpp b/src/SFML/Window/Unix/CursorImpl.cpp index 1d6b77967..462628d50 100644 --- a/src/SFML/Window/Unix/CursorImpl.cpp +++ b/src/SFML/Window/Unix/CursorImpl.cpp @@ -60,8 +60,6 @@ CursorImpl::CursorImpl() : m_display(openDisplay()) CursorImpl::~CursorImpl() { release(); - - closeDisplay(m_display); } @@ -94,7 +92,7 @@ bool CursorImpl::loadFromPixelsARGB(const std::uint8_t* pixels, Vector2u size, V } // Create the cursor. - m_cursor = XcursorImageLoadCursor(m_display, cursorImage.get()); + m_cursor = XcursorImageLoadCursor(m_display.get(), cursorImage.get()); // We assume everything went fine... return true; @@ -134,13 +132,13 @@ bool CursorImpl::loadFromPixelsMonochrome(const std::uint8_t* pixels, Vector2u s } } - const Pixmap maskPixmap = XCreateBitmapFromData(m_display, - XDefaultRootWindow(m_display), + const Pixmap maskPixmap = XCreateBitmapFromData(m_display.get(), + XDefaultRootWindow(m_display.get()), reinterpret_cast(mask.data()), size.x, size.y); - const Pixmap dataPixmap = XCreateBitmapFromData(m_display, - XDefaultRootWindow(m_display), + const Pixmap dataPixmap = XCreateBitmapFromData(m_display.get(), + XDefaultRootWindow(m_display.get()), reinterpret_cast(data.data()), size.x, size.y); @@ -156,11 +154,11 @@ bool CursorImpl::loadFromPixelsMonochrome(const std::uint8_t* pixels, Vector2u s bg.green = 0x0000; // Create the monochrome cursor. - m_cursor = XCreatePixmapCursor(m_display, dataPixmap, maskPixmap, &fg, &bg, hotspot.x, hotspot.y); + m_cursor = XCreatePixmapCursor(m_display.get(), dataPixmap, maskPixmap, &fg, &bg, hotspot.x, hotspot.y); // Free the resources - XFreePixmap(m_display, dataPixmap); - XFreePixmap(m_display, maskPixmap); + XFreePixmap(m_display.get(), dataPixmap); + XFreePixmap(m_display.get(), maskPixmap); // We assume everything went fine... return true; @@ -200,7 +198,7 @@ bool CursorImpl::loadFromSystem(Cursor::Type type) } // clang-format on - m_cursor = XCreateFontCursor(m_display, shape); + m_cursor = XCreateFontCursor(m_display.get(), shape); return true; } @@ -208,7 +206,7 @@ bool CursorImpl::loadFromSystem(Cursor::Type type) //////////////////////////////////////////////////////////// bool CursorImpl::isColorCursorSupported() { - return XcursorSupportsARGB(m_display); + return XcursorSupportsARGB(m_display.get()); } @@ -217,7 +215,7 @@ void CursorImpl::release() { if (m_cursor != None) { - XFreeCursor(m_display, m_cursor); + XFreeCursor(m_display.get(), m_cursor); m_cursor = None; } } diff --git a/src/SFML/Window/Unix/CursorImpl.hpp b/src/SFML/Window/Unix/CursorImpl.hpp index 3f11c0dcd..943611ee0 100644 --- a/src/SFML/Window/Unix/CursorImpl.hpp +++ b/src/SFML/Window/Unix/CursorImpl.hpp @@ -121,8 +121,8 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - ::Display* m_display; - ::Cursor m_cursor{None}; + std::shared_ptr<::Display> m_display; + ::Cursor m_cursor{None}; }; } // namespace sf::priv diff --git a/src/SFML/Window/Unix/Display.cpp b/src/SFML/Window/Unix/Display.cpp index 20fcefe49..0cc528926 100644 --- a/src/SFML/Window/Unix/Display.cpp +++ b/src/SFML/Window/Unix/Display.cpp @@ -42,27 +42,27 @@ namespace { -// The shared display and its reference counter -Display* sharedDisplay = nullptr; -unsigned int referenceCount = 0; -XIM sharedXIM = nullptr; -unsigned int referenceCountXIM = 0; -std::recursive_mutex mutex; - -using AtomMap = std::unordered_map; -AtomMap atoms; +// A nested named namespace is used here to allow unity builds of SFML. +namespace UnixDisplayImpl +{ +std::weak_ptr weakSharedDisplay; +std::recursive_mutex mutex; +} // namespace UnixDisplayImpl } // namespace + namespace sf::priv { //////////////////////////////////////////////////////////// -Display* openDisplay() +std::shared_ptr openDisplay() { - const std::lock_guard lock(mutex); + const std::lock_guard lock(UnixDisplayImpl::mutex); - if (referenceCount == 0) + auto sharedDisplay = UnixDisplayImpl::weakSharedDisplay.lock(); + if (!sharedDisplay) { - sharedDisplay = XOpenDisplay(nullptr); + sharedDisplay.reset(XOpenDisplay(nullptr), XCloseDisplay); + UnixDisplayImpl::weakSharedDisplay = sharedDisplay; // Opening display failed: The best we can do at the moment is to output a meaningful error message // and cause an abnormal program termination @@ -73,31 +73,22 @@ Display* openDisplay() } } - ++referenceCount; return sharedDisplay; } //////////////////////////////////////////////////////////// -void closeDisplay(Display* display) +std::shared_ptr<_XIM> openXim() { - const std::lock_guard lock(mutex); + const std::lock_guard lock(UnixDisplayImpl::mutex); - assert(display == sharedDisplay && "Display must match shared display"); + assert(!UnixDisplayImpl::weakSharedDisplay.expired() && + "Display is not initalized. Call priv::openDisplay() to initialize it."); - --referenceCount; - if (referenceCount == 0) - XCloseDisplay(display); -} + static std::weak_ptr<_XIM> xim; -//////////////////////////////////////////////////////////// -XIM openXim() -{ - const std::lock_guard lock(mutex); - - assert(sharedDisplay != nullptr && "Shared display is null. Call priv::openDisplay() to initialize it."); - - if (referenceCountXIM == 0) + auto sharedXIM = xim.lock(); + if (!sharedXIM) { // Create a new XIM instance @@ -113,7 +104,8 @@ XIM openXim() XSetLocaleModifiers(""); // Create the input context - sharedXIM = XOpenIM(sharedDisplay, nullptr, nullptr, nullptr); + sharedXIM.reset(XOpenIM(UnixDisplayImpl::weakSharedDisplay.lock().get(), nullptr, nullptr, nullptr), XCloseIM); + xim = sharedXIM; // Restore the previous locale if (prevLoc.length() != 0) @@ -123,37 +115,21 @@ XIM openXim() XSetLocaleModifiers(prevXLoc.c_str()); } - ++referenceCountXIM; - return sharedXIM; } -//////////////////////////////////////////////////////////// -void closeXim(XIM xim) -{ - const std::lock_guard lock(mutex); - - assert(xim == sharedXIM && "XIM must match shared XIM"); - - --referenceCountXIM; - - if ((referenceCountXIM == 0) && (xim != nullptr)) - XCloseIM(xim); -} //////////////////////////////////////////////////////////// Atom getAtom(const std::string& name, bool onlyIfExists) { + static std::unordered_map atoms; + if (auto it = atoms.find(name); it != atoms.end()) return it->second; - Display* display = openDisplay(); - - const Atom atom = XInternAtom(display, name.c_str(), onlyIfExists ? True : False); - - closeDisplay(display); - - atoms[name] = atom; + const auto display = openDisplay(); + const Atom atom = XInternAtom(display.get(), name.c_str(), onlyIfExists ? True : False); + atoms[name] = atom; return atom; } diff --git a/src/SFML/Window/Unix/Display.hpp b/src/SFML/Window/Unix/Display.hpp index 17b90b821..7f5347024 100644 --- a/src/SFML/Window/Unix/Display.hpp +++ b/src/SFML/Window/Unix/Display.hpp @@ -31,6 +31,7 @@ #include +#include #include @@ -39,42 +40,18 @@ namespace sf::priv //////////////////////////////////////////////////////////// /// \brief Get the shared Display /// -/// This function increments the reference count of the display, -/// it must be matched with a call to closeDisplay. -/// /// \return Pointer to the shared display /// //////////////////////////////////////////////////////////// -Display* openDisplay(); - -//////////////////////////////////////////////////////////// -/// \brief Release a reference to the shared display -/// -/// \param display Display to release -/// -//////////////////////////////////////////////////////////// -void closeDisplay(Display* display); +std::shared_ptr openDisplay(); //////////////////////////////////////////////////////////// /// \brief Get the shared XIM context for the Display /// -/// This function increments the reference count of the XIM context, -/// it must be matched with a call to CloseXIM. -/// -/// It must be called with a display already opened. -/// /// \return XIM handle (a pointer) of the context /// //////////////////////////////////////////////////////////// -XIM openXim(); - -//////////////////////////////////////////////////////////// -/// \brief Release a reference to the shared XIM context -/// -/// \param xim XIM context to release -/// -//////////////////////////////////////////////////////////// -void closeXim(XIM xim); +std::shared_ptr<_XIM> openXim(); //////////////////////////////////////////////////////////// /// \brief Get the atom with the specified name diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index 04e777038..7b922a455 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -115,7 +115,7 @@ GlxContext::GlxContext(GlxContext* shared) m_display = openDisplay(); // Make sure that extensions are initialized - ensureExtensionsInit(m_display, DefaultScreen(m_display)); + ensureExtensionsInit(m_display.get(), DefaultScreen(m_display.get())); // Create the rendering surface (window or pbuffer if supported) createSurface(shared, {1, 1}, VideoMode::getDesktopMode().bitsPerPixel); @@ -135,7 +135,7 @@ GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, cons m_display = openDisplay(); // Make sure that extensions are initialized - ensureExtensionsInit(m_display, DefaultScreen(m_display)); + ensureExtensionsInit(m_display.get(), DefaultScreen(m_display.get())); // Create the rendering surface from the owner window createSurface(owner.getNativeHandle()); @@ -155,7 +155,7 @@ GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, cons m_display = openDisplay(); // Make sure that extensions are initialized - ensureExtensionsInit(m_display, DefaultScreen(m_display)); + ensureExtensionsInit(m_display.get(), DefaultScreen(m_display.get())); // Create the rendering surface (window or pbuffer if supported) createSurface(shared, size, VideoMode::getDesktopMode().bitsPerPixel); @@ -175,12 +175,12 @@ GlxContext::~GlxContext() if (m_context) { #if defined(GLX_DEBUGGING) - GlxErrorHandler handler(m_display); + GlxErrorHandler handler(m_display.get()); #endif if (glXGetCurrentContext() == m_context) - glXMakeCurrent(m_display, None, nullptr); - glXDestroyContext(m_display, m_context); + glXMakeCurrent(m_display.get(), None, nullptr); + glXDestroyContext(m_display.get(), m_context); #if defined(GLX_DEBUGGING) if (glxErrorOccurred) @@ -190,18 +190,15 @@ GlxContext::~GlxContext() if (m_pbuffer) { - glXDestroyPbuffer(m_display, m_pbuffer); + glXDestroyPbuffer(m_display.get(), m_pbuffer); } // Destroy the window if we own it if (m_window && m_ownsWindow) { - XDestroyWindow(m_display, m_window); - XFlush(m_display); + XDestroyWindow(m_display.get(), m_window); + XFlush(m_display.get()); } - - // Close the connection with the X server - closeDisplay(m_display); } @@ -219,7 +216,7 @@ bool GlxContext::makeCurrent(bool current) return false; #if defined(GLX_DEBUGGING) - GlxErrorHandler handler(m_display); + GlxErrorHandler handler(m_display.get()); #endif bool result = false; @@ -228,16 +225,16 @@ bool GlxContext::makeCurrent(bool current) { if (m_pbuffer) { - result = glXMakeContextCurrent(m_display, m_pbuffer, m_pbuffer, m_context); + result = glXMakeContextCurrent(m_display.get(), m_pbuffer, m_pbuffer, m_context); } else if (m_window) { - result = glXMakeCurrent(m_display, m_window, m_context); + result = glXMakeCurrent(m_display.get(), m_window, m_context); } } else { - result = glXMakeCurrent(m_display, None, nullptr); + result = glXMakeCurrent(m_display.get(), None, nullptr); } #if defined(GLX_DEBUGGING) @@ -253,13 +250,13 @@ bool GlxContext::makeCurrent(bool current) void GlxContext::display() { #if defined(GLX_DEBUGGING) - GlxErrorHandler handler(m_display); + GlxErrorHandler handler(m_display.get()); #endif if (m_pbuffer) - glXSwapBuffers(m_display, m_pbuffer); + glXSwapBuffers(m_display.get(), m_pbuffer); else if (m_window) - glXSwapBuffers(m_display, m_window); + glXSwapBuffers(m_display.get(), m_window); #if defined(GLX_DEBUGGING) if (glxErrorOccurred) @@ -279,7 +276,7 @@ void GlxContext::setVerticalSyncEnabled(bool enabled) // which would require us to link in an additional library if (SF_GLAD_GLX_EXT_swap_control) { - glXSwapIntervalEXT(m_display, m_pbuffer ? m_pbuffer : m_window, enabled ? 1 : 0); + glXSwapIntervalEXT(m_display.get(), m_pbuffer ? m_pbuffer : m_window, enabled ? 1 : 0); } else if (SF_GLAD_GLX_MESA_swap_control) { @@ -414,13 +411,13 @@ void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo) int multiSampling; int samples; int sRgb; - glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth); - glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil); + glXGetConfig(m_display.get(), visualInfo, GLX_DEPTH_SIZE, &depth); + glXGetConfig(m_display.get(), visualInfo, GLX_STENCIL_SIZE, &stencil); if (SF_GLAD_GLX_ARB_multisample) { - glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling); - glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples); + glXGetConfig(m_display.get(), visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling); + glXGetConfig(m_display.get(), visualInfo, GLX_SAMPLES_ARB, &samples); } else { @@ -430,7 +427,7 @@ void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo) if (SF_GLAD_GLX_EXT_framebuffer_sRGB || SF_GLAD_GLX_ARB_framebuffer_sRGB) { - glXGetConfig(m_display, visualInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb); + glXGetConfig(m_display.get(), visualInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb); } else { @@ -449,7 +446,7 @@ void GlxContext::updateSettingsFromWindow() { // Retrieve the attributes of the target window XWindowAttributes windowAttributes; - if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0) + if (XGetWindowAttributes(m_display.get(), m_window, &windowAttributes) == 0) { err() << "Failed to get the window attributes" << std::endl; return; @@ -457,10 +454,11 @@ void GlxContext::updateSettingsFromWindow() // Get its visuals XVisualInfo tpl; - tpl.screen = DefaultScreen(m_display); + tpl.screen = DefaultScreen(m_display.get()); tpl.visualid = XVisualIDFromVisual(windowAttributes.visual); int nbVisuals = 0; - auto visualInfo = X11Ptr(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals)); + auto visualInfo = X11Ptr( + XGetVisualInfo(m_display.get(), VisualIDMask | VisualScreenMask, &tpl, &nbVisuals)); if (!visualInfo) return; @@ -473,7 +471,7 @@ void GlxContext::updateSettingsFromWindow() void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigned int bitsPerPixel) { // Choose the visual according to the context settings - XVisualInfo visualInfo = selectBestVisual(m_display, bitsPerPixel, m_settings); + XVisualInfo visualInfo = selectBestVisual(m_display.get(), bitsPerPixel, m_settings); // Check if the shared context already exists and pbuffers are supported if (shared && SF_GLAD_GLX_SGIX_pbuffer) @@ -482,7 +480,7 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne int major = 0; int minor = 0; - glXQueryVersion(m_display, &major, &minor); + glXQueryVersion(m_display.get(), &major, &minor); // Check if glXCreatePbuffer is available (requires GLX 1.3 or greater) const bool hasCreatePbuffer = ((major > 1) || (minor >= 3)); @@ -497,11 +495,11 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne // deemed suitable in selectBestVisual() int nbConfigs = 0; auto configs = X11Ptr( - glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs)); + glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs)); for (std::size_t i = 0; configs && (i < static_cast(nbConfigs)); ++i) { - auto visual = X11Ptr(glXGetVisualFromFBConfig(m_display, configs[i])); + auto visual = X11Ptr(glXGetVisualFromFBConfig(m_display.get(), configs[i])); if (!visual) continue; @@ -518,7 +516,7 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne int attributes[] = {GLX_PBUFFER_WIDTH, static_cast(size.x), GLX_PBUFFER_HEIGHT, static_cast(size.y), 0, 0}; - m_pbuffer = glXCreatePbuffer(m_display, *config, attributes); + m_pbuffer = glXCreatePbuffer(m_display.get(), *config, attributes); updateSettingsFromVisualInfo(&visualInfo); @@ -528,23 +526,23 @@ void GlxContext::createSurface(GlxContext* shared, const Vector2u& size, unsigne } // If pbuffers are not available we use a hidden window as the off-screen surface to draw to - const int screen = DefaultScreen(m_display); + const int screen = DefaultScreen(m_display.get()); // Define the window attributes XSetWindowAttributes attributes; - attributes.colormap = XCreateColormap(m_display, RootWindow(m_display, screen), visualInfo.visual, AllocNone); + attributes.colormap = XCreateColormap(m_display.get(), RootWindow(m_display.get(), screen), visualInfo.visual, AllocNone); // Note: bitsPerPixel is explicitly ignored. Instead, DefaultDepth() is used in order to avoid window creation failure due to // a depth not supported by the X window system. On Unix/Linux, the window's pixel format is not directly associated with the // rendering surface (unlike on Windows, for example). - m_window = XCreateWindow(m_display, - RootWindow(m_display, screen), + m_window = XCreateWindow(m_display.get(), + RootWindow(m_display.get(), screen), 0, 0, size.x, size.y, 0, - DefaultDepth(m_display, screen), + DefaultDepth(m_display.get(), screen), InputOutput, visualInfo.visual, CWColormap, @@ -578,21 +576,22 @@ void GlxContext::createContext(GlxContext* shared) { unsigned int fbConfigId = 0; - glXQueryDrawable(m_display, m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId); + glXQueryDrawable(m_display.get(), m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId); int attributes[] = {GLX_FBCONFIG_ID, static_cast(fbConfigId), 0, 0}; int count = 0; - auto fbconfig = X11Ptr(glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count)); + auto fbconfig = X11Ptr( + glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), attributes, &count)); if (count == 1) - visualInfo = X11Ptr(glXGetVisualFromFBConfig(m_display, *fbconfig)); + visualInfo = X11Ptr(glXGetVisualFromFBConfig(m_display.get(), *fbconfig)); } else { // Retrieve the attributes of the target window XWindowAttributes windowAttributes; - if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0) + if (XGetWindowAttributes(m_display.get(), m_window, &windowAttributes) == 0) { err() << "Failed to get the window attributes" << std::endl; return; @@ -600,10 +599,10 @@ void GlxContext::createContext(GlxContext* shared) // Get its visuals XVisualInfo tpl; - tpl.screen = DefaultScreen(m_display); + tpl.screen = DefaultScreen(m_display.get()); tpl.visualid = XVisualIDFromVisual(windowAttributes.visual); int nbVisuals = 0; - visualInfo = X11Ptr(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals)); + visualInfo = X11Ptr(XGetVisualInfo(m_display.get(), VisualIDMask | VisualScreenMask, &tpl, &nbVisuals)); } if (!visualInfo) @@ -619,7 +618,7 @@ void GlxContext::createContext(GlxContext* shared) int major = 0; int minor = 0; - if (!glXQueryVersion(m_display, &major, &minor)) + if (!glXQueryVersion(m_display.get(), &major, &minor)) err() << "Failed to query GLX version, limited to legacy context creation" << std::endl; // Check if glXCreateContextAttribsARB is available (requires GLX 1.3 or greater) @@ -634,12 +633,13 @@ void GlxContext::createContext(GlxContext* shared) // We don't supply attributes to match against, since // the visual we are matching against was already // deemed suitable in selectBestVisual() - int nbConfigs = 0; - auto configs = X11Ptr(glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs)); + int nbConfigs = 0; + auto configs = X11Ptr( + glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs)); for (std::size_t i = 0; configs && (i < static_cast(nbConfigs)); ++i) { - auto visual = X11Ptr(glXGetVisualFromFBConfig(m_display, configs[i])); + auto visual = X11Ptr(glXGetVisualFromFBConfig(m_display.get(), configs[i])); if (!visual) continue; @@ -696,11 +696,11 @@ void GlxContext::createContext(GlxContext* shared) // RAII GLX error handler (we simply ignore errors here) // On an error, glXCreateContextAttribsARB will return 0 anyway - const GlxErrorHandler handler(m_display); + const GlxErrorHandler handler(m_display.get()); if (toShare) { - if (!glXMakeCurrent(m_display, None, nullptr)) + if (!glXMakeCurrent(m_display.get(), None, nullptr)) { err() << "Failed to deactivate shared context before sharing" << std::endl; return; @@ -708,7 +708,7 @@ void GlxContext::createContext(GlxContext* shared) } // Create the context - m_context = glXCreateContextAttribsARB(m_display, *config, toShare, true, attributes.data()); + m_context = glXCreateContextAttribsARB(m_display.get(), *config, toShare, true, attributes.data()); if (!m_context) { @@ -747,12 +747,12 @@ void GlxContext::createContext(GlxContext* shared) m_settings.attributeFlags = ContextSettings::Default; #if defined(GLX_DEBUGGING) - GlxErrorHandler handler(m_display); + GlxErrorHandler handler(m_display.get()); #endif if (toShare) { - if (!glXMakeCurrent(m_display, None, nullptr)) + if (!glXMakeCurrent(m_display.get(), None, nullptr)) { err() << "Failed to deactivate shared context before sharing" << std::endl; return; @@ -760,7 +760,7 @@ void GlxContext::createContext(GlxContext* shared) } // Create the context, using the target window's visual - m_context = glXCreateContext(m_display, visualInfo.get(), toShare, true); + m_context = glXCreateContext(m_display.get(), visualInfo.get(), toShare, true); #if defined(GLX_DEBUGGING) if (glxErrorOccurred) diff --git a/src/SFML/Window/Unix/GlxContext.hpp b/src/SFML/Window/Unix/GlxContext.hpp index c00347b4c..cf6b6c62b 100644 --- a/src/SFML/Window/Unix/GlxContext.hpp +++ b/src/SFML/Window/Unix/GlxContext.hpp @@ -33,6 +33,8 @@ #include #include +#include + namespace sf::priv { @@ -173,11 +175,11 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - ::Display* m_display{}; ///< Connection to the X server - ::Window m_window{}; ///< Window to which the context is attached - GLXContext m_context{}; ///< OpenGL context - GLXPbuffer m_pbuffer{}; ///< GLX pbuffer ID if one was created - bool m_ownsWindow{}; ///< Do we own the window associated to the context? + std::shared_ptr m_display; ///< Connection to the X server + ::Window m_window{}; ///< Window to which the context is attached + GLXContext m_context{}; ///< OpenGL context + GLXPbuffer m_pbuffer{}; ///< GLX pbuffer ID if one was created + bool m_ownsWindow{}; ///< Do we own the window associated to the context? }; } // namespace sf::priv diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp index 529120ee0..dabe942de 100644 --- a/src/SFML/Window/Unix/InputImpl.cpp +++ b/src/SFML/Window/Unix/InputImpl.cpp @@ -85,7 +85,7 @@ void setVirtualKeyboardVisible(bool /*visible*/) bool isMouseButtonPressed(Mouse::Button button) { // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); // we don't care about these but they are required ::Window root; @@ -96,10 +96,7 @@ bool isMouseButtonPressed(Mouse::Button button) int gy; unsigned int buttons = 0; - XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &wx, &wy, &buttons); - - // Close the connection with the X server - closeDisplay(display); + XQueryPointer(display.get(), DefaultRootWindow(display.get()), &root, &child, &gx, &gy, &wx, &wy, &buttons); // Buttons 4 and 5 are the vertical wheel and 6 and 7 the horizontal wheel. // There is no mask for buttons 8 and 9, so checking the state of buttons @@ -122,7 +119,7 @@ bool isMouseButtonPressed(Mouse::Button button) Vector2i getMousePosition() { // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); // we don't care about these but they are required ::Window root; @@ -133,10 +130,7 @@ Vector2i getMousePosition() int gx = 0; int gy = 0; - XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &x, &y, &buttons); - - // Close the connection with the X server - closeDisplay(display); + XQueryPointer(display.get(), DefaultRootWindow(display.get()), &root, &child, &gx, &gy, &x, &y, &buttons); return {gx, gy}; } @@ -149,7 +143,7 @@ Vector2i getMousePosition(const WindowBase& relativeTo) if (handle) { // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); // we don't care about these but they are required ::Window root; @@ -160,10 +154,7 @@ Vector2i getMousePosition(const WindowBase& relativeTo) int x = 0; int y = 0; - XQueryPointer(display, handle, &root, &child, &gx, &gy, &x, &y, &buttons); - - // Close the connection with the X server - closeDisplay(display); + XQueryPointer(display.get(), handle, &root, &child, &gx, &gy, &x, &y, &buttons); return {x, y}; } @@ -178,13 +169,10 @@ Vector2i getMousePosition(const WindowBase& relativeTo) void setMousePosition(const Vector2i& position) { // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); - XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, position.x, position.y); - XFlush(display); - - // Close the connection with the X server - closeDisplay(display); + XWarpPointer(display.get(), None, DefaultRootWindow(display.get()), 0, 0, 0, 0, position.x, position.y); + XFlush(display.get()); } @@ -192,17 +180,14 @@ void setMousePosition(const Vector2i& position) void setMousePosition(const Vector2i& position, const WindowBase& relativeTo) { // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); const WindowHandle handle = relativeTo.getNativeHandle(); if (handle) { - XWarpPointer(display, None, handle, 0, 0, 0, 0, position.x, position.y); - XFlush(display); + XWarpPointer(display.get(), None, handle, 0, 0, 0, 0, position.x, position.y); + XFlush(display.get()); } - - // Close the connection with the X server - closeDisplay(display); } diff --git a/src/SFML/Window/Unix/KeyboardImpl.cpp b/src/SFML/Window/Unix/KeyboardImpl.cpp index ee0759bc6..83da3eeee 100644 --- a/src/SFML/Window/Unix/KeyboardImpl.cpp +++ b/src/SFML/Window/Unix/KeyboardImpl.cpp @@ -466,11 +466,11 @@ void ensureMapping() keycodeToScancode.fill(sf::Keyboard::Scan::Unknown); // Phase 2: Get XKB names with key code - Display* display = sf::priv::openDisplay(); + const auto display = sf::priv::openDisplay(); char name[XkbKeyNameLength + 1]; - XkbDescPtr descriptor = XkbGetMap(display, 0, XkbUseCoreKbd); - XkbGetNames(display, XkbKeyNamesMask, descriptor); + XkbDescPtr descriptor = XkbGetMap(display.get(), 0, XkbUseCoreKbd); + XkbGetNames(display.get(), XkbKeyNamesMask, descriptor); std::unordered_map nameScancodeMap = getNameScancodeMap(); sf::Keyboard::Scancode scancode = sf::Keyboard::Scan::Unknown; @@ -505,7 +505,7 @@ void ensureMapping() { if (keycodeToScancode[static_cast(keycode)] == sf::Keyboard::Scan::Unknown) { - scancode = translateKeyCode(display, static_cast(keycode)); + scancode = translateKeyCode(display.get(), static_cast(keycode)); if (scancode != sf::Keyboard::Scan::Unknown && scancodeToKeycode[scancode] == nullKeyCode) scancodeToKeycode[scancode] = static_cast(keycode); @@ -514,8 +514,6 @@ void ensureMapping() } } - sf::priv::closeDisplay(display); - isMappingInitialized = true; } @@ -551,9 +549,8 @@ KeyCode keyToKeyCode(sf::Keyboard::Key key) if (keysym != NoSymbol) { - Display* display = sf::priv::openDisplay(); - const KeyCode keycode = XKeysymToKeycode(display, keysym); - sf::priv::closeDisplay(display); + const auto display = sf::priv::openDisplay(); + const KeyCode keycode = XKeysymToKeycode(display.get(), keysym); if (keycode != nullKeyCode) return keycode; @@ -570,15 +567,13 @@ KeyCode keyToKeyCode(sf::Keyboard::Key key) //////////////////////////////////////////////////////////// KeySym scancodeToKeySym(sf::Keyboard::Scancode code) { - Display* display = sf::priv::openDisplay(); + const auto display = sf::priv::openDisplay(); KeySym keysym = NoSymbol; const KeyCode keycode = scancodeToKeyCode(code); if (keycode != nullKeyCode) // ensure that this Scancode is mapped to keycode - keysym = XkbKeycodeToKeysym(display, keycode, 0, 0); - - sf::priv::closeDisplay(display); + keysym = XkbKeycodeToKeysym(display.get(), keycode, 0, 0); return keysym; } @@ -589,13 +584,11 @@ bool isKeyPressedImpl(KeyCode keycode) { if (keycode != nullKeyCode) { - Display* display = sf::priv::openDisplay(); + const auto display = sf::priv::openDisplay(); // Get the whole keyboard state char keys[32]; - XQueryKeymap(display, keys); - - sf::priv::closeDisplay(display); + XQueryKeymap(display.get(), keys); // Check our keycode return (keys[keycode / 8] & (1 << (keycode % 8))) != 0; diff --git a/src/SFML/Window/Unix/VideoModeImpl.cpp b/src/SFML/Window/Unix/VideoModeImpl.cpp index 714fcfd45..7c021c9c8 100644 --- a/src/SFML/Window/Unix/VideoModeImpl.cpp +++ b/src/SFML/Window/Unix/VideoModeImpl.cpp @@ -57,18 +57,18 @@ std::vector VideoModeImpl::getFullscreenModes() std::vector modes; // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); if (display) { // Retrieve the default screen number - const int screen = DefaultScreen(display); + const int screen = DefaultScreen(display.get()); // Check if the XRandR extension is present int version; - if (XQueryExtension(display, "RANDR", &version, &version, &version)) + if (XQueryExtension(display.get(), "RANDR", &version, &version, &version)) { // Get the current configuration - auto config = X11Ptr(XRRGetScreenInfo(display, RootWindow(display, screen))); + auto config = X11Ptr(XRRGetScreenInfo(display.get(), RootWindow(display.get(), screen))); if (config) { // Get the available screen sizes @@ -78,7 +78,7 @@ std::vector VideoModeImpl::getFullscreenModes() { // Get the list of supported depths int nbDepths = 0; - auto depths = X11Ptr(XListDepths(display, screen, &nbDepths)); + auto depths = X11Ptr(XListDepths(display.get(), screen, &nbDepths)); if (depths && (nbDepths > 0)) { // Combine depths and sizes to fill the array of supported modes @@ -117,9 +117,6 @@ std::vector VideoModeImpl::getFullscreenModes() // XRandr extension is not supported: we cannot get the video modes err() << "Failed to use the XRandR extension while trying to get the supported video modes" << std::endl; } - - // Close the connection with the X server - closeDisplay(display); } else { @@ -137,18 +134,18 @@ VideoMode VideoModeImpl::getDesktopMode() VideoMode desktopMode; // Open a connection with the X server - Display* display = openDisplay(); + const auto display = openDisplay(); if (display) { // Retrieve the default screen number - const int screen = DefaultScreen(display); + const int screen = DefaultScreen(display.get()); // Check if the XRandR extension is present int version; - if (XQueryExtension(display, "RANDR", &version, &version, &version)) + if (XQueryExtension(display.get(), "RANDR", &version, &version, &version)) { // Get the current configuration - auto config = X11Ptr(XRRGetScreenInfo(display, RootWindow(display, screen))); + auto config = X11Ptr(XRRGetScreenInfo(display.get(), RootWindow(display.get(), screen))); if (config) { // Get the current video mode @@ -162,7 +159,7 @@ VideoMode VideoModeImpl::getDesktopMode() { desktopMode = VideoMode({static_cast(sizes[currentMode].width), static_cast(sizes[currentMode].height)}, - static_cast(DefaultDepth(display, screen))); + static_cast(DefaultDepth(display.get(), screen))); Rotation modeRotation; XRRConfigRotations(config.get(), &modeRotation); @@ -183,9 +180,6 @@ VideoMode VideoModeImpl::getDesktopMode() // XRandr extension is not supported: we cannot get the video modes err() << "Failed to use the XRandR extension while trying to get the desktop video modes" << std::endl; } - - // Close the connection with the X server - closeDisplay(display); } else { diff --git a/src/SFML/Window/Unix/VulkanImplX11.cpp b/src/SFML/Window/Unix/VulkanImplX11.cpp index b9f3168c8..8ee84ee28 100644 --- a/src/SFML/Window/Unix/VulkanImplX11.cpp +++ b/src/SFML/Window/Unix/VulkanImplX11.cpp @@ -198,15 +198,14 @@ bool VulkanImplX11::createVulkanSurface(const VkInstance& instance, // Since the surface is basically attached to the window, the connection // to the X display will stay open even after we open and close it here + const auto display = openDisplay(); VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = VkXlibSurfaceCreateInfoKHR(); surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.dpy = openDisplay(); + surfaceCreateInfo.dpy = display.get(); surfaceCreateInfo.window = windowHandle; const bool result = (vkCreateXlibSurfaceKHR(instance, &surfaceCreateInfo, allocator, &surface) == VK_SUCCESS); - closeDisplay(surfaceCreateInfo.dpy); - return result; } diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 4f4c89c22..16254dc0c 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -167,7 +167,7 @@ bool ewmhSupported() if (!netSupportingWmCheck || !netSupported) return false; - ::Display* display = sf::priv::openDisplay(); + const auto display = sf::priv::openDisplay(); Atom actualType; int actualFormat; @@ -175,8 +175,8 @@ bool ewmhSupported() unsigned long numBytes; unsigned char* data; - int result = XGetWindowProperty(display, - DefaultRootWindow(display), + int result = XGetWindowProperty(display.get(), + DefaultRootWindow(display.get()), netSupportingWmCheck, 0, 1, @@ -193,7 +193,6 @@ bool ewmhSupported() if (result == Success) XFree(data); - sf::priv::closeDisplay(display); return false; } @@ -206,11 +205,10 @@ bool ewmhSupported() if (!rootWindow) { - sf::priv::closeDisplay(display); return false; } - result = XGetWindowProperty(display, + result = XGetWindowProperty(display.get(), rootWindow, netSupportingWmCheck, 0, @@ -228,7 +226,6 @@ bool ewmhSupported() if (result == Success) XFree(data); - sf::priv::closeDisplay(display); return false; } @@ -240,17 +237,11 @@ bool ewmhSupported() XFree(data); if (!childWindow) - { - sf::priv::closeDisplay(display); return false; - } // Conforming window managers should return the same window for both queries if (rootWindow != childWindow) - { - sf::priv::closeDisplay(display); return false; - } ewmhSupported = true; @@ -259,17 +250,14 @@ bool ewmhSupported() const Atom netWmName = sf::priv::getAtom("_NET_WM_NAME", true); if (!netWmName) - { - sf::priv::closeDisplay(display); return true; - } Atom utf8StringType = sf::priv::getAtom("UTF8_STRING"); if (!utf8StringType) utf8StringType = XA_STRING; - result = XGetWindowProperty(display, + result = XGetWindowProperty(display.get(), rootWindow, netWmName, 0, @@ -295,8 +283,6 @@ bool ewmhSupported() if (result == Success) XFree(data); - sf::priv::closeDisplay(display); - return true; } @@ -442,7 +428,7 @@ WindowImplX11::WindowImplX11(WindowHandle handle) : m_isExternal(true) // Make sure to check for EWMH support before we do anything ewmhSupported(); - m_screen = DefaultScreen(m_display); + m_screen = DefaultScreen(m_display.get()); // Save the window handle m_window = handle; @@ -453,7 +439,7 @@ WindowImplX11::WindowImplX11(WindowHandle handle) : m_isExternal(true) XSetWindowAttributes attributes; attributes.event_mask = eventMask; - XChangeWindowAttributes(m_display, m_window, CWEventMask, &attributes); + XChangeWindowAttributes(m_display.get(), m_window, CWEventMask, &attributes); // Set the WM protocols setProtocols(); @@ -477,7 +463,7 @@ m_cursorGrabbed(m_fullscreen) // Make sure to check for EWMH support before we do anything ewmhSupported(); - m_screen = DefaultScreen(m_display); + m_screen = DefaultScreen(m_display.get()); // Compute position and size Vector2i windowPosition; @@ -487,7 +473,7 @@ m_cursorGrabbed(m_fullscreen) } else { - const Vector2i displaySize(DisplayWidth(m_display, m_screen), DisplayHeight(m_display, m_screen)); + const Vector2i displaySize(DisplayWidth(m_display.get(), m_screen), DisplayHeight(m_display.get(), m_screen)); windowPosition = displaySize - Vector2i(mode.size) / 2; } @@ -501,13 +487,13 @@ m_cursorGrabbed(m_fullscreen) if (settings.attributeFlags == 0xFFFFFFFF) { // Choose default visual since the user is going to use their own rendering API - visual = DefaultVisual(m_display, m_screen); - depth = DefaultDepth(m_display, m_screen); + visual = DefaultVisual(m_display.get(), m_screen); + depth = DefaultDepth(m_display.get(), m_screen); } else { // Choose the visual according to the context settings - const XVisualInfo visualInfo = ContextType::selectBestVisual(m_display, mode.bitsPerPixel, settings); + const XVisualInfo visualInfo = ContextType::selectBestVisual(m_display.get(), mode.bitsPerPixel, settings); visual = visualInfo.visual; depth = visualInfo.depth; @@ -515,12 +501,12 @@ m_cursorGrabbed(m_fullscreen) // Define the window attributes XSetWindowAttributes attributes; - attributes.colormap = XCreateColormap(m_display, DefaultRootWindow(m_display), visual, AllocNone); - attributes.event_mask = eventMask; + attributes.colormap = XCreateColormap(m_display.get(), DefaultRootWindow(m_display.get()), visual, AllocNone); + attributes.event_mask = eventMask; attributes.override_redirect = (m_fullscreen && !ewmhSupported()) ? True : False; - m_window = XCreateWindow(m_display, - DefaultRootWindow(m_display), + m_window = XCreateWindow(m_display.get(), + DefaultRootWindow(m_display.get()), windowPosition.x, windowPosition.y, width, @@ -545,7 +531,7 @@ m_cursorGrabbed(m_fullscreen) XWMHints xHints{}; xHints.flags = StateHint; xHints.initial_state = NormalState; - XSetWMHints(m_display, m_window, &xHints); + XSetWMHints(m_display.get(), m_window, &xHints); // 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) @@ -606,7 +592,7 @@ m_cursorGrabbed(m_fullscreen) hints.functions |= MWM_FUNC_CLOSE; } - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, wmHintsAtom, wmHintsAtom, @@ -627,7 +613,7 @@ m_cursorGrabbed(m_fullscreen) sizeHints.min_height = sizeHints.max_height = static_cast(height); sizeHints.x = windowPosition.x; sizeHints.y = windowPosition.y; - XSetWMNormalHints(m_display, m_window, &sizeHints); + XSetWMNormalHints(m_display.get(), m_window, &sizeHints); } // Set the window's WM class (this can be used by window managers) @@ -649,7 +635,7 @@ m_cursorGrabbed(m_fullscreen) std::copy(ansiTitle.begin(), ansiTitle.end(), windowClass.begin()); hint.res_class = windowClass.data(); - XSetClassHint(m_display, m_window, &hint); + XSetClassHint(m_display.get(), m_window, &hint); // Set the window's name setTitle(title); @@ -664,9 +650,9 @@ m_cursorGrabbed(m_fullscreen) // otherwise some windows managers will not remove window decorations XSizeHints sizeHints{}; long flags = 0; - XGetWMNormalHints(m_display, m_window, &sizeHints, &flags); + XGetWMNormalHints(m_display.get(), m_window, &sizeHints, &flags); sizeHints.flags &= ~(PMinSize | PMaxSize); - XSetWMNormalHints(m_display, m_window, &sizeHints); + XSetWMNormalHints(m_display.get(), m_window, &sizeHints); setVideoMode(mode); switchToFullscreen(); @@ -684,15 +670,15 @@ WindowImplX11::~WindowImplX11() // Destroy icon pixmap if (m_iconPixmap) - XFreePixmap(m_display, m_iconPixmap); + XFreePixmap(m_display.get(), m_iconPixmap); // Destroy icon mask pixmap if (m_iconMaskPixmap) - XFreePixmap(m_display, m_iconMaskPixmap); + XFreePixmap(m_display.get(), m_iconMaskPixmap); // Destroy the cursor if (m_hiddenCursor) - XFreeCursor(m_display, m_hiddenCursor); + XFreeCursor(m_display.get(), m_hiddenCursor); // Destroy the input context if (m_inputContext) @@ -701,17 +687,10 @@ WindowImplX11::~WindowImplX11() // Destroy the window if (m_window && !m_isExternal) { - XDestroyWindow(m_display, m_window); - XFlush(m_display); + XDestroyWindow(m_display.get(), m_window); + XFlush(m_display.get()); } - // Close the input method - if (m_inputMethod) - closeXim(m_inputMethod); - - // Close the connection with the X server - closeDisplay(m_display); - // Remove this window from the global list of windows (required for focus request) const std::lock_guard lock(allWindowsMutex); allWindows.erase(std::find(allWindows.begin(), allWindows.end(), this)); @@ -733,7 +712,7 @@ void WindowImplX11::processEvents() XEvent event; // Pick out the events that are interesting for this window - while (XCheckIfEvent(m_display, &event, &checkEvent, reinterpret_cast(m_window))) + while (XCheckIfEvent(m_display.get(), &event, &checkEvent, reinterpret_cast(m_window))) { // This function implements a workaround to properly discard // repeated key events when necessary. The problem is that the @@ -749,7 +728,7 @@ void WindowImplX11::processEvents() while (event.type == KeyRelease) { XEvent nextEvent; - if (XCheckIfEvent(m_display, &nextEvent, checkEvent, reinterpret_cast(m_window))) + if (XCheckIfEvent(m_display.get(), &nextEvent, checkEvent, reinterpret_cast(m_window))) { if ((nextEvent.type == KeyPress) && (nextEvent.xkey.keycode == event.xkey.keycode) && (event.xkey.time <= nextEvent.xkey.time) && (nextEvent.xkey.time <= event.xkey.time + 1)) @@ -811,7 +790,7 @@ Vector2i WindowImplX11::getPosition() const int xAbsRelToRoot; int yAbsRelToRoot; - XTranslateCoordinates(m_display, m_window, DefaultRootWindow(m_display), 0, 0, &xAbsRelToRoot, &yAbsRelToRoot, &child); + XTranslateCoordinates(m_display.get(), m_window, DefaultRootWindow(m_display.get()), 0, 0, &xAbsRelToRoot, &yAbsRelToRoot, &child); // CASE 1: some rare WMs actually put the window exactly where we tell // it to, even with decorations and such, which get shifted back. @@ -825,7 +804,7 @@ Vector2i WindowImplX11::getPosition() const long xFrameExtent; long yFrameExtent; - if (getEWMHFrameExtents(m_display, m_window, xFrameExtent, yFrameExtent)) + if (getEWMHFrameExtents(m_display.get(), m_window, xFrameExtent, yFrameExtent)) { // Get final X/Y coordinates: subtract EWMH frame extents from // absolute window position. @@ -846,12 +825,12 @@ Vector2i WindowImplX11::getPosition() const // our window is part of decorations/borders in some way. This // seems to hold true for most reasonable WM implementations. ::Window ancestor = m_window; - ::Window root = DefaultRootWindow(m_display); + ::Window root = DefaultRootWindow(m_display.get()); - while (getParentWindow(m_display, ancestor) != root) + while (getParentWindow(m_display.get(), ancestor) != root) { // Next window up (parent window). - ancestor = getParentWindow(m_display, ancestor); + ancestor = getParentWindow(m_display.get(), ancestor); } // Get final X/Y coordinates: take the relative position to @@ -863,7 +842,7 @@ Vector2i WindowImplX11::getPosition() const unsigned int borderWidth; unsigned int depth; - XGetGeometry(m_display, ancestor, &root, &xRelToRoot, &yRelToRoot, &width, &height, &borderWidth, &depth); + XGetGeometry(m_display.get(), ancestor, &root, &xRelToRoot, &yRelToRoot, &width, &height, &borderWidth, &depth); return {xRelToRoot, yRelToRoot}; } @@ -872,8 +851,8 @@ Vector2i WindowImplX11::getPosition() const //////////////////////////////////////////////////////////// void WindowImplX11::setPosition(const Vector2i& position) { - XMoveWindow(m_display, m_window, position.x, position.y); - XFlush(m_display); + XMoveWindow(m_display.get(), m_window, position.x, position.y); + XFlush(m_display.get()); } @@ -881,7 +860,7 @@ void WindowImplX11::setPosition(const Vector2i& position) Vector2u WindowImplX11::getSize() const { XWindowAttributes attributes; - XGetWindowAttributes(m_display, m_window, &attributes); + XGetWindowAttributes(m_display.get(), m_window, &attributes); return Vector2u(Vector2i(attributes.width, attributes.height)); } @@ -896,11 +875,11 @@ void WindowImplX11::setSize(const Vector2u& size) sizeHints.flags = PMinSize | PMaxSize; sizeHints.min_width = sizeHints.max_width = static_cast(size.x); sizeHints.min_height = sizeHints.max_height = static_cast(size.y); - XSetWMNormalHints(m_display, m_window, &sizeHints); + XSetWMNormalHints(m_display.get(), m_window, &sizeHints); } - XResizeWindow(m_display, m_window, size.x, size.y); - XFlush(m_display); + XResizeWindow(m_display.get(), m_window, size.x, size.y); + XFlush(m_display.get()); } @@ -933,7 +912,7 @@ void WindowImplX11::setTitle(const String& title) // Set the _NET_WM_NAME atom, which specifies a UTF-8 encoded window title. const Atom wmName = getAtom("_NET_WM_NAME", false); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, wmName, useUtf8, @@ -944,7 +923,7 @@ void WindowImplX11::setTitle(const String& title) // Set the _NET_WM_ICON_NAME atom, which specifies a UTF-8 encoded window title. const Atom wmIconName = getAtom("_NET_WM_ICON_NAME", false); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, wmIconName, useUtf8, @@ -955,7 +934,7 @@ void WindowImplX11::setTitle(const String& title) // Set the non-Unicode title as a fallback for window managers who don't support _NET_WM_NAME. #ifdef X_HAVE_UTF8_STRING - Xutf8SetWMProperties(m_display, + Xutf8SetWMProperties(m_display.get(), m_window, title.toAnsiString().c_str(), title.toAnsiString().c_str(), @@ -965,7 +944,15 @@ void WindowImplX11::setTitle(const String& title) nullptr, nullptr); #else - XmbSetWMProperties(m_display, m_window, title.toAnsiString().c_str(), title.toAnsiString().c_str(), nullptr, 0, nullptr, nullptr, nullptr); + XmbSetWMProperties(m_display.get(), + m_window, + title.toAnsiString().c_str(), + title.toAnsiString().c_str(), + nullptr, + 0, + nullptr, + nullptr, + nullptr); #endif } @@ -986,10 +973,10 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) } // Create the icon pixmap - Visual* defVisual = DefaultVisual(m_display, m_screen); - auto defDepth = static_cast(DefaultDepth(m_display, m_screen)); + Visual* defVisual = DefaultVisual(m_display.get(), m_screen); + auto defDepth = static_cast(DefaultDepth(m_display.get(), m_screen)); auto iconImage = X11Ptr( - XCreateImage(m_display, defVisual, defDepth, ZPixmap, 0, reinterpret_cast(iconPixels), size.x, size.y, 32, 0)); + XCreateImage(m_display.get(), defVisual, defDepth, ZPixmap, 0, reinterpret_cast(iconPixels), size.x, size.y, 32, 0)); if (!iconImage) { err() << "Failed to set the window's icon" << std::endl; @@ -997,16 +984,16 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) } if (m_iconPixmap) - XFreePixmap(m_display, m_iconPixmap); + XFreePixmap(m_display.get(), m_iconPixmap); if (m_iconMaskPixmap) - XFreePixmap(m_display, m_iconMaskPixmap); + XFreePixmap(m_display.get(), m_iconMaskPixmap); - m_iconPixmap = XCreatePixmap(m_display, RootWindow(m_display, m_screen), size.x, size.y, defDepth); + m_iconPixmap = XCreatePixmap(m_display.get(), RootWindow(m_display.get(), m_screen), size.x, size.y, defDepth); XGCValues values; - GC iconGC = XCreateGC(m_display, m_iconPixmap, 0, &values); - XPutImage(m_display, m_iconPixmap, iconGC, iconImage.get(), 0, 0, 0, 0, size.x, size.y); - XFreeGC(m_display, iconGC); + GC iconGC = XCreateGC(m_display.get(), m_iconPixmap, 0, &values); + XPutImage(m_display.get(), m_iconPixmap, iconGC, iconImage.get(), 0, 0, 0, 0, size.x, size.y); + XFreeGC(m_display.get(), iconGC); // Create the mask pixmap (must have 1 bit depth) const std::size_t pitch = (size.x + 7) / 8; @@ -1025,7 +1012,7 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) } } } - m_iconMaskPixmap = XCreatePixmapFromBitmapData(m_display, + m_iconMaskPixmap = XCreatePixmapFromBitmapData(m_display.get(), m_window, reinterpret_cast(maskPixels.data()), size.x, @@ -1039,7 +1026,7 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) hints.flags = IconPixmapHint | IconMaskHint; hints.icon_pixmap = m_iconPixmap; hints.icon_mask = m_iconMaskPixmap; - XSetWMHints(m_display, m_window, &hints); + XSetWMHints(m_display.get(), m_window, &hints); // ICCCM wants BGRA pixels: swap red and blue channels // ICCCM also wants the first 2 unsigned 32-bit values to be width and height @@ -1060,7 +1047,7 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) const Atom netWmIcon = getAtom("_NET_WM_ICON"); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, netWmIcon, XA_CARDINAL, @@ -1069,7 +1056,7 @@ void WindowImplX11::setIcon(const Vector2u& size, const std::uint8_t* pixels) reinterpret_cast(icccmIconPixels.data()), static_cast(2 + size.x * size.y)); - XFlush(m_display); + XFlush(m_display.get()); } @@ -1078,12 +1065,12 @@ void WindowImplX11::setVisible(bool visible) { if (visible) { - XMapWindow(m_display, m_window); + XMapWindow(m_display.get(), m_window); if (m_fullscreen) switchToFullscreen(); - XFlush(m_display); + XFlush(m_display.get()); // Before continuing, make sure the WM has // internally marked the window as viewable @@ -1092,9 +1079,9 @@ void WindowImplX11::setVisible(bool visible) } else { - XUnmapWindow(m_display, m_window); + XUnmapWindow(m_display.get(), m_window); - XFlush(m_display); + XFlush(m_display.get()); // Before continuing, make sure the WM has // internally marked the window as unviewable @@ -1107,8 +1094,8 @@ void WindowImplX11::setVisible(bool visible) //////////////////////////////////////////////////////////// void WindowImplX11::setMouseCursorVisible(bool visible) { - XDefineCursor(m_display, m_window, visible ? m_lastCursor : m_hiddenCursor); - XFlush(m_display); + XDefineCursor(m_display.get(), m_window, visible ? m_lastCursor : m_hiddenCursor); + XFlush(m_display.get()); } @@ -1116,8 +1103,8 @@ void WindowImplX11::setMouseCursorVisible(bool visible) void WindowImplX11::setMouseCursor(const CursorImpl& cursor) { m_lastCursor = cursor.m_cursor; - XDefineCursor(m_display, m_window, m_lastCursor); - XFlush(m_display); + XDefineCursor(m_display.get(), m_window, m_lastCursor); + XFlush(m_display.get()); } @@ -1135,7 +1122,7 @@ void WindowImplX11::setMouseCursorGrabbed(bool grabbed) // Try multiple times to grab the cursor for (unsigned int trial = 0; trial < maxTrialsCount; ++trial) { - const int result = XGrabPointer(m_display, m_window, True, None, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); + const int result = XGrabPointer(m_display.get(), m_window, True, None, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); if (result == GrabSuccess) { @@ -1153,7 +1140,7 @@ void WindowImplX11::setMouseCursorGrabbed(bool grabbed) else { // Release the cursor from the window and disable cursor grabbing - XUngrabPointer(m_display, CurrentTime); + XUngrabPointer(m_display.get(), CurrentTime); m_cursorGrabbed = false; } } @@ -1191,7 +1178,7 @@ void WindowImplX11::requestFocus() // Check if window is viewable (not on other desktop, ...) // TODO: Check also if minimized XWindowAttributes attributes; - if (XGetWindowAttributes(m_display, m_window, &attributes) == 0) + if (XGetWindowAttributes(m_display.get(), m_window, &attributes) == 0) { sf::err() << "Failed to check if window is viewable while requesting focus" << std::endl; return; // error getting attribute @@ -1209,13 +1196,13 @@ void WindowImplX11::requestFocus() { // Otherwise: display urgency hint (flashing application logo) // Ensure WM hints exist, allocate if necessary - auto hints = X11Ptr(XGetWMHints(m_display, m_window)); + auto hints = X11Ptr(XGetWMHints(m_display.get(), m_window)); if (hints == nullptr) hints.reset(XAllocWMHints()); // Add urgency (notification) flag to hints hints->flags |= XUrgencyHint; - XSetWMHints(m_display, m_window, hints.get()); + XSetWMHints(m_display.get(), m_window, hints.get()); } } @@ -1225,7 +1212,7 @@ bool WindowImplX11::hasFocus() const { ::Window focusedWindow = 0; int revertToReturn = 0; - XGetInputFocus(m_display, &focusedWindow, &revertToReturn); + XGetInputFocus(m_display.get(), &focusedWindow, &revertToReturn); return m_window == focusedWindow; } @@ -1244,7 +1231,7 @@ void WindowImplX11::grabFocus() // Only try to grab focus if the window is mapped XWindowAttributes attr; - XGetWindowAttributes(m_display, m_window, &attr); + XGetWindowAttributes(m_display.get(), m_window, &attr); if (attr.map_state == IsUnmapped) return; @@ -1260,22 +1247,22 @@ void WindowImplX11::grabFocus() event.xclient.data.l[1] = static_cast(m_lastInputTime); event.xclient.data.l[2] = 0; // We don't know the currently active window - const int result = XSendEvent(m_display, - DefaultRootWindow(m_display), + const int result = XSendEvent(m_display.get(), + DefaultRootWindow(m_display.get()), False, SubstructureNotifyMask | SubstructureRedirectMask, &event); - XFlush(m_display); + XFlush(m_display.get()); if (!result) err() << "Setting fullscreen failed, could not send \"_NET_ACTIVE_WINDOW\" event" << std::endl; } else { - XRaiseWindow(m_display, m_window); - XSetInputFocus(m_display, m_window, RevertToPointerRoot, CurrentTime); - XFlush(m_display); + XRaiseWindow(m_display.get(), m_window); + XSetInputFocus(m_display.get(), m_window, RevertToPointerRoot, CurrentTime); + XFlush(m_display.get()); } } @@ -1300,10 +1287,10 @@ void WindowImplX11::setVideoMode(const VideoMode& mode) } // Get root window - ::Window rootWindow = RootWindow(m_display, m_screen); + ::Window rootWindow = RootWindow(m_display.get(), m_screen); // Get the screen resources - auto res = X11Ptr(XRRGetScreenResources(m_display, rootWindow)); + auto res = X11Ptr(XRRGetScreenResources(m_display.get(), rootWindow)); if (!res) { err() << "Failed to get the current screen resources for fullscreen mode, switching to window mode" << std::endl; @@ -1313,7 +1300,7 @@ void WindowImplX11::setVideoMode(const VideoMode& mode) RROutput output = getOutputPrimary(rootWindow, res.get(), xRandRMajor, xRandRMinor); // Get output info from output - auto outputInfo = X11Ptr(XRRGetOutputInfo(m_display, res.get(), output)); + auto outputInfo = X11Ptr(XRRGetOutputInfo(m_display.get(), res.get(), output)); if (!outputInfo || outputInfo->connection == RR_Disconnected) { err() << "Failed to get output info for fullscreen mode, switching to window mode" << std::endl; @@ -1321,7 +1308,7 @@ void WindowImplX11::setVideoMode(const VideoMode& mode) } // Retrieve current RRMode, screen position and rotation - auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc)); + auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display.get(), res.get(), outputInfo->crtc)); if (!crtcInfo) { err() << "Failed to get crtc info for fullscreen mode, switching to window mode" << std::endl; @@ -1356,7 +1343,7 @@ void WindowImplX11::setVideoMode(const VideoMode& mode) m_oldRRCrtc = outputInfo->crtc; // Switch to fullscreen mode - XRRSetCrtcConfig(m_display, + XRRSetCrtcConfig(m_display.get(), res.get(), outputInfo->crtc, CurrentTime, @@ -1385,7 +1372,8 @@ void WindowImplX11::resetVideoMode() int xRandRMinor; if (checkXRandR(xRandRMajor, xRandRMinor)) { - auto res = X11Ptr(XRRGetScreenResources(m_display, DefaultRootWindow(m_display))); + auto res = X11Ptr( + XRRGetScreenResources(m_display.get(), DefaultRootWindow(m_display.get()))); if (!res) { err() << "Failed to get the current screen resources to reset the video mode" << std::endl; @@ -1393,7 +1381,7 @@ void WindowImplX11::resetVideoMode() } // Retrieve current screen position and rotation - auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display, res.get(), m_oldRRCrtc)); + auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display.get(), res.get(), m_oldRRCrtc)); if (!crtcInfo) { err() << "Failed to get crtc info to reset the video mode" << std::endl; @@ -1405,7 +1393,7 @@ void WindowImplX11::resetVideoMode() // 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)); + output = XRRGetOutputPrimary(m_display.get(), DefaultRootWindow(m_display.get())); // Check if returned output is valid, otherwise use the first screen if (output == None) @@ -1416,7 +1404,7 @@ void WindowImplX11::resetVideoMode() output = res->outputs[0]; } - XRRSetCrtcConfig(m_display, + XRRSetCrtcConfig(m_display.get(), res.get(), m_oldRRCrtc, CurrentTime, @@ -1449,7 +1437,7 @@ void WindowImplX11::switchToFullscreen() { constexpr unsigned long bypassCompositor = 1; - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, netWmBypassCompositor, XA_CARDINAL, @@ -1478,8 +1466,8 @@ void WindowImplX11::switchToFullscreen() event.xclient.data.l[2] = 0; // No second property event.xclient.data.l[3] = 1; // Normal window - const int result = XSendEvent(m_display, - DefaultRootWindow(m_display), + const int result = XSendEvent(m_display.get(), + DefaultRootWindow(m_display.get()), False, SubstructureNotifyMask | SubstructureRedirectMask, &event); @@ -1528,7 +1516,7 @@ void WindowImplX11::setProtocols() { const long pid = getpid(); - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, netWmPid, XA_CARDINAL, @@ -1542,7 +1530,7 @@ void WindowImplX11::setProtocols() if (!atoms.empty()) { - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, wmProtocols, XA_ATOM, @@ -1568,7 +1556,7 @@ void WindowImplX11::initialize() if (m_inputMethod) { - m_inputContext = XCreateIC(m_inputMethod, + m_inputContext = XCreateIC(m_inputMethod.get(), XNClientWindow, m_window, XNFocusWindow, @@ -1591,7 +1579,7 @@ void WindowImplX11::initialize() if (wmWindowType && wmWindowTypeNormal) { - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, wmWindowType, XA_ATOM, @@ -1611,7 +1599,7 @@ void WindowImplX11::initialize() createHiddenCursor(); // Flush the commands queue - XFlush(m_display); + XFlush(m_display.get()); // Add this window to the global list of windows (required for focus request) const std::lock_guard lock(allWindowsMutex); @@ -1628,7 +1616,7 @@ void WindowImplX11::updateLastInputTime(::Time time) if (netWmUserTime) { - XChangeProperty(m_display, + XChangeProperty(m_display.get(), m_window, netWmUserTime, XA_CARDINAL, @@ -1647,19 +1635,19 @@ void WindowImplX11::updateLastInputTime(::Time time) void WindowImplX11::createHiddenCursor() { // Create the cursor's pixmap (1x1 pixels) - const Pixmap cursorPixmap = XCreatePixmap(m_display, m_window, 1, 1, 1); - GC graphicsContext = XCreateGC(m_display, cursorPixmap, 0, nullptr); - XDrawPoint(m_display, cursorPixmap, graphicsContext, 0, 0); - XFreeGC(m_display, graphicsContext); + const Pixmap cursorPixmap = XCreatePixmap(m_display.get(), m_window, 1, 1, 1); + GC graphicsContext = XCreateGC(m_display.get(), cursorPixmap, 0, nullptr); + XDrawPoint(m_display.get(), cursorPixmap, graphicsContext, 0, 0); + XFreeGC(m_display.get(), graphicsContext); // Create the cursor, using the pixmap as both the shape and the mask of the cursor XColor color; color.flags = DoRed | DoGreen | DoBlue; color.red = color.blue = color.green = 0; - m_hiddenCursor = XCreatePixmapCursor(m_display, cursorPixmap, cursorPixmap, &color, &color, 0, 0); + m_hiddenCursor = XCreatePixmapCursor(m_display.get(), cursorPixmap, cursorPixmap, &color, &color, 0, 0); // We don't need the pixmap any longer, free it - XFreePixmap(m_display, cursorPixmap); + XFreePixmap(m_display.get(), cursorPixmap); } @@ -1703,7 +1691,15 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) // Try multiple times to grab the cursor for (unsigned int trial = 0; trial < maxTrialsCount; ++trial) { - const int result = XGrabPointer(m_display, m_window, True, None, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime); + const int result = XGrabPointer(m_display.get(), + m_window, + True, + None, + GrabModeAsync, + GrabModeAsync, + m_window, + None, + CurrentTime); if (result == GrabSuccess) { @@ -1724,12 +1720,12 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) pushEvent(event); // If the window has been previously marked urgent (notification) as a result of a focus request, undo that - auto hints = X11Ptr(XGetWMHints(m_display, m_window)); + auto hints = X11Ptr(XGetWMHints(m_display.get(), m_window)); if (hints != nullptr) { // Remove urgency (notification) flag from hints hints->flags &= ~XUrgencyHint; - XSetWMHints(m_display, m_window, hints.get()); + XSetWMHints(m_display.get(), m_window, hints.get()); } break; @@ -1744,7 +1740,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) // Release cursor if (m_cursorGrabbed) - XUngrabPointer(m_display, CurrentTime); + XUngrabPointer(m_display.get(), CurrentTime); Event event; event.type = Event::LostFocus; @@ -1796,10 +1792,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) (windowEvent.xclient.data.l[0]) == static_cast(netWmPing)) { // Handle the _NET_WM_PING message, send pong back to WM to show that we are responsive - windowEvent.xclient.window = DefaultRootWindow(m_display); + windowEvent.xclient.window = DefaultRootWindow(m_display.get()); - XSendEvent(m_display, - DefaultRootWindow(m_display), + XSendEvent(m_display.get(), + DefaultRootWindow(m_display.get()), False, SubstructureNotifyMask | SubstructureRedirectMask, &windowEvent); @@ -2099,14 +2095,15 @@ bool WindowImplX11::checkXRandR(int& xRandRMajor, int& xRandRMinor) { // Check if the XRandR extension is present int version; - if (!XQueryExtension(m_display, "RANDR", &version, &version, &version)) + if (!XQueryExtension(m_display.get(), "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)) + if (!XRRQueryVersion(m_display.get(), &xRandRMajor, &xRandRMinor) || xRandRMajor < 1 || + (xRandRMajor == 1 && xRandRMinor < 2)) { err() << "XRandR is too old" << std::endl; return false; @@ -2122,7 +2119,7 @@ RROutput WindowImplX11::getOutputPrimary(::Window& rootWindow, XRRScreenResource // if xRandR version >= 1.3 get the primary screen else take the first screen if ((xRandRMajor == 1 && xRandRMinor >= 3) || xRandRMajor > 1) { - const RROutput output = XRRGetOutputPrimary(m_display, rootWindow); + const RROutput output = XRRGetOutputPrimary(m_display.get(), rootWindow); // Check if returned output is valid, otherwise use the first screen if (output == None) @@ -2142,10 +2139,10 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition() Vector2i monitorPosition; // Get root window - ::Window rootWindow = RootWindow(m_display, m_screen); + ::Window rootWindow = RootWindow(m_display.get(), m_screen); // Get the screen resources - auto res = X11Ptr(XRRGetScreenResources(m_display, rootWindow)); + auto res = X11Ptr(XRRGetScreenResources(m_display.get(), rootWindow)); if (!res) { err() << "Failed to get the current screen resources for primary monitor position" << std::endl; @@ -2161,7 +2158,7 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition() const RROutput output = getOutputPrimary(rootWindow, res.get(), xRandRMajor, xRandRMinor); // Get output info from output - auto outputInfo = X11Ptr(XRRGetOutputInfo(m_display, res.get(), output)); + auto outputInfo = X11Ptr(XRRGetOutputInfo(m_display.get(), res.get(), output)); if (!outputInfo || outputInfo->connection == RR_Disconnected) { err() << "Failed to get output info for primary monitor position" << std::endl; @@ -2169,7 +2166,7 @@ Vector2i WindowImplX11::getPrimaryMonitorPosition() } // Retrieve current RRMode, screen position and rotation - auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc)); + auto crtcInfo = X11Ptr(XRRGetCrtcInfo(m_display.get(), res.get(), outputInfo->crtc)); if (!crtcInfo) { err() << "Failed to get crtc info for primary monitor position" << std::endl; @@ -2203,7 +2200,7 @@ void WindowImplX11::setWindowSizeConstraints() const sizeHints.max_width = static_cast(maximumSize->x); sizeHints.max_height = static_cast(maximumSize->y); } - XSetWMNormalHints(m_display, m_window, &sizeHints); + XSetWMNormalHints(m_display.get(), m_window, &sizeHints); } } // namespace sf::priv diff --git a/src/SFML/Window/Unix/WindowImplX11.hpp b/src/SFML/Window/Unix/WindowImplX11.hpp index 398ac2e5f..3261d61b7 100644 --- a/src/SFML/Window/Unix/WindowImplX11.hpp +++ b/src/SFML/Window/Unix/WindowImplX11.hpp @@ -35,6 +35,7 @@ #include #include +#include namespace sf::priv @@ -321,15 +322,15 @@ private: //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - ::Window m_window{}; ///< X identifier defining our window - ::Display* m_display; ///< Pointer to the display - int m_screen; ///< Screen identifier - XIM m_inputMethod{}; ///< Input method linked to the X display - XIC m_inputContext{}; ///< Input context used to get unicode input in our window - bool m_isExternal{}; ///< Tell whether the window has been created externally or by SFML - RRMode 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 + ::Window m_window{}; ///< X identifier defining our window + std::shared_ptr m_display; ///< Pointer to the display + int m_screen; ///< Screen identifier + std::shared_ptr<_XIM> m_inputMethod; ///< Input method linked to the X display + XIC m_inputContext{}; ///< Input context used to get unicode input in our window + bool m_isExternal{}; ///< Tell whether the window has been created externally or by SFML + RRMode 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{None}; ///< Last cursor used -- this data is not owned by the window and is required to be always valid bool m_keyRepeat{true}; ///< Is the KeyRepeat feature enabled? Vector2i m_previousSize{-1, -1}; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only)