Added joystick implementation for FreeBSD (#477)

This commit is contained in:
David Demelier 2013-10-08 22:40:11 +02:00 committed by Laurent Gomila
parent 713aed7079
commit cc3dc29ef4
19 changed files with 1043 additions and 527 deletions

View File

@ -15,9 +15,10 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
endif() endif()
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LINUX 1) set(LINUX 1)
set(UNIX 1)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
# FreeBSD compile path is the same as Linux set(FreeBSD 1)
set(LINUX 1) set(UNIX 1)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(MACOSX 1) set(MACOSX 1)

View File

@ -52,22 +52,33 @@ if(WINDOWS)
# make sure that we use the Unicode version of the Win API functions # make sure that we use the Unicode version of the Win API functions
add_definitions(-DUNICODE) add_definitions(-DUNICODE)
elseif(LINUX) elseif(UNIX)
set(PLATFORM_SRC set(PLATFORM_SRC
${SRCROOT}/Linux/Display.cpp ${SRCROOT}/Unix/Display.cpp
${SRCROOT}/Linux/Display.hpp ${SRCROOT}/Unix/Display.hpp
${SRCROOT}/Linux/GlxContext.cpp ${SRCROOT}/Unix/GlxContext.cpp
${SRCROOT}/Linux/GlxContext.hpp ${SRCROOT}/Unix/GlxContext.hpp
${SRCROOT}/Linux/InputImpl.cpp ${SRCROOT}/Unix/InputImpl.cpp
${SRCROOT}/Linux/InputImpl.hpp ${SRCROOT}/Unix/InputImpl.hpp
${SRCROOT}/Linux/JoystickImpl.cpp ${SRCROOT}/Unix/VideoModeImpl.cpp
${SRCROOT}/Linux/JoystickImpl.hpp ${SRCROOT}/Unix/WindowImplX11.cpp
${SRCROOT}/Linux/VideoModeImpl.cpp ${SRCROOT}/Unix/WindowImplX11.hpp
${SRCROOT}/Linux/WindowImplX11.cpp
${SRCROOT}/Linux/WindowImplX11.hpp
) )
source_group("linux" FILES ${PLATFORM_SRC}) if(LINUX)
else() # MACOSX set(PLATFORM_SRC
${PLATFORM_SRC}
${SRCROOT}/Unix/JoystickImpl.cpp
${SRCROOT}/Unix/JoystickImpl.hpp
)
elseif(FREEBSD)
set(PLATFORM_SRC
${PLATFORM_SRC}
${SRCROOT}/FreeBSD/JoystickImpl.cpp
${SRCROOT}/FreeBSD/JoystickImpl.hpp
)
endif()
source_group("unix" FILES ${PLATFORM_SRC})
elseif(MACOSX)
set(PLATFORM_SRC set(PLATFORM_SRC
${SRCROOT}/OSX/cpp_objc_conversion.h ${SRCROOT}/OSX/cpp_objc_conversion.h
${SRCROOT}/OSX/cpp_objc_conversion.mm ${SRCROOT}/OSX/cpp_objc_conversion.mm
@ -126,6 +137,9 @@ if(WINDOWS)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32) set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32)
elseif(LINUX) elseif(LINUX)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB}) set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
if(FREEBSD)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} usbhid)
endif()
elseif(MACOSX) elseif(MACOSX)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit -framework IOKit -framework Carbon") set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit -framework IOKit -framework Carbon")
endif() endif()

View File

