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)
set(SRC
${SRC}
${SRCROOT}/Linux/Display.cpp
${SRCROOT}/Linux/Display.hpp
${SRCROOT}/Linux/GlxContext.cpp
${SRCROOT}/Linux/GlxContext.hpp
${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
#include <SFML/Window/Linux/GlxContext.hpp>
#include <SFML/Window/Linux/WindowImplX11.hpp>
#include <SFML/Window/Linux/Display.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Window/glext/glxext.h>
#include <SFML/System/Err.hpp>
@ -40,11 +41,10 @@ namespace priv
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared) :
m_window (0),
m_context (NULL),
m_ownsWindow(true)
m_context(NULL)
{
// Open a connection with the X server
m_display = XOpenDisplay(NULL);
m_display = OpenDisplay();
// Create a dummy window (disabled and hidden)
int screen = DefaultScreen(m_display);
@ -66,11 +66,11 @@ m_ownsWindow(true)
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
m_window (0),
m_context (NULL),
m_ownsWindow(false)
m_context(NULL)
{
// Use the same display as the owner window (important!)
m_display = static_cast<const WindowImplX11*>(owner)->getDisplay();
// Open a connection with the X server
// (important: must be the same display as the owner window)
m_display = OpenDisplay();
// Get the owner window and its device context
m_window = static_cast< ::Window>(owner->getSystemHandle());
@ -84,11 +84,10 @@ m_ownsWindow(false)
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
m_window (0),
m_context (NULL),
m_ownsWindow(true)
m_context(NULL)
{
// Open a connection with the X server
m_display = XOpenDisplay(NULL);
m_display = OpenDisplay();
// Create the hidden window
int screen = DefaultScreen(m_display);
@ -119,15 +118,14 @@ GlxContext::~GlxContext()
}
// Destroy the window if we own it
if (m_window && m_ownsWindow)
if (m_window)
{
XDestroyWindow(m_display, m_window);
XFlush(m_display);
}
// Close the connection with the X server
if (m_ownsWindow)
XCloseDisplay(m_display);
CloseDisplay(m_display);
}

View File

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

View File

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

View File

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

View File

@ -71,16 +71,6 @@ public :
////////////////////////////////////////////////////////////
~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
///