mirror of
https://github.com/SFML/SFML.git
synced 2025-01-31 21:55:13 +08:00
Modernize management of X11 resources
This approach uses RAII to manage resources rather than relying on correctly calling cleanup functions at all places where scope exits. This also has the benefit of removing a mutex and no longer having to lock that mutex so many times.
This commit is contained in:
parent
7d095c8b6e
commit
5dfa3f7858
@ -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<XPointer>(m_window)))
|
||||
while (XCheckIfEvent(m_display.get(), &event, &checkEvent, reinterpret_cast<XPointer>(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<std::uint8_t> 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<XEvent*>(&selectionEvent));
|
||||
XSendEvent(m_display.get(),
|
||||
selectionRequestEvent.requestor,
|
||||
True,
|
||||
NoEventMask,
|
||||
reinterpret_cast<XEvent*>(&selectionEvent));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<XEvent> 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<XEvent> 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
|
||||
|
@ -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<char*>(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<char*>(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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<std::string, Atom>;
|
||||
AtomMap atoms;
|
||||
// A nested named namespace is used here to allow unity builds of SFML.
|
||||
namespace UnixDisplayImpl
|
||||
{
|
||||
std::weak_ptr<Display> weakSharedDisplay;
|
||||
std::recursive_mutex mutex;
|
||||
} // namespace UnixDisplayImpl
|
||||
} // namespace
|
||||
|
||||
|
||||
namespace sf::priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
Display* openDisplay()
|
||||
std::shared_ptr<Display> 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<std::string, Atom> 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;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
@ -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<Display> 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
|
||||
|
@ -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<XVisualInfo>(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals));
|
||||
auto visualInfo = X11Ptr<XVisualInfo>(
|
||||
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<GLXFBConfig[]>(
|
||||
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<std::size_t>(nbConfigs)); ++i)
|
||||
{
|
||||
auto visual = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, configs[i]));
|
||||
auto visual = X11Ptr<XVisualInfo>(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<int>(size.x), GLX_PBUFFER_HEIGHT, static_cast<int>(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<int>(fbConfigId), 0, 0};
|
||||
|
||||
int count = 0;
|
||||
auto fbconfig = X11Ptr<GLXFBConfig>(glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count));
|
||||
auto fbconfig = X11Ptr<GLXFBConfig>(
|
||||
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), attributes, &count));
|
||||
|
||||
if (count == 1)
|
||||
visualInfo = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, *fbconfig));
|
||||
visualInfo = X11Ptr<XVisualInfo>(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<XVisualInfo>(XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals));
|
||||
visualInfo = X11Ptr<XVisualInfo>(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<GLXFBConfig[]>(glXChooseFBConfig(m_display, DefaultScreen(m_display), nullptr, &nbConfigs));
|
||||
int nbConfigs = 0;
|
||||
auto configs = X11Ptr<GLXFBConfig[]>(
|
||||
glXChooseFBConfig(m_display.get(), DefaultScreen(m_display.get()), nullptr, &nbConfigs));
|
||||
|
||||
for (std::size_t i = 0; configs && (i < static_cast<std::size_t>(nbConfigs)); ++i)
|
||||
{
|
||||
auto visual = X11Ptr<XVisualInfo>(glXGetVisualFromFBConfig(m_display, configs[i]));
|
||||
auto visual = X11Ptr<XVisualInfo>(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)
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <glad/glx.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<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?
|
||||
};
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<std::string, sf::Keyboard::Scancode> nameScancodeMap = getNameScancodeMap();
|
||||
sf::Keyboard::Scancode scancode = sf::Keyboard::Scan::Unknown;
|
||||
@ -505,7 +505,7 @@ void ensureMapping()
|
||||
{
|
||||
if (keycodeToScancode[static_cast<KeyCode>(keycode)] == sf::Keyboard::Scan::Unknown)
|
||||
{
|
||||
scancode = translateKeyCode(display, static_cast<KeyCode>(keycode));
|
||||
scancode = translateKeyCode(display.get(), static_cast<KeyCode>(keycode));
|
||||
|
||||
if (scancode != sf::Keyboard::Scan::Unknown && scancodeToKeycode[scancode] == nullKeyCode)
|
||||
scancodeToKeycode[scancode] = static_cast<KeyCode>(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;
|
||||
|
@ -57,18 +57,18 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
||||
std::vector<VideoMode> 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<XRRScreenConfiguration>(XRRGetScreenInfo(display, RootWindow(display, screen)));
|
||||
auto config = X11Ptr<XRRScreenConfiguration>(XRRGetScreenInfo(display.get(), RootWindow(display.get(), screen)));
|
||||
if (config)
|
||||
{
|
||||
// Get the available screen sizes
|
||||
@ -78,7 +78,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
||||
{
|
||||
// Get the list of supported depths
|
||||
int nbDepths = 0;
|
||||
auto depths = X11Ptr<int[]>(XListDepths(display, screen, &nbDepths));
|
||||
auto depths = X11Ptr<int[]>(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<VideoMode> 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<XRRScreenConfiguration>(XRRGetScreenInfo(display, RootWindow(display, screen)));
|
||||
auto config = X11Ptr<XRRScreenConfiguration>(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<unsigned int>(sizes[currentMode].width),
|
||||
static_cast<unsigned int>(sizes[currentMode].height)},
|
||||
static_cast<unsigned int>(DefaultDepth(display, screen)));
|
||||
static_cast<unsigned int>(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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<int>(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<XPointer>(m_window)))
|
||||
while (XCheckIfEvent(m_display.get(), &event, &checkEvent, reinterpret_cast<XPointer>(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<XPointer>(m_window)))
|
||||
if (XCheckIfEvent(m_display.get(), &nextEvent, checkEvent, reinterpret_cast<XPointer>(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<int>(size.x);
|
||||
sizeHints.min_height = sizeHints.max_height = static_cast<int>(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<unsigned int>(DefaultDepth(m_display, m_screen));
|
||||
Visual* defVisual = DefaultVisual(m_display.get(), m_screen);
|
||||
auto defDepth = static_cast<unsigned int>(DefaultDepth(m_display.get(), m_screen));
|
||||
auto iconImage = X11Ptr<XImage>(
|
||||
XCreateImage(m_display, defVisual, defDepth, ZPixmap, 0, reinterpret_cast<char*>(iconPixels), size.x, size.y, 32, 0));
|
||||
XCreateImage(m_display.get(), defVisual, defDepth, ZPixmap, 0, reinterpret_cast<char*>(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<char*>(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<const unsigned char*>(icccmIconPixels.data()),
|
||||
static_cast<int>(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<XWMHints>(XGetWMHints(m_display, m_window));
|
||||
auto hints = X11Ptr<XWMHints>(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<long>(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<XRRScreenResources>(XRRGetScreenResources(m_display, rootWindow));
|
||||
auto res = X11Ptr<XRRScreenResources>(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<XRROutputInfo>(XRRGetOutputInfo(m_display, res.get(), output));
|
||||
auto outputInfo = X11Ptr<XRROutputInfo>(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<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc));
|
||||
auto crtcInfo = X11Ptr<XRRCrtcInfo>(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<XRRScreenResources>(XRRGetScreenResources(m_display, DefaultRootWindow(m_display)));
|
||||
auto res = X11Ptr<XRRScreenResources>(
|
||||
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<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), m_oldRRCrtc));
|
||||
auto crtcInfo = X11Ptr<XRRCrtcInfo>(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<XWMHints>(XGetWMHints(m_display, m_window));
|
||||
auto hints = X11Ptr<XWMHints>(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<long>(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<XRRScreenResources>(XRRGetScreenResources(m_display, rootWindow));
|
||||
auto res = X11Ptr<XRRScreenResources>(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<XRROutputInfo>(XRRGetOutputInfo(m_display, res.get(), output));
|
||||
auto outputInfo = X11Ptr<XRROutputInfo>(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<XRRCrtcInfo>(XRRGetCrtcInfo(m_display, res.get(), outputInfo->crtc));
|
||||
auto crtcInfo = X11Ptr<XRRCrtcInfo>(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<int>(maximumSize->x);
|
||||
sizeHints.max_height = static_cast<int>(maximumSize->y);
|
||||
}
|
||||
XSetWMNormalHints(m_display, m_window, &sizeHints);
|
||||
XSetWMNormalHints(m_display.get(), m_window, &sizeHints);
|
||||
}
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
|
||||
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<Display> 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)
|
||||
|
Loading…
Reference in New Issue
Block a user