@ -0,0 +1,380 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
// 2013-2013 David Demelier (demelier.david@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/JoystickImpl.hpp>
#include <SFML/System/Err.hpp>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <map>
#include <string>
#include <utility>
////////////////////////////////////////////////////////////
/// \brief This file implements FreeBSD driver joystick
///
/// It has been tested on a Saitek gamepad with 12 buttons,
/// 2 analog axis and one hat.
///
/// Note: old joy(4) drivers are not supported and no one use that
/// anymore.
////////////////////////////////////////////////////////////
namespace
{
std::map<unsigned int, std::string> plugged;
std::map<int, std::pair<int, int> > hatmap;
bool isJoystick(const char *name)
{
int fd, id;
bool ret;
report_desc_t desc = NULL;
hid_data_t data = NULL;
hid_item_t item;
// Assume it isn't
ret = false;
if ((fd = ::open(name, O_RDONLY | O_NONBLOCK)) < 0)
return false;
if ((desc = hid_get_report_desc(fd)) == NULL)
goto end;
id = hid_get_report_id(fd);
if ((data = hid_start_parse(desc, 1 << hid_input, id)) == NULL)
goto end;
while (hid_get_item(data, &item) > 0) {
switch (item.kind) {
case hid_collection:
switch (HID_PAGE(item.usage)) {
case HUP_GENERIC_DESKTOP:
switch (HID_USAGE(item.usage)) {
case HUG_JOYSTICK:
case HUG_GAME_PAD:
ret = true;
break;
default:
break;
}
default:
break;
}
default:
break;
}
}
end:
if (desc != NULL)
hid_dispose_report_desc(desc);
if (data != NULL)
hid_end_parse(data);
close(fd);
return ret;
}
void updatePluggedList()
{
DIR *dp;
struct dirent *entry;
/*
* Devices /dev/uhid<x> are shared between joystick and any other
* human interface device. We need to iterate over all found devices
* and check if they are joysticks. The index of JoystickImpl::open
* does not match the /dev/uhid<index> device!
*/
if ((dp = opendir("/dev")) != NULL) {
char name[FILENAME_MAX];
int jc = 0;
while ((entry = readdir(dp)) != NULL && jc < sf::Joystick::Count) {
if (strncmp(entry->d_name, "uhid", 4) == 0) {
std::sprintf(name, "/dev/%s", entry->d_name);
if (isJoystick(name))
plugged[jc++] = std::string(name);
}
}
closedir(dp);
}
}
int usageToAxis(int usage)
{
int axis;
switch (usage) {
case HUG_X:
axis = sf::Joystick::X;
break;
case HUG_Y:
axis = sf::Joystick::Y;
break;
case HUG_Z:
axis = sf::Joystick::Z;
break;
case HUG_RZ:
axis = sf::Joystick::R;
break;
case HUG_RX:
axis = sf::Joystick::U;
break;
case HUG_RY:
axis = sf::Joystick::V;
break;
default:
axis = -1;
break;
}
return axis;
}
void hatvalToSFML(int value, sf::priv::JoystickState &state)
{
state.axes[sf::Joystick::PovX] = hatmap[value].first;
state.axes[sf::Joystick::PovY] = hatmap[value].second;
}
}
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
void JoystickImpl::initialize()
{
hid_init(NULL);
// Do an initial scan
updatePluggedList();
// Map of hat values
hatmap[0] = std::make_pair<int, int>(0, 0); // center
hatmap[1] = std::make_pair<int, int>(0, -100); // top
hatmap[3] = std::make_pair<int, int>(100, 0); // right
hatmap[5] = std::make_pair<int, int>(0, 100); // bottom
hatmap[7] = std::make_pair<int, int>(-100, 0); // left
hatmap[2] = std::make_pair<int, int>(100, -100); // top-right
hatmap[4] = std::make_pair<int, int>(100, 100); // bottom-right
hatmap[6] = std::make_pair<int, int>(-100, 100); // bottom-left
hatmap[8] = std::make_pair<int, int>(-100, -100); // top-left
}
////////////////////////////////////////////////////////////
void JoystickImpl::cleanup()
{
}
////////////////////////////////////////////////////////////
bool JoystickImpl::isConnected(unsigned int index)
{
return plugged.find(index) != plugged.end();
}
////////////////////////////////////////////////////////////
bool JoystickImpl::open(unsigned int index)
{
if (isConnected(index))
{
// Open the joystick's file descriptor (read-only and non-blocking)
m_file = ::open(plugged[index].c_str(), O_RDONLY | O_NONBLOCK);
if (m_file >= 0)
{
// Reset the joystick state
m_state = JoystickState();
// Get the report descriptor
m_desc = hid_get_report_desc(m_file);
if (m_desc == NULL) {
::close(m_file);
return false;
}
// And the id
m_id = hid_get_report_id(m_file);
// Then allocate a buffer for data retrievement
m_length = hid_report_size(m_desc, hid_input, m_id);
m_buffer = std::calloc(1, m_length);
if (m_buffer == NULL) {
::close(m_file);
::hid_dispose_report_desc(m_desc);
return false;
}
return m_state.connected = true;
}
else
{
return false;
}
}
else
{
return false;
}
}
////////////////////////////////////////////////////////////
void JoystickImpl::close()
{
::close(m_file);
::hid_dispose_report_desc(m_desc);
::free(m_buffer);
}
////////////////////////////////////////////////////////////
JoystickCaps JoystickImpl::getCapabilities() const
{
JoystickCaps caps;
hid_data_t data;
hid_item_t item;
data = hid_start_parse(m_desc, 1 << hid_input, m_id);
while (hid_get_item(data, &item)) {
switch (item.kind) {
case hid_input:
switch (HID_PAGE(item.usage)) {
case HUP_BUTTON:
caps.buttonCount ++;
break;
case HUP_GENERIC_DESKTOP:
{
int usage = HID_USAGE(item.usage);
int axis;
if (usage == HUG_HAT_SWITCH) {
caps.axes[Joystick::PovX] = true;
caps.axes[Joystick::PovY] = true;
}
else if ((axis = usageToAxis(usage)) != -1)
{
caps.axes[axis] = true;
}
break;
}
default:
break;
}
default:
break;
}
}
hid_end_parse(data);
return caps;
}
////////////////////////////////////////////////////////////
JoystickState JoystickImpl::JoystickImpl::update()
{
while (read(m_file, m_buffer, m_length) == m_length) {
hid_data_t data;
hid_item_t item;
data = hid_start_parse(m_desc, 1 << hid_input, m_id);
// No memory?
if (data == NULL)
continue;
int but = 0;
while (hid_get_item(data, &item)) {
switch (item.kind) {
case hid_input:
switch (HID_PAGE(item.usage)) {
case HUP_BUTTON:
m_state.buttons[but++] = hid_get_data(m_buffer, &item);
break;
case HUP_GENERIC_DESKTOP:
{
int usage = HID_USAGE(item.usage);
int v = hid_get_data(m_buffer, &item);
int axis;
if (usage == HUG_HAT_SWITCH)
hatvalToSFML(v, m_state);
else if ((axis = usageToAxis(usage)) != -1)
{
int &min = item.logical_minimum;
int &max = item.logical_maximum;
v = (v - min) * (200) / (max - min) -100;
m_state.axes[axis] = v;
}
break;
}
default:
break;
}
default:
break;
}
}
hid_end_parse(data);
}
return m_state;
}
} // namespace priv
} // namespace sf
// vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:

