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