Permalink
Browse files

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

  • Loading branch information...
1 parent 2308c5a commit b75e340dc05e5d127a3b6890fe6bf7053b690efd @LaurentGomila LaurentGomila committed Sep 18, 2012
@@ -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
@@ -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
@@ -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
@@ -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>
@@ -39,12 +40,11 @@ namespace priv
{
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared) :
-m_window (0),
-m_context (NULL),
-m_ownsWindow(true)
+m_window (0),
+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);
@@ -65,12 +65,12 @@ 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_window (0),
+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());
@@ -83,12 +83,11 @@ 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_window (0),
+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);
}
@@ -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;
+ 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,14 +208,20 @@ 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;
unsigned int buttons;
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,14 +233,20 @@ 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;
unsigned int buttons;
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
Oops, something went wrong.

0 comments on commit b75e340

Please sign in to comment.