View File

@ -0,0 +1,123 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 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_JOYSTICKIMPLFREEBSD_HPP
#define SFML_JOYSTICKIMPLFREEBSD_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <dev/usb/usbhid.h>
#include <usbhid.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief FreeBSD implementation of joysticks
///
/// This code has been tested on FreeBSD 9.1 only.
////////////////////////////////////////////////////////////
class JoystickImpl
{
public :
////////////////////////////////////////////////////////////
/// \brief Perform the global initialization of the joystick module
///
////////////////////////////////////////////////////////////
static void initialize();
////////////////////////////////////////////////////////////
/// \brief Perform the global cleanup of the joystick module
///
////////////////////////////////////////////////////////////
static void cleanup();
////////////////////////////////////////////////////////////
/// \brief Check if a joystick is currently connected
///
/// \param index Index of the joystick to check
///
/// \return True if the joystick is connected, false otherwise
///
////////////////////////////////////////////////////////////
static bool isConnected(unsigned int index);
////////////////////////////////////////////////////////////
/// \brief Open the joystick
///
/// \param index Index assigned to the joystick
///
/// \return True on success, false on failure
///
////////////////////////////////////////////////////////////
bool open(unsigned int index);
////////////////////////////////////////////////////////////
/// \brief Close the joystick
///
////////////////////////////////////////////////////////////
void close();
////////////////////////////////////////////////////////////
/// \brief Get the joystick capabilities
///
/// \return Joystick capabilities
///
////////////////////////////////////////////////////////////
JoystickCaps getCapabilities() const;
////////////////////////////////////////////////////////////
/// \brief Update the joystick and get its new state
///
/// \return Joystick state
///
////////////////////////////////////////////////////////////
JoystickState update();
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
int m_file; ///< File descriptor of the joystick
report_desc_t m_desc; ///< USB report descriptor
int m_id; ///< USB id
void *m_buffer; ///< USB HID buffer
int m_length; ///< Buffer length
JoystickState m_state; ///< Current state of the joystick
};
} // namespace priv
} // namespace sf
#endif // SFML_JOYSTICKIMPLFREEBSD_HPP

