All windows and contexts now use the same X display (Linux)

This commit is contained in:
Laurent Gomila 2012-09-18 22:45:29 +02:00
parent 2308c5a627
commit b75e340dc0
8 changed files with 215 additions and 85 deletions

View File

@ -51,6 +51,8 @@ if(WINDOWS)
elseif(LINUX) elseif(LINUX)
set(SRC set(SRC
${SRC} ${SRC}
${SRCROOT}/Linux/Display.cpp
${SRCROOT}/Linux/Display.hpp
${SRCROOT}/Linux/GlxContext.cpp ${SRCROOT}/Linux/GlxContext.cpp
${SRCROOT}/Linux/GlxContext.hpp ${SRCROOT}/Linux/GlxContext.hpp
${SRCROOT}/Linux/InputImpl.cpp ${SRCROOT}/Linux/InputImpl.cpp

View File

@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2012 Laurent Gomila (laurent.gom@gmail.com)
//
// 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.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Linux/Display.hpp>
#include <cassert>
namespace
{
// The shared display and its reference counter
Display* sharedDisplay = NULL;
unsigned int referenceCount = 0;
}
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
Display* OpenDisplay()
{
if (referenceCount == 0)
sharedDisplay = XOpenDisplay(NULL);
referenceCount++;
return sharedDisplay;
}
////////////////////////////////////////////////////////////
void CloseDisplay(Display* display)
{
assert(display == sharedDisplay);
referenceCount--;
if (referenceCount == 0)
XCloseDisplay(display);
}
} // namespace priv
} // namespace sf

View File

@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2012 Laurent Gomila (laurent.gom@gmail.com)
//
// 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_SHAREDDISPLAY_HPP
#define SFML_SHAREDDISPLAY_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <X11/Xlib.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Get the shared Display
///
/// This function increments the reference count of the display,
/// it must be matched with a call to CloseDisplay.
///
/// \return Pointer to the shared display
///
////////////////////////////////////////////////////////////
Display* OpenDisplay();
////////////////////////////////////////////////////////////
/// \brief Release a reference to the shared
///
/// \param display Display to release
///
////////////////////////////////////////////////////////////
void CloseDisplay(Display* display);
} // namespace priv
} // namespace sf
#endif // SFML_SHAREDDISPLAY_HPP

View File

@ -28,6 +28,7 @@
#define GLX_GLXEXT_LEGACY // so that our local glxext.h is used instead of the system one #define GLX_GLXEXT_LEGACY // so that our local glxext.h is used instead of the system one
#include <SFML/Window/Linux/GlxContext.hpp> #include <SFML/Window/Linux/GlxContext.hpp>
#include <SFML/Window/Linux/WindowImplX11.hpp> #include <SFML/Window/Linux/WindowImplX11.hpp>
#include <SFML/Window/Linux/Display.hpp>
#include <SFML/OpenGL.hpp> #include <SFML/OpenGL.hpp>
#include <SFML/Window/glext/glxext.h> #include <SFML/Window/glext/glxext.h>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
@ -39,12 +40,11 @@ namespace priv
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared) : GlxContext::GlxContext(GlxContext* shared) :
m_window (0), m_window (0),
m_context (NULL), m_context(NULL)
m_ownsWindow(true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = XOpenDisplay(NULL); m_display = OpenDisplay();
// Create a dummy window (disabled and hidden) // Create a dummy window (disabled and hidden)
int screen = DefaultScreen(m_display); int screen = DefaultScreen(m_display);
@ -65,12 +65,12 @@ m_ownsWindow(true)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
m_window (0), m_window (0),
m_context (NULL), m_context(NULL)
m_ownsWindow(false)
{ {
// Use the same display as the owner window (important!) // Open a connection with the X server
m_display = static_cast<const WindowImplX11*>(owner)->getDisplay(); // (important: must be the same display as the owner window)
m_display = OpenDisplay();
// Get the owner window and its device context // Get the owner window and its device context
m_window = static_cast< ::Window>(owner->getSystemHandle()); m_window = static_cast< ::Window>(owner->getSystemHandle());
@ -83,12 +83,11 @@ m_ownsWindow(false)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) : GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
m_window (0), m_window (0),
m_context (NULL), m_context(NULL)
m_ownsWindow(true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = XOpenDisplay(NULL); m_display = OpenDisplay();
// Create the hidden window // Create the hidden window
int screen = DefaultScreen(m_display); int screen = DefaultScreen(m_display);
@ -119,15 +118,14 @@ GlxContext::~GlxContext()
} }
// Destroy the window if we own it // Destroy the window if we own it
if (m_window && m_ownsWindow) if (m_window)
{ {
XDestroyWindow(m_display, m_window); XDestroyWindow(m_display, m_window);
XFlush(m_display); XFlush(m_display);
} }
// Close the connection with the X server // Close the connection with the X server
if (m_ownsWindow) CloseDisplay(m_display);
XCloseDisplay(m_display);
} }

View File

