Wrapped XCB replies in scoped pointers.
This commit is contained in:
parent
b2b35d0a43
commit
95ec9180ad
@ -25,9 +25,10 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/Window.hpp> // important to be included first (conflict with None)
|
||||||
#include <SFML/Window/Unix/InputImpl.hpp>
|
#include <SFML/Window/Unix/InputImpl.hpp>
|
||||||
#include <SFML/Window/Window.hpp>
|
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
|
#include <SFML/Window/Unix/ScopedXcbPtr.hpp>
|
||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -157,16 +158,13 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
|
|||||||
if (keycode != 0)
|
if (keycode != 0)
|
||||||
{
|
{
|
||||||
// Get the whole keyboard state
|
// Get the whole keyboard state
|
||||||
xcb_query_keymap_reply_t* keymap = xcb_query_keymap_reply(connection, xcb_query_keymap(connection), NULL);
|
ScopedXcbPtr<xcb_query_keymap_reply_t> keymap(xcb_query_keymap_reply(connection, xcb_query_keymap(connection), NULL));
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseDisplay(display);
|
CloseDisplay(display);
|
||||||
|
|
||||||
// Check our keycode
|
// Check our keycode
|
||||||
bool isPressed = (keymap->keys[keycode / 8] & (1 << (keycode % 8))) != 0;
|
return (keymap->keys[keycode / 8] & (1 << (keycode % 8))) != 0;
|
||||||
|
|
||||||
free(keymap);
|
|
||||||
return isPressed;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -192,18 +190,17 @@ bool InputImpl::isMouseButtonPressed(Mouse::Button button)
|
|||||||
xcb_connection_t* connection = OpenConnection();
|
xcb_connection_t* connection = OpenConnection();
|
||||||
|
|
||||||
// Get pointer mask
|
// Get pointer mask
|
||||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL);
|
ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL));
|
||||||
uint16_t mask = pointer->mask;
|
uint16_t buttons = pointer->mask;
|
||||||
free(pointer);
|
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseConnection(connection);
|
CloseConnection(connection);
|
||||||
|
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
case Mouse::Left: return mask & XCB_BUTTON_MASK_1;
|
case Mouse::Left: return buttons & XCB_BUTTON_MASK_1;
|
||||||
case Mouse::Right: return mask & XCB_BUTTON_MASK_3;
|
case Mouse::Right: return buttons & XCB_BUTTON_MASK_3;
|
||||||
case Mouse::Middle: return mask & XCB_BUTTON_MASK_2;
|
case Mouse::Middle: return buttons & XCB_BUTTON_MASK_2;
|
||||||
case Mouse::XButton1: return false; // not supported by X
|
case Mouse::XButton1: return false; // not supported by X
|
||||||
case Mouse::XButton2: return false; // not supported by X
|
case Mouse::XButton2: return false; // not supported by X
|
||||||
default: return false;
|
default: return false;
|
||||||
@ -217,16 +214,12 @@ Vector2i InputImpl::getMousePosition()
|
|||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
xcb_connection_t* connection = OpenConnection();
|
xcb_connection_t* connection = OpenConnection();
|
||||||
|
|
||||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL);
|
ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(xcb_query_pointer_reply(connection, xcb_query_pointer(connection, XCBDefaultRootWindow(connection)), NULL));
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseConnection(connection);
|
CloseConnection(connection);
|
||||||
|
|
||||||
// Prepare result.
|
return Vector2i(pointer->root_x, pointer->root_y);
|
||||||
Vector2i result(pointer->root_x, pointer->root_y);
|
|
||||||
free(pointer);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -239,16 +232,12 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
|
|||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
xcb_connection_t* connection = OpenConnection();
|
xcb_connection_t* connection = OpenConnection();
|
||||||
|
|
||||||
xcb_query_pointer_reply_t* pointer = xcb_query_pointer_reply(connection, xcb_query_pointer(connection, handle), NULL);
|
ScopedXcbPtr<xcb_query_pointer_reply_t> pointer(xcb_query_pointer_reply(connection, xcb_query_pointer(connection, handle), NULL));
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseConnection(connection);
|
CloseConnection(connection);
|
||||||
|
|
||||||
// Prepare result.
|
return Vector2i(pointer->win_x, pointer->win_y);
|
||||||
Vector2i result(pointer->win_x, pointer->win_y);
|
|
||||||
free(pointer);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
102
src/SFML/Window/Unix/ScopedXcbPtr.hpp
Normal file
102
src/SFML/Window/Unix/ScopedXcbPtr.hpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SFML_SCOPEDXCBPTR_HPP
|
||||||
|
#define SFML_SCOPEDXCBPTR_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Scoped pointer that frees memory returned in XCB replies
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template<typename T>
|
||||||
|
class ScopedXcbPtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Constructor
|
||||||
|
///
|
||||||
|
/// \param pointer Pointer value to store
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ScopedXcbPtr(T* pointer);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Destructor, calls std::free() on the stored pointer
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~ScopedXcbPtr();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Structure dereference operator
|
||||||
|
///
|
||||||
|
/// \return Stored pointer
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
T* operator ->() const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Address operator.
|
||||||
|
///
|
||||||
|
/// \return Address of the stored pointer
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
T** operator &();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check if stored pointer is valid
|
||||||
|
///
|
||||||
|
/// \return true if stored pointer is valid
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Retrieve the stored pointer.
|
||||||
|
///
|
||||||
|
/// \return The stored pointer
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
T* get() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_pointer; ///< Stored pointer
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <SFML/Window/Unix/ScopedXcbPtr.inl>
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
||||||
|
|
||||||
|
#endif // SFML_SCOPEDXCBPTR_HPP
|
72
src/SFML/Window/Unix/ScopedXcbPtr.inl
Normal file
72
src/SFML/Window/Unix/ScopedXcbPtr.inl
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline ScopedXcbPtr<T>::ScopedXcbPtr(T* pointer) :
|
||||||
|
m_pointer(pointer)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline ScopedXcbPtr<T>::~ScopedXcbPtr()
|
||||||
|
{
|
||||||
|
std::free(m_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline T* ScopedXcbPtr<T>::operator ->() const
|
||||||
|
{
|
||||||
|
return m_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline T** ScopedXcbPtr<T>::operator &()
|
||||||
|
{
|
||||||
|
return &m_pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline ScopedXcbPtr<T>::operator bool() const
|
||||||
|
{
|
||||||
|
return m_pointer != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
template <typename T>
|
||||||
|
inline T* ScopedXcbPtr<T>::get() const
|
||||||
|
{
|
||||||
|
return m_pointer;
|
||||||
|
}
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/VideoModeImpl.hpp>
|
#include <SFML/Window/VideoModeImpl.hpp>
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
|
#include <SFML/Window/Unix/ScopedXcbPtr.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -49,7 +50,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
|
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
static const std::string RANDR = "RANDR";
|
static const std::string RANDR = "RANDR";
|
||||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
ScopedXcbPtr<xcb_query_extension_reply_t> randr_ext(xcb_query_extension_reply(
|
||||||
connection,
|
connection,
|
||||||
xcb_query_extension(
|
xcb_query_extension(
|
||||||
connection,
|
connection,
|
||||||
@ -57,25 +58,25 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
RANDR.c_str()
|
RANDR.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (randr_ext->present)
|
if (randr_ext->present)
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
xcb_generic_error_t* error;
|
ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
|
||||||
connection,
|
connection,
|
||||||
xcb_randr_get_screen_info(
|
xcb_randr_get_screen_info(
|
||||||
connection,
|
connection,
|
||||||
screen->root
|
screen->root
|
||||||
),
|
),
|
||||||
&error
|
&error
|
||||||
);
|
));
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
|
||||||
if (sizes && (config->nSizes > 0))
|
if (sizes && (config->nSizes > 0))
|
||||||
{
|
{
|
||||||
// Get the list of supported depths
|
// Get the list of supported depths
|
||||||
@ -100,10 +101,6 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
// Failed to get the screen configuration
|
// Failed to get the screen configuration
|
||||||
err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;
|
err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
free(error);
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -111,8 +108,6 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(randr_ext);
|
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseConnection(connection);
|
CloseConnection(connection);
|
||||||
|
|
||||||
@ -133,7 +128,7 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
|
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
static const std::string RANDR = "RANDR";
|
static const std::string RANDR = "RANDR";
|
||||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
ScopedXcbPtr<xcb_query_extension_reply_t> randr_ext(xcb_query_extension_reply(
|
||||||
connection,
|
connection,
|
||||||
xcb_query_extension(
|
xcb_query_extension(
|
||||||
connection,
|
connection,
|
||||||
@ -141,20 +136,20 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
RANDR.c_str()
|
RANDR.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (randr_ext->present)
|
if (randr_ext->present)
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
xcb_generic_error_t* error;
|
ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
|
||||||
connection,
|
connection,
|
||||||
xcb_randr_get_screen_info(
|
xcb_randr_get_screen_info(
|
||||||
connection,
|
connection,
|
||||||
screen->root
|
screen->root
|
||||||
),
|
),
|
||||||
&error
|
&error
|
||||||
);
|
));
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@ -162,8 +157,8 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
xcb_randr_mode_t currentMode = config->sizeID;
|
xcb_randr_mode_t currentMode = config->sizeID;
|
||||||
|
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
int nbSizes = xcb_randr_get_screen_info_sizes_length(config);
|
int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get());
|
||||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
|
||||||
if (sizes && (nbSizes > 0))
|
if (sizes && (nbSizes > 0))
|
||||||
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);
|
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);
|
||||||
}
|
}
|
||||||
@ -172,10 +167,6 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
// Failed to get the screen configuration
|
// Failed to get the screen configuration
|
||||||
err() << "Failed to retrieve the screen configuration while trying to get the desktop video modes" << std::endl;
|
err() << "Failed to retrieve the screen configuration while trying to get the desktop video modes" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
free(error);
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -183,8 +174,6 @@ VideoMode VideoModeImpl::getDesktopMode()
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(randr_ext);
|
|
||||||
|
|
||||||
// Close the connection with the X server
|
// Close the connection with the X server
|
||||||
CloseConnection(connection);
|
CloseConnection(connection);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
||||||
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
#include <SFML/Window/Unix/WindowImplX11.hpp>
|
||||||
#include <SFML/Window/Unix/Display.hpp>
|
#include <SFML/Window/Unix/Display.hpp>
|
||||||
|
#include <SFML/Window/Unix/ScopedXcbPtr.hpp>
|
||||||
#include <SFML/System/Utf.hpp>
|
#include <SFML/System/Utf.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <xcb/xcb_atom.h>
|
#include <xcb/xcb_atom.h>
|
||||||
@ -181,7 +182,7 @@ m_useSizeHints(false)
|
|||||||
// Create the window
|
// Create the window
|
||||||
m_window = xcb_generate_id(m_connection);
|
m_window = xcb_generate_id(m_connection);
|
||||||
|
|
||||||
xcb_generic_error_t* errptr = xcb_request_check(
|
ScopedXcbPtr<xcb_generic_error_t> errptr(xcb_request_check(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_create_window_checked(
|
xcb_create_window_checked(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -196,12 +197,9 @@ m_useSizeHints(false)
|
|||||||
XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT,
|
XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT,
|
||||||
value_list
|
value_list
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
|
|
||||||
bool createWindowFailed = (errptr != NULL);
|
if (errptr)
|
||||||
free(errptr);
|
|
||||||
|
|
||||||
if (createWindowFailed)
|
|
||||||
{
|
{
|
||||||
err() << "Failed to create window" << std::endl;
|
err() << "Failed to create window" << std::endl;
|
||||||
return;
|
return;
|
||||||
@ -214,7 +212,7 @@ m_useSizeHints(false)
|
|||||||
if (!fullscreen)
|
if (!fullscreen)
|
||||||
{
|
{
|
||||||
static const std::string MOTIF_WM_HINTS = "_MOTIF_WM_HINTS";
|
static const std::string MOTIF_WM_HINTS = "_MOTIF_WM_HINTS";
|
||||||
xcb_intern_atom_reply_t* hintsAtomReply = xcb_intern_atom_reply(
|
ScopedXcbPtr<xcb_intern_atom_reply_t> hintsAtomReply(xcb_intern_atom_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_intern_atom(
|
xcb_intern_atom(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -223,7 +221,7 @@ m_useSizeHints(false)
|
|||||||
MOTIF_WM_HINTS.c_str()
|
MOTIF_WM_HINTS.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (hintsAtomReply)
|
if (hintsAtomReply)
|
||||||
{
|
{
|
||||||
@ -285,8 +283,6 @@ m_useSizeHints(false)
|
|||||||
sizeof(hints) / sizeof(hints.flags),
|
sizeof(hints) / sizeof(hints.flags),
|
||||||
reinterpret_cast<const unsigned char*>(&hints)
|
reinterpret_cast<const unsigned char*>(&hints)
|
||||||
);
|
);
|
||||||
|
|
||||||
free(hintsAtomReply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a hack to force some windows managers to disable resizing
|
// This is a hack to force some windows managers to disable resizing
|
||||||
@ -442,30 +438,26 @@ Vector2i WindowImplX11::getPosition() const
|
|||||||
{
|
{
|
||||||
::Window topLevelWindow = m_window;
|
::Window topLevelWindow = m_window;
|
||||||
::Window nextWindow = topLevelWindow;
|
::Window nextWindow = topLevelWindow;
|
||||||
xcb_query_tree_reply_t* treeReply = NULL;
|
|
||||||
|
|
||||||
// Get "top level" window, i.e. the window with the root window as its parent.
|
// Get "top level" window, i.e. the window with the root window as its parent.
|
||||||
while (nextWindow != m_screen->root)
|
while (nextWindow != m_screen->root)
|
||||||
{
|
{
|
||||||
topLevelWindow = nextWindow;
|
topLevelWindow = nextWindow;
|
||||||
|
|
||||||
treeReply = xcb_query_tree_reply(m_connection, xcb_query_tree(m_connection, topLevelWindow), NULL);
|
ScopedXcbPtr<xcb_query_tree_reply_t> treeReply(xcb_query_tree_reply(m_connection, xcb_query_tree(m_connection, topLevelWindow), NULL));
|
||||||
nextWindow = treeReply->parent;
|
nextWindow = treeReply->parent;
|
||||||
free(treeReply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_get_geometry_reply_t* geometryReply = xcb_get_geometry_reply(
|
ScopedXcbPtr<xcb_get_geometry_reply_t> geometryReply(xcb_get_geometry_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_get_geometry(
|
xcb_get_geometry(
|
||||||
m_connection,
|
m_connection,
|
||||||
topLevelWindow
|
topLevelWindow
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
sf::Vector2i result(geometryReply->x, geometryReply->y);
|
|
||||||
free(geometryReply);
|
|
||||||
|
|
||||||
return result;
|
return sf::Vector2i(geometryReply->x, geometryReply->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -483,11 +475,9 @@ void WindowImplX11::setPosition(const Vector2i& position)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Vector2u WindowImplX11::getSize() const
|
Vector2u WindowImplX11::getSize() const
|
||||||
{
|
{
|
||||||
xcb_get_geometry_reply_t* reply = xcb_get_geometry_reply(m_connection, xcb_get_geometry(m_connection, m_window), NULL);
|
ScopedXcbPtr<xcb_get_geometry_reply_t> reply(xcb_get_geometry_reply(m_connection, xcb_get_geometry(m_connection, m_window), NULL));
|
||||||
Vector2u result(reply->width, reply->height);
|
|
||||||
free(reply);
|
|
||||||
|
|
||||||
return result;
|
return Vector2u(reply->width, reply->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -565,7 +555,7 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8
|
|||||||
xcb_gcontext_t iconGC = xcb_generate_id(m_connection);
|
xcb_gcontext_t iconGC = xcb_generate_id(m_connection);
|
||||||
xcb_create_gc(m_connection, iconGC, iconPixmap, 0, NULL);
|
xcb_create_gc(m_connection, iconGC, iconPixmap, 0, NULL);
|
||||||
|
|
||||||
xcb_generic_error_t* errptr = xcb_request_check(
|
ScopedXcbPtr<xcb_generic_error_t> errptr(xcb_request_check(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_put_image_checked(
|
xcb_put_image_checked(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -581,14 +571,13 @@ void WindowImplX11::setIcon(unsigned int width, unsigned int height, const Uint8
|
|||||||
sizeof(iconPixels),
|
sizeof(iconPixels),
|
||||||
iconPixels
|
iconPixels
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
|
|
||||||
xcb_free_gc(m_connection, iconGC);
|
xcb_free_gc(m_connection, iconGC);
|
||||||
|
|
||||||
if (errptr)
|
if (errptr)
|
||||||
{
|
{
|
||||||
err() << "Failed to set the window's icon: Error code " << static_cast<int>(errptr->error_code) << std::endl;
|
err() << "Failed to set the window's icon: Error code " << static_cast<int>(errptr->error_code) << std::endl;
|
||||||
free(errptr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,14 +668,15 @@ 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
|
||||||
xcb_get_window_attributes_reply_t* attributes = xcb_get_window_attributes_reply(
|
ScopedXcbPtr<xcb_get_window_attributes_reply_t> attributes(xcb_get_window_attributes_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_get_window_attributes(
|
xcb_get_window_attributes(
|
||||||
m_connection,
|
m_connection,
|
||||||
m_window
|
m_window
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (!attributes)
|
if (!attributes)
|
||||||
{
|
{
|
||||||
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;
|
||||||
@ -694,7 +684,6 @@ void WindowImplX11::requestFocus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool windowViewable = (attributes->map_state == XCB_MAP_STATE_VIEWABLE);
|
bool windowViewable = (attributes->map_state == XCB_MAP_STATE_VIEWABLE);
|
||||||
free(attributes);
|
|
||||||
|
|
||||||
if (sfmlWindowFocused && windowViewable)
|
if (sfmlWindowFocused && windowViewable)
|
||||||
{
|
{
|
||||||
@ -729,18 +718,15 @@ void WindowImplX11::requestFocus()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool WindowImplX11::hasFocus() const
|
bool WindowImplX11::hasFocus() const
|
||||||
{
|
{
|
||||||
xcb_get_input_focus_reply_t* reply = xcb_get_input_focus_reply(
|
ScopedXcbPtr<xcb_get_input_focus_reply_t> reply(xcb_get_input_focus_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_get_input_focus_unchecked(
|
xcb_get_input_focus_unchecked(
|
||||||
m_connection
|
m_connection
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
bool focused = (reply->focus == m_window);
|
return (reply->focus == m_window);
|
||||||
free(reply);
|
|
||||||
|
|
||||||
return focused;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -749,7 +735,7 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
|||||||
{
|
{
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
static const std::string RANDR = "RANDR";
|
static const std::string RANDR = "RANDR";
|
||||||
xcb_query_extension_reply_t* randr_ext = xcb_query_extension_reply(
|
ScopedXcbPtr<xcb_query_extension_reply_t> randr_ext(xcb_query_extension_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_query_extension(
|
xcb_query_extension(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -757,20 +743,20 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
|||||||
RANDR.c_str()
|
RANDR.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (randr_ext->present)
|
if (randr_ext->present)
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
xcb_generic_error_t* error;
|
ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_randr_get_screen_info(
|
xcb_randr_get_screen_info(
|
||||||
m_connection,
|
m_connection,
|
||||||
m_screen->root
|
m_screen->root
|
||||||
),
|
),
|
||||||
&error
|
&error
|
||||||
);
|
));
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@ -778,7 +764,7 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
|||||||
m_oldVideoMode = config->sizeID;
|
m_oldVideoMode = config->sizeID;
|
||||||
|
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config);
|
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
|
||||||
if (sizes && (config->nSizes > 0))
|
if (sizes && (config->nSizes > 0))
|
||||||
{
|
{
|
||||||
// Search a matching size
|
// Search a matching size
|
||||||
@ -810,18 +796,12 @@ void WindowImplX11::switchToFullscreen(const VideoMode& mode)
|
|||||||
// Failed to get the screen configuration
|
// Failed to get the screen configuration
|
||||||
err() << "Failed to get the current screen configuration for fullscreen mode, switching to window mode" << std::endl;
|
err() << "Failed to get the current screen configuration for fullscreen mode, switching to window mode" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
free(error);
|
|
||||||
free(config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// XRandR extension is not supported: we cannot use fullscreen mode
|
// XRandR extension is not supported: we cannot use fullscreen mode
|
||||||
err() << "Fullscreen is not supported, switching to window mode" << std::endl;
|
err() << "Fullscreen is not supported, switching to window mode" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(randr_ext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -830,7 +810,7 @@ void WindowImplX11::initialize()
|
|||||||
{
|
{
|
||||||
// Get the atoms for registering the close event
|
// Get the atoms for registering the close event
|
||||||
static const std::string WM_DELETE_WINDOW_NAME = "WM_DELETE_WINDOW";
|
static const std::string WM_DELETE_WINDOW_NAME = "WM_DELETE_WINDOW";
|
||||||
xcb_intern_atom_reply_t* deleteWindowAtomReply = xcb_intern_atom_reply(
|
ScopedXcbPtr<xcb_intern_atom_reply_t> deleteWindowAtomReply(xcb_intern_atom_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_intern_atom(
|
xcb_intern_atom(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -839,10 +819,10 @@ void WindowImplX11::initialize()
|
|||||||
WM_DELETE_WINDOW_NAME.c_str()
|
WM_DELETE_WINDOW_NAME.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
static const std::string WM_PROTOCOLS_NAME = "WM_PROTOCOLS";
|
static const std::string WM_PROTOCOLS_NAME = "WM_PROTOCOLS";
|
||||||
xcb_intern_atom_reply_t* protocolsAtomReply = xcb_intern_atom_reply(
|
ScopedXcbPtr<xcb_intern_atom_reply_t> protocolsAtomReply(xcb_intern_atom_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_intern_atom(
|
xcb_intern_atom(
|
||||||
m_connection,
|
m_connection,
|
||||||
@ -851,7 +831,7 @@ void WindowImplX11::initialize()
|
|||||||
WM_PROTOCOLS_NAME.c_str()
|
WM_PROTOCOLS_NAME.c_str()
|
||||||
),
|
),
|
||||||
NULL
|
NULL
|
||||||
);
|
));
|
||||||
|
|
||||||
if (protocolsAtomReply && deleteWindowAtomReply)
|
if (protocolsAtomReply && deleteWindowAtomReply)
|
||||||
{
|
{
|
||||||
@ -871,9 +851,6 @@ void WindowImplX11::initialize()
|
|||||||
std::cerr << "Failed to request WM_PROTOCOLS/WM_DELETE_WINDOW_NAME atoms." << std::endl;
|
std::cerr << "Failed to request WM_PROTOCOLS/WM_DELETE_WINDOW_NAME atoms." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(protocolsAtomReply);
|
|
||||||
free(deleteWindowAtomReply);
|
|
||||||
|
|
||||||
// Create the input context
|
// Create the input context
|
||||||
m_inputMethod = XOpenIM(m_display, NULL, NULL, NULL);
|
m_inputMethod = XOpenIM(m_display, NULL, NULL, NULL);
|
||||||
|
|
||||||
@ -945,15 +922,15 @@ void WindowImplX11::cleanup()
|
|||||||
if (fullscreenWindow == this)
|
if (fullscreenWindow == this)
|
||||||
{
|
{
|
||||||
// Get current screen info
|
// Get current screen info
|
||||||
xcb_generic_error_t* error;
|
ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
xcb_randr_get_screen_info_reply_t* config = xcb_randr_get_screen_info_reply(
|
ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
|
||||||
m_connection,
|
m_connection,
|
||||||
xcb_randr_get_screen_info(
|
xcb_randr_get_screen_info(
|
||||||
m_connection,
|
m_connection,
|
||||||
m_screen->root
|
m_screen->root
|
||||||
),
|
),
|
||||||
&error
|
&error
|
||||||
);
|
));
|
||||||
|
|
||||||
if (!error)
|
if (!error)
|
||||||
{
|
{
|
||||||
@ -969,10 +946,6 @@ void WindowImplX11::cleanup()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the configuration instance
|
|
||||||
free(error);
|
|
||||||
free(config);
|
|
||||||
|
|
||||||
// Reset the fullscreen window
|
// Reset the fullscreen window
|
||||||
fullscreenWindow = NULL;
|
fullscreenWindow = NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user