View File

@ -43,7 +43,7 @@
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/GlxContext.hpp> #include <SFML/Window/Unix/GlxContext.hpp>
typedef sf::priv::GlxContext ContextType; typedef sf::priv::GlxContext ContextType;
#elif defined(SFML_SYSTEM_MACOS) #elif defined(SFML_SYSTEM_MACOS)

View File

@ -33,7 +33,7 @@
#if defined(SFML_SYSTEM_WINDOWS) #if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/Window/Win32/InputImpl.hpp> #include <SFML/Window/Win32/InputImpl.hpp>
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/InputImpl.hpp> #include <SFML/Window/Unix/InputImpl.hpp>
#elif defined(SFML_SYSTEM_MACOS) #elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/OSX/InputImpl.hpp> #include <SFML/Window/OSX/InputImpl.hpp>
#endif #endif

View File

@ -79,8 +79,10 @@ struct JoystickState
#if defined(SFML_SYSTEM_WINDOWS) #if defined(SFML_SYSTEM_WINDOWS)
#include <SFML/Window/Win32/JoystickImpl.hpp> #include <SFML/Window/Win32/JoystickImpl.hpp>
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) #elif defined(SFML_SYSTEM_LINUX)
#include <SFML/Window/Linux/JoystickImpl.hpp> #include <SFML/Window/Unix/JoystickImpl.hpp>
#elif defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/FreeBSD/JoystickImpl.hpp>
#elif defined(SFML_SYSTEM_MACOS) #elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/OSX/JoystickImpl.hpp> #include <SFML/Window/OSX/JoystickImpl.hpp>
#endif #endif

View File

@ -25,7 +25,7 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/Linux/Display.hpp> #include <SFML/Window/Unix/Display.hpp>
#include <cassert> #include <cassert>

View File