@ -27,34 +27,11 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/Linux/InputImpl.hpp> #include <SFML/Window/Linux/InputImpl.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Window/Window.hpp>
#include <SFML/Window/Linux/Display.hpp>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
namespace
{
// Open, store and close a X display
struct GlobalDisplay
{
GlobalDisplay()
{
display = XOpenDisplay(NULL);
window = DefaultRootWindow(display);
}
~GlobalDisplay()
{
XCloseDisplay(display);
}
::Display* display;
::Window window;
};
// Global connection with the X server, used in global input functions
GlobalDisplay global;
}
namespace sf namespace sf
{ {
namespace priv namespace priv
@ -170,32 +147,49 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
default: keysym = 0; break; default: keysym = 0; break;
} }
// Open a connection with the X server
Display* display = OpenDisplay();
// Convert to keycode // Convert to keycode
KeyCode keycode = XKeysymToKeycode(global.display, keysym); KeyCode keycode = XKeysymToKeycode(display, keysym);
if (keycode != 0) if (keycode != 0)
{ {
// Get the whole keyboard state // Get the whole keyboard state
char keys[32]; char keys[32];
XQueryKeymap(global.display, keys); XQueryKeymap(display, keys);
// Close the connection with the X server
CloseDisplay(display);
// Check our keycode // Check our keycode
return (keys[keycode / 8] & (1 << (keycode % 8))) != 0; return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
} }
else
{
// Close the connection with the X server
CloseDisplay(display);
return false; return false;
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool InputImpl::isMouseButtonPressed(Mouse::Button button) bool InputImpl::isMouseButtonPressed(Mouse::Button button)
{ {
// Open a connection with the X server
Display* display = OpenDisplay();
// we don't care about these but they are required // we don't care about these but they are required
::Window root, child; ::Window root, child;
int wx, wy; int wx, wy;
int gx, gy; int gx, gy;
unsigned int buttons = 0; unsigned int buttons = 0;
XQueryPointer(global.display, global.window, &root, &child, &gx, &gy, &wx, &wy, &buttons); XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &wx, &wy, &buttons);
// Close the connection with the X server
CloseDisplay(display);
switch (button) switch (button)
{ {
@ -214,6 +208,9 @@ bool InputImpl::isMouseButtonPressed(Mouse::Button button)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Vector2i InputImpl::getMousePosition() Vector2i InputImpl::getMousePosition()
{ {
// Open a connection with the X server
Display* display = OpenDisplay();
// we don't care about these but they are required // we don't care about these but they are required
::Window root, child; ::Window root, child;
int x, y; int x, y;
@ -221,7 +218,10 @@ Vector2i InputImpl::getMousePosition()
int gx = 0; int gx = 0;
int gy = 0; int gy = 0;
XQueryPointer(global.display, global.window, &root, &child, &gx, &gy, &x, &y, &buttons); XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &x, &y, &buttons);
// Close the connection with the X server
CloseDisplay(display);
return Vector2i(gx, gy); return Vector2i(gx, gy);
} }
@ -233,6 +233,9 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
WindowHandle handle = relativeTo.getSystemHandle(); WindowHandle handle = relativeTo.getSystemHandle();
if (handle) if (handle)
{ {
// Open a connection with the X server
Display* display = OpenDisplay();
// we don't care about these but they are required // we don't care about these but they are required
::Window root, child; ::Window root, child;
int gx, gy; int gx, gy;
@ -240,7 +243,10 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
int x = 0; int x = 0;
int y = 0; int y = 0;
XQueryPointer(global.display, handle, &root, &child, &gx, &gy, &x, &y, &buttons); XQueryPointer(display, handle, &root, &child, &gx, &gy, &x, &y, &buttons);
// Close the connection with the X server
CloseDisplay(display);
return Vector2i(x, y); return Vector2i(x, y);
} }
@ -254,20 +260,32 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void InputImpl::setMousePosition(const Vector2i& position) void InputImpl::setMousePosition(const Vector2i& position)
{ {
XWarpPointer(global.display, None, global.window, 0, 0, 0, 0, position.x, position.y); // Open a connection with the X server
XFlush(global.display); Display* display = OpenDisplay();
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, position.x, position.y);
XFlush(display);
// Close the connection with the X server
CloseDisplay(display);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo) void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo)
{ {
// Open a connection with the X server
Display* display = OpenDisplay();
WindowHandle handle = relativeTo.getSystemHandle(); WindowHandle handle = relativeTo.getSystemHandle();
if (handle) if (handle)
{ {
XWarpPointer(global.display, None, handle, 0, 0, 0, 0, position.x, position.y); XWarpPointer(display, None, handle, 0, 0, 0, 0, position.x, position.y);
XFlush(global.display); XFlush(display);
} }
// Close the connection with the X server
CloseDisplay(display);
} }
} // namespace priv } // namespace priv

View File

@ -26,6 +26,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/VideoModeImpl.hpp> #include <SFML/Window/VideoModeImpl.hpp>
#include <SFML/Window/Linux/Display.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
@ -42,18 +43,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* disp = XOpenDisplay(NULL); Display* display = OpenDisplay();
if (disp) if (display)
{ {
// Retrieve the default screen number // Retrieve the default screen number
int screen = DefaultScreen(disp); int screen = DefaultScreen(display);
// Check if the XRandR extension is present // Check if the XRandR extension is present
int version; int version;
if (XQueryExtension(disp, "RANDR", &version, &version, &version)) if (XQueryExtension(display, "RANDR", &version, &version, &version))
{ {
// Get the current configuration // Get the current configuration
XRRScreenConfiguration* config = XRRGetScreenInfo(disp, RootWindow(disp, screen)); XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
if (config) if (config)
{ {
// Get the available screen sizes // Get the available screen sizes
@ -63,7 +64,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{ {
// Get the list of supported depths // Get the list of supported depths
int nbDepths = 0; int nbDepths = 0;
int* depths = XListDepths(disp, screen, &nbDepths); int* depths = XListDepths(display, screen, &nbDepths);
if (depths && (nbDepths > 0)) if (depths && (nbDepths > 0))
{ {
// Combine depths and sizes to fill the array of supported modes // Combine depths and sizes to fill the array of supported modes
@ -101,7 +102,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
} }
// Close the connection with the X server // Close the connection with the X server
XCloseDisplay(disp); CloseDisplay(display);
} }
else else
{ {
@ -119,18 +120,18 @@ VideoMode VideoModeImpl::getDesktopMode()
VideoMode desktopMode; VideoMode desktopMode;
// Open a connection with the X server // Open a connection with the X server
Display* disp = XOpenDisplay(NULL); Display* display = OpenDisplay();
if (disp) if (display)
{ {
// Retrieve the default screen number // Retrieve the default screen number
int screen = DefaultScreen(disp); int screen = DefaultScreen(display);
// Check if the XRandR extension is present // Check if the XRandR extension is present
int version; int version;
if (XQueryExtension(disp, "RANDR", &version, &version, &version)) if (XQueryExtension(display, "RANDR", &version, &version, &version))
{ {
// Get the current configuration // Get the current configuration
XRRScreenConfiguration* config = XRRGetScreenInfo(disp, RootWindow(disp, screen)); XRRScreenConfiguration* config = XRRGetScreenInfo(display, RootWindow(display, screen));
if (config) if (config)
{ {
// Get the current video mode // Get the current video mode
@ -141,7 +142,7 @@ VideoMode VideoModeImpl::getDesktopMode()
int nbSizes; int nbSizes;
XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes); XRRScreenSize* sizes = XRRConfigSizes(config, &nbSizes);
if (sizes && (nbSizes > 0)) if (sizes && (nbSizes > 0))
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, DefaultDepth(disp, screen)); desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, DefaultDepth(display, screen));
// Free the configuration instance // Free the configuration instance
XRRFreeScreenConfigInfo(config); XRRFreeScreenConfigInfo(config);
@ -159,7 +160,7 @@ VideoMode VideoModeImpl::getDesktopMode()
} }
// Close the connection with the X server // Close the connection with the X server
XCloseDisplay(disp); CloseDisplay(display);
} }
else else
{ {

View File

@ -27,6 +27,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/Linux/WindowImplX11.hpp> #include <SFML/Window/Linux/WindowImplX11.hpp>
#include <SFML/Window/Linux/Display.hpp>
#include <SFML/System/Utf.hpp> #include <SFML/System/Utf.hpp>
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -72,7 +73,7 @@ m_hiddenCursor(0),
m_keyRepeat (true) m_keyRepeat (true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = XOpenDisplay(NULL); m_display = OpenDisplay();
m_screen = DefaultScreen(m_display); m_screen = DefaultScreen(m_display);
// Save the window handle // Save the window handle
@ -101,7 +102,7 @@ m_hiddenCursor(0),
m_keyRepeat (true) m_keyRepeat (true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = XOpenDisplay(NULL); m_display = OpenDisplay();
m_screen = DefaultScreen(m_display); m_screen = DefaultScreen(m_display);
// Compute position and size // Compute position and size
@ -255,14 +256,7 @@ WindowImplX11::~WindowImplX11()
XCloseIM(m_inputMethod); XCloseIM(m_inputMethod);
// Close the connection with the X server // Close the connection with the X server
XCloseDisplay(m_display); CloseDisplay(m_display);
}
////////////////////////////////////////////////////////////
::Display* WindowImplX11::getDisplay() const
{
return m_display;
} }

View File

@ -71,16 +71,6 @@ public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~WindowImplX11(); ~WindowImplX11();
////////////////////////////////////////////////////////////
/// \brief Get the display used by the window
///
/// This functions is meant to be used internally by ContextGLX.
///
/// \return Pointer to the X display of the window
///
////////////////////////////////////////////////////////////
::Display* getDisplay() const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the OS-specific handle of the window /// \brief Get the OS-specific handle of the window
/// ///