mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 12:51:05 +08:00
All windows and contexts now use the same X display (Linux)
This commit is contained in:
parent
2308c5a627
commit
b75e340dc0
@ -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
|
||||
|
65
src/SFML/Window/Linux/Display.cpp
Normal file
65
src/SFML/Window/Linux/Display.cpp
Normal 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
|
62
src/SFML/Window/Linux/Display.hpp
Normal file
62
src/SFML/Window/Linux/Display.hpp
Normal 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
|
@ -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,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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user