@ -1,343 +1,343 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // 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. // 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, // Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely, // including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions: // subject to the following restrictions:
// //
// 1. The origin of this software must not be misrepresented; // 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software. // you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment // If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required. // in the product documentation would be appreciated but is not required.
// //
// 2. Altered source versions must be plainly marked as such, // 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software. // and must not be misrepresented as being the original software.
// //
// 3. This notice may not be removed or altered from any source distribution. // 3. This notice may not be removed or altered from any source distribution.
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#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/Unix/GlxContext.hpp>
#include <SFML/Window/Linux/WindowImplX11.hpp> #include <SFML/Window/Unix/WindowImplX11.hpp>
#include <SFML/Window/Linux/Display.hpp> #include <SFML/Window/Unix/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>
namespace sf namespace sf
{ {
namespace priv 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) m_ownsWindow(true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = OpenDisplay(); 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);
m_window = XCreateWindow(m_display, m_window = XCreateWindow(m_display,
RootWindow(m_display, screen), RootWindow(m_display, screen),
0, 0, 0, 0,
1, 1, 1, 1,
0, 0,
DefaultDepth(m_display, screen), DefaultDepth(m_display, screen),
InputOutput, InputOutput,
DefaultVisual(m_display, screen), DefaultVisual(m_display, screen),
0, NULL); 0, NULL);
// Create the context // Create the context
createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings()); createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
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) m_ownsWindow(false)
{ {
// Open a connection with the X server // Open a connection with the X server
// (important: must be the same display as the owner window) // (important: must be the same display as the owner window)
m_display = OpenDisplay(); 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());
// Create the context // Create the context
if (m_window) if (m_window)
createContext(shared, bitsPerPixel, settings); createContext(shared, bitsPerPixel, settings);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
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) m_ownsWindow(true)
{ {
// Open a connection with the X server // Open a connection with the X server
m_display = OpenDisplay(); m_display = OpenDisplay();
// Create the hidden window // Create the hidden window
int screen = DefaultScreen(m_display); int screen = DefaultScreen(m_display);
m_window = XCreateWindow(m_display, m_window = XCreateWindow(m_display,
RootWindow(m_display, screen), RootWindow(m_display, screen),
0, 0, 0, 0,
width, height, width, height,
0, 0,
DefaultDepth(m_display, screen), DefaultDepth(m_display, screen),
InputOutput, InputOutput,
DefaultVisual(m_display, screen), DefaultVisual(m_display, screen),
0, NULL); 0, NULL);
// Create the context // Create the context
createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings); createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext::~GlxContext() GlxContext::~GlxContext()
{ {
// Destroy the context // Destroy the context
if (m_context) if (m_context)
{ {
if (glXGetCurrentContext() == m_context) if (glXGetCurrentContext() == m_context)
glXMakeCurrent(m_display, None, NULL); glXMakeCurrent(m_display, None, NULL);
glXDestroyContext(m_display, m_context); glXDestroyContext(m_display, m_context);
} }
// Destroy the window if we own it // Destroy the window if we own it
if (m_window && m_ownsWindow) if (m_window && m_ownsWindow)
{ {
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
CloseDisplay(m_display); CloseDisplay(m_display);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
bool GlxContext::makeCurrent() bool GlxContext::makeCurrent()
{ {
return m_context && glXMakeCurrent(m_display, m_window, m_context); return m_context && glXMakeCurrent(m_display, m_window, m_context);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void GlxContext::display() void GlxContext::display()
{ {
if (m_window) if (m_window)
glXSwapBuffers(m_display, m_window); glXSwapBuffers(m_display, m_window);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void GlxContext::setVerticalSyncEnabled(bool enabled) void GlxContext::setVerticalSyncEnabled(bool enabled)
{ {
const GLubyte* name = reinterpret_cast<const GLubyte*>("glXSwapIntervalSGI"); const GLubyte* name = reinterpret_cast<const GLubyte*>("glXSwapIntervalSGI");
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress(name)); PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress(name));
if (glXSwapIntervalSGI) if (glXSwapIntervalSGI)
glXSwapIntervalSGI(enabled ? 1 : 0); glXSwapIntervalSGI(enabled ? 1 : 0);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings) XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings)
{ {
// Retrieve all the visuals // Retrieve all the visuals
int count; int count;
XVisualInfo* visuals = XGetVisualInfo(display, 0, NULL, &count); XVisualInfo* visuals = XGetVisualInfo(display, 0, NULL, &count);
if (visuals) if (visuals)
{ {
// Evaluate all the returned visuals, and pick the best one1 // Evaluate all the returned visuals, and pick the best one1
int bestScore = 0xFFFF; int bestScore = 0xFFFF;
XVisualInfo bestVisual; XVisualInfo bestVisual;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
// Check mandatory attributes // Check mandatory attributes
int doubleBuffer; int doubleBuffer;
glXGetConfig(display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer); glXGetConfig(display, &visuals[i], GLX_DOUBLEBUFFER, &doubleBuffer);
if (!doubleBuffer) if (!doubleBuffer)
continue; continue;
// Extract the components of the current visual // Extract the components of the current visual
int red, green, blue, alpha, depth, stencil, multiSampling, samples; int red, green, blue, alpha, depth, stencil, multiSampling, samples;
glXGetConfig(display, &visuals[i], GLX_RED_SIZE, &red); glXGetConfig(display, &visuals[i], GLX_RED_SIZE, &red);
glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE, &green); glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE, &green);
glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE, &blue); glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE, &blue);
glXGetConfig(display, &visuals[i], GLX_ALPHA_SIZE, &alpha); glXGetConfig(display, &visuals[i], GLX_ALPHA_SIZE, &alpha);
glXGetConfig(display, &visuals[i], GLX_DEPTH_SIZE, &depth); glXGetConfig(display, &visuals[i], GLX_DEPTH_SIZE, &depth);
glXGetConfig(display, &visuals[i], GLX_STENCIL_SIZE, &stencil); glXGetConfig(display, &visuals[i], GLX_STENCIL_SIZE, &stencil);
glXGetConfig(display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling); glXGetConfig(display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
glXGetConfig(display, &visuals[i], GLX_SAMPLES_ARB, &samples); glXGetConfig(display, &visuals[i], GLX_SAMPLES_ARB, &samples);
// Evaluate the visual // Evaluate the visual
int color = red + green + blue + alpha; int color = red + green + blue + alpha;
int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0); int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0);
// If it's better than the current best, make it the new best // If it's better than the current best, make it the new best
if (score < bestScore) if (score < bestScore)
{ {
bestScore = score; bestScore = score;
bestVisual = visuals[i]; bestVisual = visuals[i];
} }
} }
// Free the array of visuals // Free the array of visuals
XFree(visuals); XFree(visuals);
return bestVisual; return bestVisual;
} }
else else
{ {
// Should never happen... // Should never happen...
err() << "No GLX visual found. You should check your graphics driver" << std::endl; err() << "No GLX visual found. You should check your graphics driver" << std::endl;
return XVisualInfo(); return XVisualInfo();
} }
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings) void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
{ {
XVisualInfo* visualInfo = NULL; XVisualInfo* visualInfo = NULL;
// Save the creation settings // Save the creation settings
m_settings = settings; m_settings = settings;
// Get the context to share display lists with // Get the context to share display lists with
GLXContext toShare = shared ? shared->m_context : NULL; GLXContext toShare = shared ? shared->m_context : NULL;
// Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code) // Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code)
if (m_settings.majorVersion >= 3) if (m_settings.majorVersion >= 3)
{ {
const GLubyte* name = reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB"); const GLubyte* name = reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB");
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(name)); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(name));
if (glXCreateContextAttribsARB) if (glXCreateContextAttribsARB)
{ {
// Select a GLXFB config that matches the requested context settings // Select a GLXFB config that matches the requested context settings
int nbConfigs = 0; int nbConfigs = 0;
int fbAttributes[] = int fbAttributes[] =
{ {
GLX_DEPTH_SIZE, settings.depthBits, GLX_DEPTH_SIZE, settings.depthBits,
GLX_STENCIL_SIZE, settings.stencilBits, GLX_STENCIL_SIZE, settings.stencilBits,
GLX_SAMPLE_BUFFERS, settings.antialiasingLevel > 0, GLX_SAMPLE_BUFFERS, settings.antialiasingLevel > 0,
GLX_SAMPLES, settings.antialiasingLevel, GLX_SAMPLES, settings.antialiasingLevel,
GLX_RED_SIZE, 8, GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8, GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8, GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, bitsPerPixel == 32 ? 8 : 0, GLX_ALPHA_SIZE, bitsPerPixel == 32 ? 8 : 0,
GLX_DOUBLEBUFFER, True, GLX_DOUBLEBUFFER, True,
GLX_X_RENDERABLE, True, GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_CONFIG_CAVEAT, GLX_NONE, GLX_CONFIG_CAVEAT, GLX_NONE,
None None
}; };
GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), fbAttributes, &nbConfigs); GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), fbAttributes, &nbConfigs);
if (configs && nbConfigs) if (configs && nbConfigs)
{ {
while (!m_context && (m_settings.majorVersion >= 3)) while (!m_context && (m_settings.majorVersion >= 3))
{ {
// Create the context // Create the context
int attributes[] = int attributes[] =
{ {
GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion), GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion), GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0, 0 0, 0
}; };
m_context = glXCreateContextAttribsARB(m_display, configs[0], toShare, true, attributes); m_context = glXCreateContextAttribsARB(m_display, configs[0], toShare, true, attributes);
if (m_context) if (m_context)
{ {
// Ok: retrieve the config's visual // Ok: retrieve the config's visual
visualInfo = glXGetVisualFromFBConfig(m_display, configs[0]); visualInfo = glXGetVisualFromFBConfig(m_display, configs[0]);
} }
else else
{ {
// If we couldn't create the context, lower the version number and try again -- stop at 3.0 // If we couldn't create the context, lower the version number and try again -- stop at 3.0
// Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care
if (m_settings.minorVersion > 0) if (m_settings.minorVersion > 0)
{ {
// If the minor version is not 0, we decrease it and try again // If the minor version is not 0, we decrease it and try again
m_settings.minorVersion--; m_settings.minorVersion--;
} }
else else
{ {
// If the minor version is 0, we decrease the major version // If the minor version is 0, we decrease the major version
m_settings.majorVersion--; m_settings.majorVersion--;
m_settings.minorVersion = 9; m_settings.minorVersion = 9;
} }
} }
} }
XFree(configs); XFree(configs);
} }
} }
} }
// If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context // If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context
if (!m_context) if (!m_context)
{ {
// set the context version to 2.0 (arbitrary) // set the context version to 2.0 (arbitrary)
m_settings.majorVersion = 2; m_settings.majorVersion = 2;
m_settings.minorVersion = 0; m_settings.minorVersion = 0;
// Retrieve the attributes of the target window // Retrieve the attributes of the target window
XWindowAttributes windowAttributes; XWindowAttributes windowAttributes;
if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0) if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
{ {
err() << "Failed to get the window attributes" << std::endl; err() << "Failed to get the window attributes" << std::endl;
return; return;
} }
// Get its visual // Get its visual
XVisualInfo tpl; XVisualInfo tpl;
tpl.screen = DefaultScreen(m_display); tpl.screen = DefaultScreen(m_display);
tpl.visualid = XVisualIDFromVisual(windowAttributes.visual); tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
int nbVisuals = 0; int nbVisuals = 0;
visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals); visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
// Create the context, using the target window's visual // Create the context, using the target window's visual
m_context = glXCreateContext(m_display, visualInfo, toShare, true); m_context = glXCreateContext(m_display, visualInfo, toShare, true);
if (!m_context) if (!m_context)
{ {
err() << "Failed to create an OpenGL context for this window" << std::endl; err() << "Failed to create an OpenGL context for this window" << std::endl;
return; return;
} }
} }
// Update the creation settings from the chosen format // Update the creation settings from the chosen format
int depth, stencil, multiSampling, samples; int depth, stencil, multiSampling, samples;
glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth); glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth);
glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil); glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);
glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling); glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples); glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples);
m_settings.depthBits = static_cast<unsigned int>(depth); m_settings.depthBits = static_cast<unsigned int>(depth);
m_settings.stencilBits = static_cast<unsigned int>(stencil); m_settings.stencilBits = static_cast<unsigned int>(stencil);
m_settings.antialiasingLevel = multiSampling ? samples : 0; m_settings.antialiasingLevel = multiSampling ? samples : 0;
// Free the visual info // Free the visual info
XFree(visualInfo); XFree(visualInfo);
} }
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf

View File

@ -1,148 +1,148 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// //
// SFML - Simple and Fast Multimedia Library // SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
// //
// This software is provided 'as-is', without any express or implied warranty. // 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. // 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, // Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely, // including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions: // subject to the following restrictions:
// //
// 1. The origin of this software must not be misrepresented; // 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software. // you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment // If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required. // in the product documentation would be appreciated but is not required.
// //
// 2. Altered source versions must be plainly marked as such, // 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software. // and must not be misrepresented as being the original software.
// //
// 3. This notice may not be removed or altered from any source distribution. // 3. This notice may not be removed or altered from any source distribution.
// //
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#ifndef SFML_GLXCONTEXT_HPP #ifndef SFML_GLXCONTEXT_HPP
#define SFML_GLXCONTEXT_HPP #define SFML_GLXCONTEXT_HPP
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/GlContext.hpp> #include <SFML/Window/GlContext.hpp>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <GL/glx.h> #include <GL/glx.h>
namespace sf namespace sf
{ {
namespace priv namespace priv
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Linux (GLX) implementation of OpenGL contexts /// \brief Linux (GLX) implementation of OpenGL contexts
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
class GlxContext : public GlContext class GlxContext : public GlContext
{ {
public : public :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new default context /// \brief Create a new default context
/// ///
/// \param shared Context to share the new one with (can be NULL) /// \param shared Context to share the new one with (can be NULL)
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext(GlxContext* shared); GlxContext(GlxContext* shared);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new context attached to a window /// \brief Create a new context attached to a window
/// ///
/// \param shared Context to share the new one with /// \param shared Context to share the new one with
/// \param settings Creation parameters /// \param settings Creation parameters
/// \param owner Pointer to the owner window /// \param owner Pointer to the owner window
/// \param bitsPerPixel Pixel depth, in bits per pixel /// \param bitsPerPixel Pixel depth, in bits per pixel
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel); GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create a new context that embeds its own rendering target /// \brief Create a new context that embeds its own rendering target
/// ///
/// \param shared Context to share the new one with /// \param shared Context to share the new one with
/// \param settings Creation parameters /// \param settings Creation parameters
/// \param width Back buffer width, in pixels /// \param width Back buffer width, in pixels
/// \param height Back buffer height, in pixels /// \param height Back buffer height, in pixels
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height); GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Destructor /// \brief Destructor
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
~GlxContext(); ~GlxContext();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Activate the context as the current target for rendering /// \brief Activate the context as the current target for rendering
/// ///
/// \return True on success, false if any error happened /// \return True on success, false if any error happened
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual bool makeCurrent(); virtual bool makeCurrent();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Display what has been rendered to the context so far /// \brief Display what has been rendered to the context so far
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void display(); virtual void display();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Enable or disable vertical synchronization /// \brief Enable or disable vertical synchronization
/// ///
/// Activating vertical synchronization will limit the number /// Activating vertical synchronization will limit the number
/// of frames displayed to the refresh rate of the monitor. /// of frames displayed to the refresh rate of the monitor.
/// This can avoid some visual artifacts, and limit the framerate /// This can avoid some visual artifacts, and limit the framerate
/// to a good value (but not constant across different computers). /// to a good value (but not constant across different computers).
/// ///
/// \param enabled True to enable v-sync, false to deactivate /// \param enabled True to enable v-sync, false to deactivate
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
virtual void setVerticalSyncEnabled(bool enabled); virtual void setVerticalSyncEnabled(bool enabled);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Select the best GLX visual for a given set of settings /// \brief Select the best GLX visual for a given set of settings
/// ///
/// \param display X display /// \param display X display
/// \param bitsPerPixel Pixel depth, in bits per pixel /// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Requested context settings /// \param settings Requested context settings
/// ///
/// \return The best visual /// \return The best visual
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static XVisualInfo selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings); static XVisualInfo selectBestVisual(::Display* display, unsigned int bitsPerPixel, const ContextSettings& settings);
private : private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Create the context /// \brief Create the context
/// ///
/// \param shared Context to share the new one with (can be NULL) /// \param shared Context to share the new one with (can be NULL)
/// \param bitsPerPixel Pixel depth, in bits per pixel /// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Creation parameters /// \param settings Creation parameters
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings); void createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Member data // Member data
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
::Display* m_display; ///< Connection to the X server ::Display* m_display; ///< Connection to the X server
::Window m_window; ///< Window to which the context is attached ::Window m_window; ///< Window to which the context is attached
GLXContext m_context; ///< OpenGL context GLXContext m_context; ///< OpenGL context
bool m_ownsWindow; ///< Do we own the window associated to the context? bool m_ownsWindow; ///< Do we own the window associated to the context?
}; };
} // namespace priv } // namespace priv
} // namespace sf } // namespace sf
#endif // SFML_GLXCONTEXT_HPP #endif // SFML_GLXCONTEXT_HPP

View File

@ -25,9 +25,9 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/Linux/InputImpl.hpp> #include <SFML/Window/Unix/InputImpl.hpp>
#include <SFML/Window/Window.hpp> #include <SFML/Window/Window.hpp>
#include <SFML/Window/Linux/Display.hpp> #include <SFML/Window/Unix/Display.hpp>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>

View File

@ -28,13 +28,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#if defined(SFML_SYSTEM_LINUX) #include <linux/joystick.h>
#include <linux/joystick.h> #include <fcntl.h>
#include <fcntl.h>
#elif defined(SFML_SYSTEM_FREEBSD)
// #include <sys/joystick.h> ?
#define ABS_MAX 1
#endif
namespace sf namespace sf

View File

@ -26,7 +26,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/Window/VideoModeImpl.hpp> #include <SFML/Window/VideoModeImpl.hpp>
#include <SFML/Window/Linux/Display.hpp> #include <SFML/Window/Unix/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>
@ -74,7 +74,7 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{ {
// Convert to VideoMode // Convert to VideoMode
VideoMode mode(sizes[j].width, sizes[j].height, depths[i]); VideoMode mode(sizes[j].width, sizes[j].height, depths[i]);
// Add it only if it is not already in the array // Add it only if it is not already in the array
if (std::find(modes.begin(), modes.end(), mode) == modes.end()) if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode); modes.push_back(mode);

View File

@ -26,14 +26,15 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#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/Unix/WindowImplX11.hpp>
#include <SFML/Window/Linux/GlxContext.hpp> #include <SFML/Window/Unix/GlxContext.hpp>
#include <SFML/Window/Linux/Display.hpp> #include <SFML/Window/Unix/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>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <libgen.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>

View File

@ -39,7 +39,7 @@
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD) #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
#include <SFML/Window/Linux/WindowImplX11.hpp> #include <SFML/Window/Unix/WindowImplX11.hpp>
typedef sf::priv::WindowImplX11 WindowImplType; typedef sf::priv::WindowImplX11 WindowImplType;
#elif defined(SFML_SYSTEM_MACOS) #elif defined(SFML_SYSTEM_MACOS)