Added Linux implementation of OpenGL context (work in progress)
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1066 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
9c370e38da
commit
19ae448f13
294
src/SFML/Window/Linux/ContextGLX.cpp
Normal file
294
src/SFML/Window/Linux/ContextGLX.cpp
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2009 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/ContextGLX.hpp>
|
||||||
|
#include <SFML/Window/WindowImpl.hpp>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <SFML/Window/glext/glxext.h>
|
||||||
|
#include <SFML/Window/glext/glext.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create a new context, not associated to a window
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ContextGLX::ContextGLX(ContextGLX* Shared) :
|
||||||
|
myWindow (NULL),
|
||||||
|
myContext (NULL)/*,
|
||||||
|
myOwnsWindow(true)*/
|
||||||
|
{
|
||||||
|
// Create the rendering context
|
||||||
|
XVisualInfo Visual;
|
||||||
|
CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
||||||
|
|
||||||
|
// Create a new color map with the chosen visual
|
||||||
|
/*Colormap ColMap = XCreateColormap(ourDisplay, RootWindow(ourDisplay, ourScreen), Visual.visual, AllocNone);
|
||||||
|
|
||||||
|
// Define the window attributes
|
||||||
|
XSetWindowAttributes Attributes;
|
||||||
|
Attributes.colormap = ColMap;
|
||||||
|
|
||||||
|
// Create a dummy window (disabled and hidden)
|
||||||
|
myWindow = XCreateWindow(ourDisplay,
|
||||||
|
RootWindow(ourDisplay, ourScreen),
|
||||||
|
0, 0,
|
||||||
|
myWidth, myHeight,
|
||||||
|
0,
|
||||||
|
Visual.depth,
|
||||||
|
InputOutput,
|
||||||
|
Visual.visual,
|
||||||
|
CWColormap, &Attributes);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create a new context attached to a window
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ContextGLX::ContextGLX(ContextWGL* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings) :
|
||||||
|
myWindow (NULL),
|
||||||
|
myContext (NULL),/*
|
||||||
|
myOwnsWindow(false)*/
|
||||||
|
{
|
||||||
|
// Get the owner window and its device context
|
||||||
|
myWindow = static_cast<Window>(Owner->GetHandle());
|
||||||
|
|
||||||
|
// Create the context
|
||||||
|
if (myWindow)
|
||||||
|
CreateContext(Shared, BitsPerPixel, Settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ContextGLX::~ContextGLX()
|
||||||
|
{
|
||||||
|
// Destroy the OpenGL context
|
||||||
|
if (myContext)
|
||||||
|
{
|
||||||
|
if (glXGetCurrentContext() == myContext)
|
||||||
|
glXMakeCurrent(myDisplay.GetDisplay(), None, NULL);
|
||||||
|
glXDestroyContext(myContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the window if we own it
|
||||||
|
/*if (myWindow && myOwnsWindow)
|
||||||
|
{
|
||||||
|
XDestroyWindow(myDisplay.GetDisplay(), myWindow);
|
||||||
|
XFlush(myDisplay.GetDisplay());
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::MakeCurrent
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool ContextGLX::MakeCurrent(bool Active)
|
||||||
|
{
|
||||||
|
if (Active)
|
||||||
|
{
|
||||||
|
if (myWindow && myContext)
|
||||||
|
{
|
||||||
|
if (glXGetCurrentContext() != myContext)
|
||||||
|
return glXMakeCurrent(myDisplay.GetDisplay(), myWindow, myContext) != 0;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (glXGetCurrentContext() == myContext)
|
||||||
|
return wglMakeCurrent(myDisplay.GetDisplay(), None, NULL) != 0;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::Display
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void ContextGLX::Display()
|
||||||
|
{
|
||||||
|
if (myWindow)
|
||||||
|
glXSwapBuffers(myDisplay.GetDisplay(), myWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::UseVerticalSync
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void ContextGLX::UseVerticalSync(bool Enabled)
|
||||||
|
{
|
||||||
|
const GLubyte* ProcAddress = reinterpret_cast<const GLubyte*>("glXSwapIntervalSGI");
|
||||||
|
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress(ProcAddress));
|
||||||
|
if (glXSwapIntervalSGI)
|
||||||
|
glXSwapIntervalSGI(Enabled ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Check if a context is active on the current thread
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool ContextGLX::IsContextActive()
|
||||||
|
{
|
||||||
|
return glXGetCurrentContext() != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create the context
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void ContextGLX::CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings)
|
||||||
|
{
|
||||||
|
XVisualInfo Template;
|
||||||
|
Template.screen = DefaultScreen(myDisplayRef.GetDisplay());
|
||||||
|
if (myWindow)
|
||||||
|
{
|
||||||
|
// Get the attributes of the target window
|
||||||
|
XWindowAttributes WindowAttributes;
|
||||||
|
if (XGetWindowAttributes(myDisplayRef.GetDisplay(), myWindow, &WindowAttributes) == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to get the window attributes" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the visual infos to match
|
||||||
|
Template.depth = WindowAttributes.depth;
|
||||||
|
Template.visualid = XVisualIDFromVisual(WindowAttributes.visual);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all the visuals matching the template
|
||||||
|
int NbVisuals = 0;
|
||||||
|
XVisualInfo* Visuals = XGetVisualInfo(myDisplay.GetDisplay(), VisualDepthMask | VisualIDMask | VisualScreenMask, &Template, &NbVisuals);
|
||||||
|
if (!Visuals || (NbVisuals == 0))
|
||||||
|
{
|
||||||
|
if (Visuals)
|
||||||
|
XFree(Visuals);
|
||||||
|
std::cerr << "There is no valid visual for the selected screen" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the best visual
|
||||||
|
int BestScore = 0xFFFF;
|
||||||
|
XVisualInfo* BestVisual = NULL;
|
||||||
|
while (!BestVisual)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NbVisuals; ++i)
|
||||||
|
{
|
||||||
|
// Get the current visual attributes
|
||||||
|
int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA, &RGBA);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE, &Red);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE, &Green);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE, &Blue);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE, &Alpha);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE, &Depth);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE, &Stencil);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
|
||||||
|
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB, &Samples);
|
||||||
|
|
||||||
|
// First check the mandatory parameters
|
||||||
|
if ((RGBA == 0) || (DoubleBuffer == 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Evaluate the current configuration
|
||||||
|
int Color = Red + Green + Blue + Alpha;
|
||||||
|
int Score = EvaluateFormat(BitsPerPixel, mySettings, Color, Depth, Stencil, MultiSampling ? Samples : 0);
|
||||||
|
|
||||||
|
// Keep it if it's better than the current best
|
||||||
|
if (Score < BestScore)
|
||||||
|
{
|
||||||
|
BestScore = Score;
|
||||||
|
BestVisual = &Visuals[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no visual has been found, try a lower level of antialiasing
|
||||||
|
if (!BestVisual)
|
||||||
|
{
|
||||||
|
if (Params.AntialiasingLevel > 2)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find a pixel format supporting "
|
||||||
|
<< Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
|
||||||
|
Params.AntialiasingLevel = 2;
|
||||||
|
}
|
||||||
|
else if (Params.AntialiasingLevel > 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
|
||||||
|
Params.AntialiasingLevel = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the context to share display lists with
|
||||||
|
GLXContext ToShare = Shared ? Shared->myContext : NULL;
|
||||||
|
|
||||||
|
// Create the context
|
||||||
|
myContext = glXCreateContext(myDisplay.GetDisplay(), BestVisual, ToShare, true);
|
||||||
|
if (!myContext)
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the creation settings from the chosen format
|
||||||
|
int Depth, Stencil;
|
||||||
|
glXGetConfig(myDisplay.GetDisplay(), BestVisual, GLX_DEPTH_SIZE, &Depth);
|
||||||
|
glXGetConfig(myDisplay.GetDisplay(), BestVisual, GLX_STENCIL_SIZE, &Stencil);
|
||||||
|
mySettings.DepthBits = static_cast<unsigned int>(Depth);
|
||||||
|
mySettings.StencilBits = static_cast<unsigned int>(Stencil);
|
||||||
|
|
||||||
|
// Change the target window's colormap so that it matches the context's one
|
||||||
|
if (myWindow)
|
||||||
|
{
|
||||||
|
::Window Root = RootWindow(myDisplay.GetDisplay(), DefaultScreen(myDisplay.GetDisplay()))
|
||||||
|
Colormap ColMap = XCreateColormap(myDisplay.GetDisplay(), Root, BestVisual->visual, AllocNone);
|
||||||
|
XSetWindowColormap(myDisplay.GetDisplay(), myWindow, ColMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the temporary visuals array
|
||||||
|
XFree(Visuals);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
138
src/SFML/Window/Linux/ContextGLX.hpp
Normal file
138
src/SFML/Window/Linux/ContextGLX.hpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2009 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_CONTEXTGLX_HPP
|
||||||
|
#define SFML_CONTEXTGLX_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/Context.hpp>
|
||||||
|
#include <SFML/Window/Linux/DisplayRef.hpp>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Linux (GLX) implementation of OpenGL contexts
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
class ContextGLX : public Context
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create a new context, not associated to a window
|
||||||
|
///
|
||||||
|
/// \param Shared : Context to share the new one with (can be NULL)
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ContextGLX(ContextGLX* Shared);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create a new context attached to a window
|
||||||
|
///
|
||||||
|
/// \param Shared : Context to share the new one with (can be NULL)
|
||||||
|
/// \param Owner : Pointer to the owner window
|
||||||
|
/// \param BitsPerPixel : Pixel depth (in bits per pixel)
|
||||||
|
/// \param Settings : Creation parameters
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
ContextGLX(ContextGLX* Shared, const WindowImpl* Owner, unsigned int BitsPerPixel, const ContextSettings& Settings);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~ContextGLX();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::MakeCurrent
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual bool MakeCurrent(bool Active);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::Display
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void Display();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \see Context::UseVerticalSync
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void UseVerticalSync(bool Enabled);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Check if a context is active on the current thread
|
||||||
|
///
|
||||||
|
/// \return True if there's an active context, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static bool IsContextActive();
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create the context
|
||||||
|
///
|
||||||
|
/// \param Shared : Context to share the new one with (can be NULL)
|
||||||
|
/// \param BitsPerPixel : Pixel depth, in bits per pixel
|
||||||
|
/// \param Settings : Creation parameters
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void CreateContext(ContextGLX* Shared, unsigned int BitsPerPixel, const ContextSettings& Settings);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Create the OpenGL rendering context
|
||||||
|
///
|
||||||
|
/// \param Mode : Video mode to use
|
||||||
|
/// \param ChosenVisual : Visual that has been chosen for creating the contexte
|
||||||
|
/// \param Params : Creation parameters
|
||||||
|
/// \param Template : Visual infos to match
|
||||||
|
/// \param Mask : Visual attributes to check in Template
|
||||||
|
///
|
||||||
|
/// \return True on success, false on error
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//bool CreateContext(XVisualInfo& ChosenVisual, WindowSettings& Params, XVisualInfo Template = XVisualInfo(), unsigned long Mask = 0);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Member data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef myDisplay; ///< Connection to the X server
|
||||||
|
::Window myWindow; ///< Window to which the context is attached
|
||||||
|
GLXContext myContext; ///< OpenGL context
|
||||||
|
//bool myOwnsWindow; ///< Did we create the host window?
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
||||||
|
|
||||||
|
#endif // SFML_CONTEXTGLX_HPP
|
122
src/SFML/Window/Linux/DisplayRef.cpp
Normal file
122
src/SFML/Window/Linux/DisplayRef.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2009 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/DisplayRef.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Private data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
::Display* TheDisplay = NULL;
|
||||||
|
XIM TheInputMethod = NULL;
|
||||||
|
int RefCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Default constructor
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef::DisplayRef()
|
||||||
|
{
|
||||||
|
// If the display hasn't been opened yet, open it
|
||||||
|
if (TheDisplay == NULL)
|
||||||
|
{
|
||||||
|
TheDisplay = XOpenDisplay(NULL);
|
||||||
|
if (TheDisplay)
|
||||||
|
{
|
||||||
|
// Create the input method object
|
||||||
|
TheInputMethod = XOpenIM(TheDisplay, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to open a connection with the X server" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase the number of references
|
||||||
|
RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Copy constructor
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef::DisplayRef(const DisplayRef& Copy)
|
||||||
|
{
|
||||||
|
// Increase the number of references
|
||||||
|
RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef::~DisplayRef()
|
||||||
|
{
|
||||||
|
// Decrease the number of references
|
||||||
|
RefCount--;
|
||||||
|
|
||||||
|
// If all references have been destroyed, we can close the display
|
||||||
|
if (RefCount == 0)
|
||||||
|
{
|
||||||
|
// Destroy the input method object
|
||||||
|
if (TheInputMethod)
|
||||||
|
XCloseIM(TheInputMethod);
|
||||||
|
|
||||||
|
// Close the display
|
||||||
|
XCloseDisplay(TheDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Get the current display
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
::Display* DisplayRef::GetDisplay() const
|
||||||
|
{
|
||||||
|
return TheDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Get the input method associated to the display
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
XIM DisplayRef::GetInputMethod() const
|
||||||
|
{
|
||||||
|
return TheInputMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
86
src/SFML/Window/Linux/DisplayRef.hpp
Normal file
86
src/SFML/Window/Linux/DisplayRef.hpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2009 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_DISPLAYREF_HPP
|
||||||
|
#define SFML_DISPLAYREF_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Provides an access to the display (connection to the X server)
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
class DisplayRef
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Default constructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Copy constructor
|
||||||
|
///
|
||||||
|
/// \param Copy : Instance to copy
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef(const DisplayRef& Copy);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Destructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~DisplayRef();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Get the current display
|
||||||
|
///
|
||||||
|
/// \return Pointer to the current display
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
::Display* GetDisplay() const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Get the input method associated to the display
|
||||||
|
///
|
||||||
|
/// \return Input method object
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
XIM GetInputMethod() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
||||||
|
|
||||||
|
#endif // SFML_DISPLAYREF_HPP
|
@ -26,7 +26,7 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/Linux/VideoModeSupport.hpp>
|
#include <SFML/Window/Linux/VideoModeSupport.hpp>
|
||||||
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
#include <SFML/Window/Linux/DisplayRef.hpp>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -45,17 +45,15 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
|
|||||||
// First, clear array to fill
|
// First, clear array to fill
|
||||||
Modes.clear();
|
Modes.clear();
|
||||||
|
|
||||||
// Get the display and screen from sfWindowImplUnix
|
// Get an access to the display
|
||||||
WindowImplX11::OpenDisplay(false);
|
DisplayRef Disp;
|
||||||
Display* Disp = WindowImplX11::ourDisplay;
|
|
||||||
int Screen = WindowImplX11::ourScreen;
|
|
||||||
|
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
int Version;
|
int Version;
|
||||||
if (XQueryExtension(Disp, "RANDR", &Version, &Version, &Version))
|
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp, RootWindow(Disp, Screen));
|
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay())));
|
||||||
if (Config)
|
if (Config)
|
||||||
{
|
{
|
||||||
// Get the available screen sizes
|
// Get the available screen sizes
|
||||||
@ -99,17 +97,15 @@ VideoMode VideoModeSupport::GetDesktopVideoMode()
|
|||||||
{
|
{
|
||||||
VideoMode DesktopMode;
|
VideoMode DesktopMode;
|
||||||
|
|
||||||
// Get the display and screen from sfWindowImplUnix
|
// Get an access to the display
|
||||||
WindowImplX11::OpenDisplay(false);
|
DisplayRef Disp;
|
||||||
Display* Disp = WindowImplX11::ourDisplay;
|
|
||||||
int Screen = WindowImplX11::ourScreen;
|
|
||||||
|
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
int Version;
|
int Version;
|
||||||
if (XQueryExtension(Disp, "RANDR", &Version, &Version, &Version))
|
if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version))
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp, RootWindow(Disp, Screen));
|
XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay())));
|
||||||
if (Config)
|
if (Config)
|
||||||
{
|
{
|
||||||
// Get the current video mode
|
// Get the current video mode
|
||||||
|
@ -27,8 +27,6 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
#include <SFML/Window/WindowStyle.hpp> // important to be included first (conflict with None)
|
||||||
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
||||||
#include <SFML/Window/glext/glxext.h>
|
|
||||||
#include <SFML/Window/glext/glext.h>
|
|
||||||
#include <SFML/System/Unicode.hpp>
|
#include <SFML/System/Unicode.hpp>
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <X11/extensions/Xrandr.h>
|
#include <X11/extensions/Xrandr.h>
|
||||||
@ -37,89 +35,37 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Private data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
WindowImplX11* FullscreenWindow = NULL;
|
||||||
|
unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
||||||
|
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Static member data
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Display* WindowImplX11::ourDisplay = NULL;
|
|
||||||
int WindowImplX11::ourScreen = 0;
|
|
||||||
WindowImplX11* WindowImplX11::ourFullscreenWindow = NULL;
|
|
||||||
unsigned int WindowImplX11::ourWindowsCount = 0;
|
|
||||||
XIM WindowImplX11::ourInputMethod = NULL;
|
|
||||||
unsigned long WindowImplX11::ourEventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
|
|
||||||
PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask |
|
|
||||||
EnterWindowMask | LeaveWindowMask;
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Default constructor
|
|
||||||
/// (creates a dummy window to provide a valid OpenGL context)
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
WindowImplX11::WindowImplX11() :
|
|
||||||
myWindow (0),
|
|
||||||
myIsExternal (false),
|
|
||||||
myGLContext (NULL),
|
|
||||||
myAtomClose (0),
|
|
||||||
myOldVideoMode(-1),
|
|
||||||
myHiddenCursor(0),
|
|
||||||
myInputContext(NULL),
|
|
||||||
myKeyRepeat (true)
|
|
||||||
{
|
|
||||||
// Open the display at first call
|
|
||||||
if (!OpenDisplay())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Use small dimensions
|
|
||||||
myWidth = 1;
|
|
||||||
myHeight = 1;
|
|
||||||
|
|
||||||
// Create the rendering context
|
|
||||||
XVisualInfo Visual;
|
|
||||||
WindowSettings Params(0, 0, 0);
|
|
||||||
if (!CreateContext(VideoMode(myWidth, myHeight, 32), Visual, Params))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Create a new color map with the chosen visual
|
|
||||||
Colormap ColMap = XCreateColormap(ourDisplay, RootWindow(ourDisplay, ourScreen), Visual.visual, AllocNone);
|
|
||||||
|
|
||||||
// Define the window attributes
|
|
||||||
XSetWindowAttributes Attributes;
|
|
||||||
Attributes.colormap = ColMap;
|
|
||||||
|
|
||||||
// Create a dummy window (disabled and hidden)
|
|
||||||
myWindow = XCreateWindow(ourDisplay,
|
|
||||||
RootWindow(ourDisplay, ourScreen),
|
|
||||||
0, 0,
|
|
||||||
myWidth, myHeight,
|
|
||||||
0,
|
|
||||||
Visual.depth,
|
|
||||||
InputOutput,
|
|
||||||
Visual.visual,
|
|
||||||
CWColormap, &Attributes);
|
|
||||||
|
|
||||||
// Don't activate the dummy context by default
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create the window implementation from an existing control
|
/// Create the window implementation from an existing control
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11::WindowImplX11(WindowHandle Handle, WindowSettings& Params) :
|
WindowImplX11::WindowImplX11(WindowHandle Handle) :
|
||||||
myWindow (0),
|
myWindow (0),
|
||||||
myIsExternal (true),
|
myIsExternal (true),
|
||||||
myGLContext (NULL),
|
|
||||||
myAtomClose (0),
|
myAtomClose (0),
|
||||||
myOldVideoMode(-1),
|
myOldVideoMode(-1),
|
||||||
myHiddenCursor(0),
|
myHiddenCursor(0),
|
||||||
myInputContext(NULL),
|
myInputContext(NULL),
|
||||||
myKeyRepeat (true)
|
myKeyRepeat (true)
|
||||||
{
|
{
|
||||||
// Open the display at first call
|
// Get the display and screen
|
||||||
if (!OpenDisplay())
|
myDisplay = myDisplayRef.GetDisplay();
|
||||||
return;
|
myScreen = DefaultScreen(myDisplay);
|
||||||
|
|
||||||
// Save the window handle
|
// Save the window handle
|
||||||
myWindow = Handle;
|
myWindow = Handle;
|
||||||
@ -128,7 +74,7 @@ myKeyRepeat (true)
|
|||||||
{
|
{
|
||||||
// Get the window size
|
// Get the window size
|
||||||
XWindowAttributes WindowAttributes;
|
XWindowAttributes WindowAttributes;
|
||||||
if (XGetWindowAttributes(ourDisplay, myWindow, &WindowAttributes) == 0)
|
if (XGetWindowAttributes(myDisplay, myWindow, &WindowAttributes) == 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to get the window attributes" << std::endl;
|
std::cerr << "Failed to get the window attributes" << std::endl;
|
||||||
return;
|
return;
|
||||||
@ -136,24 +82,8 @@ myKeyRepeat (true)
|
|||||||
myWidth = WindowAttributes.width;
|
myWidth = WindowAttributes.width;
|
||||||
myHeight = WindowAttributes.height;
|
myHeight = WindowAttributes.height;
|
||||||
|
|
||||||
// Setup the visual infos to match
|
|
||||||
XVisualInfo Template;
|
|
||||||
Template.depth = WindowAttributes.depth;
|
|
||||||
Template.visualid = XVisualIDFromVisual(WindowAttributes.visual);
|
|
||||||
unsigned long Mask = VisualDepthMask | VisualIDMask;
|
|
||||||
|
|
||||||
// Create the rendering context
|
|
||||||
VideoMode Mode(myWidth, myHeight, VideoMode::GetDesktopMode().BitsPerPixel);
|
|
||||||
XVisualInfo Visual;
|
|
||||||
if (!CreateContext(Mode, Visual, Params, Template, Mask))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Create a new color map with the chosen visual
|
|
||||||
Colormap ColMap = XCreateColormap(ourDisplay, RootWindow(ourDisplay, ourScreen), Visual.visual, AllocNone);
|
|
||||||
XSetWindowColormap(ourDisplay, myWindow, ColMap);
|
|
||||||
|
|
||||||
// Make sure the window is listening to all the requiered events
|
// Make sure the window is listening to all the requiered events
|
||||||
XSelectInput(ourDisplay, myWindow, ourEventMask & ~ButtonPressMask);
|
XSelectInput(myDisplay, myWindow, EventMask & ~ButtonPressMask);
|
||||||
|
|
||||||
// Do some common initializations
|
// Do some common initializations
|
||||||
Initialize();
|
Initialize();
|
||||||
@ -164,7 +94,7 @@ myKeyRepeat (true)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create the window implementation
|
/// Create the window implementation
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11::WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params) :
|
WindowImplX11::WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle) :
|
||||||
myWindow (0),
|
myWindow (0),
|
||||||
myIsExternal (false),
|
myIsExternal (false),
|
||||||
myGLContext (NULL),
|
myGLContext (NULL),
|
||||||
@ -174,17 +104,13 @@ myHiddenCursor(0),
|
|||||||
myInputContext(NULL),
|
myInputContext(NULL),
|
||||||
myKeyRepeat (true)
|
myKeyRepeat (true)
|
||||||
{
|
{
|
||||||
// Open the display at first call
|
|
||||||
if (!OpenDisplay())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Compute position and size
|
// Compute position and size
|
||||||
int Left, Top;
|
int Left, Top;
|
||||||
bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
|
bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
|
||||||
if (!Fullscreen)
|
if (!Fullscreen)
|
||||||
{
|
{
|
||||||
Left = (DisplayWidth(ourDisplay, ourScreen) - Mode.Width) / 2;
|
Left = (DisplayWidth(myDisplay, myScreen) - Mode.Width) / 2;
|
||||||
Top = (DisplayHeight(ourDisplay, ourScreen) - Mode.Height) / 2;
|
Top = (DisplayHeight(myDisplay, myScreen) - Mode.Height) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -198,23 +124,14 @@ myKeyRepeat (true)
|
|||||||
if (Fullscreen)
|
if (Fullscreen)
|
||||||
SwitchToFullscreen(Mode);
|
SwitchToFullscreen(Mode);
|
||||||
|
|
||||||
// Create the rendering context
|
|
||||||
XVisualInfo Visual;
|
|
||||||
if (!CreateContext(Mode, Visual, Params))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Create a new color map with the chosen visual
|
|
||||||
Colormap ColMap = XCreateColormap(ourDisplay, RootWindow(ourDisplay, ourScreen), Visual.visual, AllocNone);
|
|
||||||
|
|
||||||
// Define the window attributes
|
// Define the window attributes
|
||||||
XSetWindowAttributes Attributes;
|
XSetWindowAttributes Attributes;
|
||||||
Attributes.event_mask = ourEventMask;
|
Attributes.event_mask = EventMask;
|
||||||
Attributes.colormap = ColMap;
|
|
||||||
Attributes.override_redirect = Fullscreen;
|
Attributes.override_redirect = Fullscreen;
|
||||||
|
|
||||||
// Create the window
|
// Create the window
|
||||||
myWindow = XCreateWindow(ourDisplay,
|
myWindow = XCreateWindow(myDisplay,
|
||||||
RootWindow(ourDisplay, ourScreen),
|
RootWindow(myDisplay, myScreen),
|
||||||
Left, Top,
|
Left, Top,
|
||||||
Width, Height,
|
Width, Height,
|
||||||
0,
|
0,
|
||||||
@ -229,12 +146,12 @@ myKeyRepeat (true)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the window's name
|
// Set the window's name
|
||||||
XStoreName(ourDisplay, myWindow, Title.c_str());
|
XStoreName(myDisplay, myWindow, Title.c_str());
|
||||||
|
|
||||||
// Set the window's style (tell the windows manager to change our window's decorations and functions according to the requested style)
|
// Set the window's style (tell the windows manager to change our window's decorations and functions according to the requested style)
|
||||||
if (!Fullscreen)
|
if (!Fullscreen)
|
||||||
{
|
{
|
||||||
Atom WMHintsAtom = XInternAtom(ourDisplay, "_MOTIF_WM_HINTS", false);
|
Atom WMHintsAtom = XInternAtom(myDisplay, "_MOTIF_WM_HINTS", false);
|
||||||
if (WMHintsAtom)
|
if (WMHintsAtom)
|
||||||
{
|
{
|
||||||
static const unsigned long MWM_HINTS_FUNCTIONS = 1 << 0;
|
static const unsigned long MWM_HINTS_FUNCTIONS = 1 << 0;
|
||||||
@ -286,7 +203,7 @@ myKeyRepeat (true)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char* HintsPtr = reinterpret_cast<const unsigned char*>(&Hints);
|
const unsigned char* HintsPtr = reinterpret_cast<const unsigned char*>(&Hints);
|
||||||
XChangeProperty(ourDisplay, myWindow, WMHintsAtom, WMHintsAtom, 32, PropModeReplace, HintsPtr, 5);
|
XChangeProperty(myDisplay, myWindow, WMHintsAtom, WMHintsAtom, 32, PropModeReplace, HintsPtr, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a hack to force some windows managers to disable resizing
|
// This is a hack to force some windows managers to disable resizing
|
||||||
@ -296,7 +213,7 @@ myKeyRepeat (true)
|
|||||||
XSizeHints.flags = PMinSize | PMaxSize;
|
XSizeHints.flags = PMinSize | PMaxSize;
|
||||||
XSizeHints.min_width = XSizeHints.max_width = Width;
|
XSizeHints.min_width = XSizeHints.max_width = Width;
|
||||||
XSizeHints.min_height = XSizeHints.max_height = Height;
|
XSizeHints.min_height = XSizeHints.max_height = Height;
|
||||||
XSetWMNormalHints(ourDisplay, myWindow, &XSizeHints);
|
XSetWMNormalHints(myDisplay, myWindow, &XSizeHints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,8 +223,8 @@ myKeyRepeat (true)
|
|||||||
// In fullscreen mode, we must grab keyboard and mouse inputs
|
// In fullscreen mode, we must grab keyboard and mouse inputs
|
||||||
if (Fullscreen)
|
if (Fullscreen)
|
||||||
{
|
{
|
||||||
XGrabPointer(ourDisplay, myWindow, true, 0, GrabModeAsync, GrabModeAsync, myWindow, None, CurrentTime);
|
XGrabPointer(myDisplay, myWindow, true, 0, GrabModeAsync, GrabModeAsync, myWindow, None, CurrentTime);
|
||||||
XGrabKeyboard(ourDisplay, myWindow, true, GrabModeAsync, GrabModeAsync, CurrentTime);
|
XGrabKeyboard(myDisplay, myWindow, true, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,38 +239,14 @@ WindowImplX11::~WindowImplX11()
|
|||||||
|
|
||||||
// Destroy the input context
|
// Destroy the input context
|
||||||
if (myInputContext)
|
if (myInputContext)
|
||||||
{
|
|
||||||
XDestroyIC(myInputContext);
|
XDestroyIC(myInputContext);
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the window
|
// Destroy the window
|
||||||
if (myWindow && !myIsExternal)
|
if (myWindow && !myIsExternal)
|
||||||
{
|
{
|
||||||
XDestroyWindow(ourDisplay, myWindow);
|
XDestroyWindow(myDisplay, myWindow);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the display
|
|
||||||
CloseDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Check if there's an active context on the current thread
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool WindowImplX11::IsContextActive()
|
|
||||||
{
|
|
||||||
return glXGetCurrentContext() != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::Display
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImplX11::Display()
|
|
||||||
{
|
|
||||||
if (myWindow && myGLContext)
|
|
||||||
glXSwapBuffers(ourDisplay, myWindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -364,21 +257,21 @@ void WindowImplX11::ProcessEvents()
|
|||||||
{
|
{
|
||||||
// Process any event in the queue matching our window
|
// Process any event in the queue matching our window
|
||||||
XEvent Event;
|
XEvent Event;
|
||||||
while (XCheckIfEvent(ourDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast<XPointer>(myWindow)))
|
while (XCheckIfEvent(myDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast<XPointer>(myWindow)))
|
||||||
{
|
{
|
||||||
// Filter repeated key events
|
// Filter repeated key events
|
||||||
if (Event.type == KeyRelease)
|
if (Event.type == KeyRelease)
|
||||||
{
|
{
|
||||||
if (XPending(ourDisplay))
|
if (XPending(myDisplay))
|
||||||
{
|
{
|
||||||
XEvent NextEvent;
|
XEvent NextEvent;
|
||||||
XPeekEvent(ourDisplay, &NextEvent);
|
XPeekEvent(myDisplay, &NextEvent);
|
||||||
if ((NextEvent.type == KeyPress) &&
|
if ((NextEvent.type == KeyPress) &&
|
||||||
(NextEvent.xkey.keycode == Event.xkey.keycode) &&
|
(NextEvent.xkey.keycode == Event.xkey.keycode) &&
|
||||||
(NextEvent.xkey.time == Event.xkey.time))
|
(NextEvent.xkey.time == Event.xkey.time))
|
||||||
{
|
{
|
||||||
if (!myKeyRepeat)
|
if (!myKeyRepeat)
|
||||||
XNextEvent(ourDisplay, &NextEvent);
|
XNextEvent(myDisplay, &NextEvent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,43 +282,13 @@ void WindowImplX11::ProcessEvents()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::SetActive
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImplX11::SetActive(bool Active) const
|
|
||||||
{
|
|
||||||
if (Active)
|
|
||||||
{
|
|
||||||
if (myWindow && myGLContext && (glXGetCurrentContext() != myGLContext))
|
|
||||||
glXMakeCurrent(ourDisplay, myWindow, myGLContext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (glXGetCurrentContext() == myGLContext)
|
|
||||||
glXMakeCurrent(ourDisplay, None, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::UseVerticalSync
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImplX11::UseVerticalSync(bool Enabled)
|
|
||||||
{
|
|
||||||
const GLubyte* ProcAddress = reinterpret_cast<const GLubyte*>("glXSwapIntervalSGI");
|
|
||||||
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(glXGetProcAddress(ProcAddress));
|
|
||||||
if (glXSwapIntervalSGI)
|
|
||||||
glXSwapIntervalSGI(Enabled ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see WindowImpl::ShowMouseCursor
|
/// /see WindowImpl::ShowMouseCursor
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::ShowMouseCursor(bool Show)
|
void WindowImplX11::ShowMouseCursor(bool Show)
|
||||||
{
|
{
|
||||||
XDefineCursor(ourDisplay, myWindow, Show ? None : myHiddenCursor);
|
XDefineCursor(myDisplay, myWindow, Show ? None : myHiddenCursor);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -434,8 +297,8 @@ void WindowImplX11::ShowMouseCursor(bool Show)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::SetCursorPosition(unsigned int Left, unsigned int Top)
|
void WindowImplX11::SetCursorPosition(unsigned int Left, unsigned int Top)
|
||||||
{
|
{
|
||||||
XWarpPointer(ourDisplay, None, myWindow, 0, 0, 0, 0, Left, Top);
|
XWarpPointer(myDisplay, None, myWindow, 0, 0, 0, 0, Left, Top);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -444,8 +307,8 @@ void WindowImplX11::SetCursorPosition(unsigned int Left, unsigned int Top)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::SetPosition(int Left, int Top)
|
void WindowImplX11::SetPosition(int Left, int Top)
|
||||||
{
|
{
|
||||||
XMoveWindow(ourDisplay, myWindow, Left, Top);
|
XMoveWindow(myDisplay, myWindow, Left, Top);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -454,8 +317,8 @@ void WindowImplX11::SetPosition(int Left, int Top)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::SetSize(unsigned int Width, unsigned int Height)
|
void WindowImplX11::SetSize(unsigned int Width, unsigned int Height)
|
||||||
{
|
{
|
||||||
XResizeWindow(ourDisplay, myWindow, Width, Height);
|
XResizeWindow(myDisplay, myWindow, Width, Height);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -465,11 +328,11 @@ void WindowImplX11::SetSize(unsigned int Width, unsigned int Height)
|
|||||||
void WindowImplX11::Show(bool State)
|
void WindowImplX11::Show(bool State)
|
||||||
{
|
{
|
||||||
if (State)
|
if (State)
|
||||||
XMapWindow(ourDisplay, myWindow);
|
XMapWindow(myDisplay, myWindow);
|
||||||
else
|
else
|
||||||
XUnmapWindow(ourDisplay, myWindow);
|
XUnmapWindow(myDisplay, myWindow);
|
||||||
|
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -499,19 +362,19 @@ void WindowImplX11::SetIcon(unsigned int Width, unsigned int Height, const Uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the icon pixmap
|
// Create the icon pixmap
|
||||||
Visual* DefVisual = DefaultVisual(ourDisplay, ourScreen);
|
Visual* DefVisual = DefaultVisual(myDisplay, myScreen);
|
||||||
unsigned int DefDepth = DefaultDepth(ourDisplay, ourScreen);
|
unsigned int DefDepth = DefaultDepth(myDisplay, myScreen);
|
||||||
XImage* IconImage = XCreateImage(ourDisplay, DefVisual, DefDepth, ZPixmap, 0, (char*)IconPixels, Width, Height, 32, 0);
|
XImage* IconImage = XCreateImage(myDisplay, DefVisual, DefDepth, ZPixmap, 0, (char*)IconPixels, Width, Height, 32, 0);
|
||||||
if (!IconImage)
|
if (!IconImage)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to set the window's icon" << std::endl;
|
std::cerr << "Failed to set the window's icon" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Pixmap IconPixmap = XCreatePixmap(ourDisplay, RootWindow(ourDisplay, ourScreen), Width, Height, DefDepth);
|
Pixmap IconPixmap = XCreatePixmap(myDisplay, RootWindow(myDisplay, myScreen), Width, Height, DefDepth);
|
||||||
XGCValues Values;
|
XGCValues Values;
|
||||||
GC IconGC = XCreateGC(ourDisplay, IconPixmap, 0, &Values);
|
GC IconGC = XCreateGC(myDisplay, IconPixmap, 0, &Values);
|
||||||
XPutImage(ourDisplay, IconPixmap, IconGC, IconImage, 0, 0, 0, 0, Width, Height);
|
XPutImage(myDisplay, IconPixmap, IconGC, IconImage, 0, 0, 0, 0, Width, Height);
|
||||||
XFreeGC(ourDisplay, IconGC);
|
XFreeGC(myDisplay, IconGC);
|
||||||
XDestroyImage(IconImage);
|
XDestroyImage(IconImage);
|
||||||
|
|
||||||
// Create the mask pixmap (must have 1 bit depth)
|
// Create the mask pixmap (must have 1 bit depth)
|
||||||
@ -531,17 +394,17 @@ void WindowImplX11::SetIcon(unsigned int Width, unsigned int Height, const Uint8
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pixmap MaskPixmap = XCreatePixmapFromBitmapData(ourDisplay, myWindow, (char*)&MaskPixels[0], Width, Height, 1, 0, 1);
|
Pixmap MaskPixmap = XCreatePixmapFromBitmapData(myDisplay, myWindow, (char*)&MaskPixels[0], Width, Height, 1, 0, 1);
|
||||||
|
|
||||||
// Send our new icon to the window through the WMHints
|
// Send our new icon to the window through the WMHints
|
||||||
XWMHints* Hints = XAllocWMHints();
|
XWMHints* Hints = XAllocWMHints();
|
||||||
Hints->flags = IconPixmapHint | IconMaskHint;
|
Hints->flags = IconPixmapHint | IconMaskHint;
|
||||||
Hints->icon_pixmap = IconPixmap;
|
Hints->icon_pixmap = IconPixmap;
|
||||||
Hints->icon_mask = MaskPixmap;
|
Hints->icon_mask = MaskPixmap;
|
||||||
XSetWMHints(ourDisplay, myWindow, Hints);
|
XSetWMHints(myDisplay, myWindow, Hints);
|
||||||
XFree(Hints);
|
XFree(Hints);
|
||||||
|
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -552,10 +415,10 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode)
|
|||||||
{
|
{
|
||||||
// Check if the XRandR extension is present
|
// Check if the XRandR extension is present
|
||||||
int Version;
|
int Version;
|
||||||
if (XQueryExtension(ourDisplay, "RANDR", &Version, &Version, &Version))
|
if (XQueryExtension(myDisplay, "RANDR", &Version, &Version, &Version))
|
||||||
{
|
{
|
||||||
// Get the current configuration
|
// Get the current configuration
|
||||||
XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen));
|
XRRScreenConfiguration* Config = XRRGetScreenInfo(myDisplay, RootWindow(myDisplay, myScreen));
|
||||||
if (Config)
|
if (Config)
|
||||||
{
|
{
|
||||||
// Get the current rotation
|
// Get the current rotation
|
||||||
@ -573,10 +436,10 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode)
|
|||||||
if ((Sizes[i].width == static_cast<int>(Mode.Width)) && (Sizes[i].height == static_cast<int>(Mode.Height)))
|
if ((Sizes[i].width == static_cast<int>(Mode.Width)) && (Sizes[i].height == static_cast<int>(Mode.Height)))
|
||||||
{
|
{
|
||||||
// Switch to fullscreen mode
|
// Switch to fullscreen mode
|
||||||
XRRSetScreenConfig(ourDisplay, Config, RootWindow(ourDisplay, ourScreen), i, CurrentRotation, CurrentTime);
|
XRRSetScreenConfig(myDisplay, Config, RootWindow(myDisplay, myScreen), i, CurrentRotation, CurrentTime);
|
||||||
|
|
||||||
// Set "this" as the current fullscreen window
|
// Set "this" as the current fullscreen window
|
||||||
ourFullscreenWindow = this;
|
FullscreenWindow = this;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -599,124 +462,20 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Create the OpenGL rendering context
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool WindowImplX11::CreateContext(const VideoMode& Mode, XVisualInfo& ChosenVisual, WindowSettings& Params, XVisualInfo Template, unsigned long Mask)
|
|
||||||
{
|
|
||||||
// Get all the visuals matching the template
|
|
||||||
Template.screen = ourScreen;
|
|
||||||
int NbVisuals = 0;
|
|
||||||
XVisualInfo* Visuals = XGetVisualInfo(ourDisplay, Mask | VisualScreenMask, &Template, &NbVisuals);
|
|
||||||
if (!Visuals || (NbVisuals == 0))
|
|
||||||
{
|
|
||||||
if (Visuals)
|
|
||||||
XFree(Visuals);
|
|
||||||
std::cerr << "There is no valid visual for the selected screen" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the best visual
|
|
||||||
int BestScore = 0xFFFF;
|
|
||||||
XVisualInfo* BestVisual = NULL;
|
|
||||||
while (!BestVisual)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NbVisuals; ++i)
|
|
||||||
{
|
|
||||||
// Get the current visual attributes
|
|
||||||
int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA, &RGBA);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER, &DoubleBuffer);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE, &Red);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE, &Green);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE, &Blue);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE, &Alpha);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE, &Depth);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE, &Stencil);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
|
|
||||||
glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB, &Samples);
|
|
||||||
|
|
||||||
// First check the mandatory parameters
|
|
||||||
if ((RGBA == 0) || (DoubleBuffer == 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Evaluate the current configuration
|
|
||||||
int Color = Red + Green + Blue + Alpha;
|
|
||||||
int Score = EvaluateConfig(Mode, Params, Color, Depth, Stencil, MultiSampling ? Samples : 0);
|
|
||||||
|
|
||||||
// Keep it if it's better than the current best
|
|
||||||
if (Score < BestScore)
|
|
||||||
{
|
|
||||||
BestScore = Score;
|
|
||||||
BestVisual = &Visuals[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no visual has been found, try a lower level of antialiasing
|
|
||||||
if (!BestVisual)
|
|
||||||
{
|
|
||||||
if (Params.AntialiasingLevel > 2)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find a pixel format supporting "
|
|
||||||
<< Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
|
|
||||||
Params.AntialiasingLevel = 2;
|
|
||||||
}
|
|
||||||
else if (Params.AntialiasingLevel > 0)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
|
|
||||||
Params.AntialiasingLevel = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the OpenGL context
|
|
||||||
myGLContext = glXCreateContext(ourDisplay, BestVisual, glXGetCurrentContext(), true);
|
|
||||||
if (myGLContext == NULL)
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the creation settings from the chosen format
|
|
||||||
int Depth, Stencil;
|
|
||||||
glXGetConfig(ourDisplay, BestVisual, GLX_DEPTH_SIZE, &Depth);
|
|
||||||
glXGetConfig(ourDisplay, BestVisual, GLX_STENCIL_SIZE, &Stencil);
|
|
||||||
Params.DepthBits = static_cast<unsigned int>(Depth);
|
|
||||||
Params.StencilBits = static_cast<unsigned int>(Stencil);
|
|
||||||
|
|
||||||
// Assign the chosen visual, and free the temporary visuals array
|
|
||||||
ChosenVisual = *BestVisual;
|
|
||||||
XFree(Visuals);
|
|
||||||
|
|
||||||
// Activate the context
|
|
||||||
SetActive(true);
|
|
||||||
|
|
||||||
// Enable multisampling if needed
|
|
||||||
if (Params.AntialiasingLevel > 0)
|
|
||||||
glEnable(GL_MULTISAMPLE_ARB);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Do some common initializations after the window has been created
|
/// Do some common initializations after the window has been created
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::Initialize()
|
void WindowImplX11::Initialize()
|
||||||
{
|
{
|
||||||
// Get the atom defining the close event
|
// Get the atom defining the close event
|
||||||
myAtomClose = XInternAtom(ourDisplay, "WM_DELETE_WINDOW", false);
|
myAtomClose = XInternAtom(myDisplay, "WM_DELETE_WINDOW", false);
|
||||||
XSetWMProtocols(ourDisplay, myWindow, &myAtomClose, 1);
|
XSetWMProtocols(myDisplay, myWindow, &myAtomClose, 1);
|
||||||
|
|
||||||
// Create the input context
|
// Create the input context
|
||||||
if (ourInputMethod)
|
XIM InputMethod = myDisplayRef.GetInputMethod();
|
||||||
|
if (InputMethod)
|
||||||
{
|
{
|
||||||
myInputContext = XCreateIC(ourInputMethod,
|
myInputContext = XCreateIC(InputMethod,
|
||||||
XNClientWindow, myWindow,
|
XNClientWindow, myWindow,
|
||||||
XNFocusWindow, myWindow,
|
XNFocusWindow, myWindow,
|
||||||
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||||
@ -727,17 +486,14 @@ void WindowImplX11::Initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show the window
|
// Show the window
|
||||||
XMapWindow(ourDisplay, myWindow);
|
XMapWindow(myDisplay, myWindow);
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
|
|
||||||
// Create the hiden cursor
|
// Create the hiden cursor
|
||||||
CreateHiddenCursor();
|
CreateHiddenCursor();
|
||||||
|
|
||||||
// Set our context as the current OpenGL context for rendering
|
|
||||||
SetActive();
|
|
||||||
|
|
||||||
// Flush the commands queue
|
// Flush the commands queue
|
||||||
XFlush(ourDisplay);
|
XFlush(myDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -747,19 +503,19 @@ void WindowImplX11::Initialize()
|
|||||||
void WindowImplX11::CreateHiddenCursor()
|
void WindowImplX11::CreateHiddenCursor()
|
||||||
{
|
{
|
||||||
// Create the cursor's pixmap (1x1 pixels)
|
// Create the cursor's pixmap (1x1 pixels)
|
||||||
Pixmap CursorPixmap = XCreatePixmap(ourDisplay, myWindow, 1, 1, 1);
|
Pixmap CursorPixmap = XCreatePixmap(myDisplay, myWindow, 1, 1, 1);
|
||||||
GC GraphicsContext = XCreateGC(ourDisplay, CursorPixmap, 0, NULL);
|
GC GraphicsContext = XCreateGC(myDisplay, CursorPixmap, 0, NULL);
|
||||||
XDrawPoint(ourDisplay, CursorPixmap, GraphicsContext, 0, 0);
|
XDrawPoint(myDisplay, CursorPixmap, GraphicsContext, 0, 0);
|
||||||
XFreeGC(ourDisplay, GraphicsContext);
|
XFreeGC(myDisplay, GraphicsContext);
|
||||||
|
|
||||||
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
|
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
|
||||||
XColor Color;
|
XColor Color;
|
||||||
Color.flags = DoRed | DoGreen | DoBlue;
|
Color.flags = DoRed | DoGreen | DoBlue;
|
||||||
Color.red = Color.blue = Color.green = 0;
|
Color.red = Color.blue = Color.green = 0;
|
||||||
myHiddenCursor = XCreatePixmapCursor(ourDisplay, CursorPixmap, CursorPixmap, &Color, &Color, 0, 0);
|
myHiddenCursor = XCreatePixmapCursor(myDisplay, CursorPixmap, CursorPixmap, &Color, &Color, 0, 0);
|
||||||
|
|
||||||
// We don't need the pixmap any longer, free it
|
// We don't need the pixmap any longer, free it
|
||||||
XFreePixmap(ourDisplay, CursorPixmap);
|
XFreePixmap(myDisplay, CursorPixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -769,10 +525,10 @@ void WindowImplX11::CreateHiddenCursor()
|
|||||||
void WindowImplX11::CleanUp()
|
void WindowImplX11::CleanUp()
|
||||||
{
|
{
|
||||||
// Restore the previous video mode (in case we were running in fullscreen)
|
// Restore the previous video mode (in case we were running in fullscreen)
|
||||||
if (ourFullscreenWindow == this)
|
if (FullscreenWindow == this)
|
||||||
{
|
{
|
||||||
// Get current screen info
|
// Get current screen info
|
||||||
XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen));
|
XRRScreenConfiguration* Config = XRRGetScreenInfo(myDisplay, RootWindow(myDisplay, myScreen));
|
||||||
if (Config)
|
if (Config)
|
||||||
{
|
{
|
||||||
// Get the current rotation
|
// Get the current rotation
|
||||||
@ -780,25 +536,18 @@ void WindowImplX11::CleanUp()
|
|||||||
XRRConfigCurrentConfiguration(Config, &CurrentRotation);
|
XRRConfigCurrentConfiguration(Config, &CurrentRotation);
|
||||||
|
|
||||||
// Reset the video mode
|
// Reset the video mode
|
||||||
XRRSetScreenConfig(ourDisplay, Config, RootWindow(ourDisplay, ourScreen), myOldVideoMode, CurrentRotation, CurrentTime);
|
XRRSetScreenConfig(myDisplay, Config, RootWindow(myDisplay, myScreen), myOldVideoMode, CurrentRotation, CurrentTime);
|
||||||
|
|
||||||
// Free the configuration instance
|
// Free the configuration instance
|
||||||
XRRFreeScreenConfigInfo(Config);
|
XRRFreeScreenConfigInfo(Config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the fullscreen window
|
// Reset the fullscreen window
|
||||||
ourFullscreenWindow = NULL;
|
FullscreenWindow = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unhide the mouse cursor (in case it was hidden)
|
// Unhide the mouse cursor (in case it was hidden)
|
||||||
ShowMouseCursor(true);
|
ShowMouseCursor(true);
|
||||||
|
|
||||||
// Destroy the OpenGL context
|
|
||||||
if (myGLContext)
|
|
||||||
{
|
|
||||||
glXDestroyContext(ourDisplay, myGLContext);
|
|
||||||
myGLContext = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1165,57 +914,6 @@ Key::Code WindowImplX11::KeysymToSF(KeySym Sym)
|
|||||||
return Key::Code(0);
|
return Key::Code(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Open the display (if not already done)
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool WindowImplX11::OpenDisplay(bool AddWindow)
|
|
||||||
{
|
|
||||||
// If no display has been opened yet, open it
|
|
||||||
if (ourDisplay == NULL)
|
|
||||||
{
|
|
||||||
ourDisplay = XOpenDisplay(NULL);
|
|
||||||
if (ourDisplay)
|
|
||||||
{
|
|
||||||
ourScreen = DefaultScreen(ourDisplay);
|
|
||||||
|
|
||||||
// Get the input method (XIM) object
|
|
||||||
ourInputMethod = XOpenIM(ourDisplay, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Failed to open a connection with the X server" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increase the number of windows
|
|
||||||
if (AddWindow)
|
|
||||||
ourWindowsCount++;
|
|
||||||
|
|
||||||
return ourDisplay != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Close the display
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImplX11::CloseDisplay()
|
|
||||||
{
|
|
||||||
// Decrease the number of windows
|
|
||||||
ourWindowsCount--;
|
|
||||||
|
|
||||||
// If all windows have been destroyed, then we can close the display
|
|
||||||
if (ourWindowsCount == 0)
|
|
||||||
{
|
|
||||||
// Close the input method object
|
|
||||||
if (ourInputMethod)
|
|
||||||
XCloseIM(ourInputMethod);
|
|
||||||
|
|
||||||
XCloseDisplay(ourDisplay);
|
|
||||||
ourDisplay = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/Event.hpp>
|
#include <SFML/Window/Event.hpp>
|
||||||
#include <SFML/Window/WindowImpl.hpp>
|
#include <SFML/Window/WindowImpl.hpp>
|
||||||
|
#include <SFML/Window/Linux/DisplayRef.hpp>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <GL/glx.h>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -40,8 +40,6 @@ namespace sf
|
|||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
class VideoModeSupport;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// WindowImplX11 is the Linux (X11) implementation of WindowImpl
|
/// WindowImplX11 is the Linux (X11) implementation of WindowImpl
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -49,21 +47,13 @@ class WindowImplX11 : public WindowImpl
|
|||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Default constructor
|
|
||||||
/// (creates a dummy window to provide a valid OpenGL context)
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
WindowImplX11();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Construct the window implementation from an existing control
|
/// Construct the window implementation from an existing control
|
||||||
///
|
///
|
||||||
/// \param Handle : Platform-specific handle of the control
|
/// \param Handle : Platform-specific handle of the control
|
||||||
/// \param Params : Creation settings
|
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11(WindowHandle Handle, WindowSettings& Params);
|
WindowImplX11(WindowHandle Handle);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create the window implementation
|
/// Create the window implementation
|
||||||
@ -71,10 +61,9 @@ public :
|
|||||||
/// \param Mode : Video mode to use
|
/// \param Mode : Video mode to use
|
||||||
/// \param Title : Title of the window
|
/// \param Title : Title of the window
|
||||||
/// \param WindowStyle : Window style (resizable, fixed, or fullscren)
|
/// \param WindowStyle : Window style (resizable, fixed, or fullscren)
|
||||||
/// \param Params : Creation settings
|
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params);
|
WindowImplX11(VideoMode Mode, const std::string& Title, unsigned long WindowStyle);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Destructor
|
/// Destructor
|
||||||
@ -92,32 +81,12 @@ public :
|
|||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
friend class VideoModeSupport;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::Display
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
virtual void Display();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see WindowImpl::ProcessEvents
|
/// /see WindowImpl::ProcessEvents
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void ProcessEvents();
|
virtual void ProcessEvents();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::SetActive
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
virtual void SetActive(bool Active = true) const;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// /see WindowImpl::UseVerticalSync
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
virtual void UseVerticalSync(bool Enabled);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// /see WindowImpl::ShowMouseCursor
|
/// /see WindowImpl::ShowMouseCursor
|
||||||
///
|
///
|
||||||
@ -168,20 +137,6 @@ private :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SwitchToFullscreen(const VideoMode& Mode);
|
void SwitchToFullscreen(const VideoMode& Mode);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Create the OpenGL rendering context
|
|
||||||
///
|
|
||||||
/// \param Mode : Video mode to use
|
|
||||||
/// \param ChosenVisual : Visual that has been chosen for creating the contexte
|
|
||||||
/// \param Params : Creation parameters
|
|
||||||
/// \param Template : Visual infos to match
|
|
||||||
/// \param Mask : Visual attributes to check in Template
|
|
||||||
///
|
|
||||||
/// \return True on success, false on error
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool CreateContext(const VideoMode& Mode, XVisualInfo& ChosenVisual, WindowSettings& Params, XVisualInfo Template = XVisualInfo(), unsigned long Mask = 0);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Do some common initializations after the window has been created
|
/// Do some common initializations after the window has been created
|
||||||
///
|
///
|
||||||
@ -230,38 +185,14 @@ private :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static Key::Code KeysymToSF(KeySym Sym);
|
static Key::Code KeysymToSF(KeySym Sym);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Open the display (if not already done)
|
|
||||||
///
|
|
||||||
/// \param AddWindow : Tell whether or not we must increase the windows count
|
|
||||||
///
|
|
||||||
/// \return True if the display is properly opened
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static bool OpenDisplay(bool AddWindow = true);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Close the display
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static void CloseDisplay();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Static member data
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static ::Display* ourDisplay; ///< Current opened display
|
|
||||||
static int ourScreen; ///< Default screen on the opened display
|
|
||||||
static WindowImplX11* ourFullscreenWindow; ///< Keep track of the active fullscreen window
|
|
||||||
static unsigned int ourWindowsCount; ///< Number of windows created
|
|
||||||
static unsigned long ourEventMask; ///< Mask defining the events that will be caught by our windows
|
|
||||||
static XIM ourInputMethod; ///< Input object used to get unicode characters from keypress messages
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
DisplayRef myDisplayRef; ///< Connection to the X server
|
||||||
::Window myWindow; ///< X11 structure defining our window
|
::Window myWindow; ///< X11 structure defining our window
|
||||||
|
::Display* myDisplay; ///< Pointer to the display
|
||||||
|
int myScreen; ///< Screen identifier
|
||||||
bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
|
bool myIsExternal; ///< Tell whether the window has been created externally or by SFML
|
||||||
GLXContext myGLContext; ///< OpenGL context attached to the window
|
|
||||||
Atom myAtomClose; ///< Atom used to identify the close event
|
Atom myAtomClose; ///< Atom used to identify the close event
|
||||||
int myOldVideoMode; ///< Video mode in use before we switch to fullscreen
|
int myOldVideoMode; ///< Video mode in use before we switch to fullscreen
|
||||||
Cursor myHiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one
|
Cursor myHiddenCursor; ///< As X11 doesn't provide cursor hidding, we must create a transparent one
|
||||||
|
@ -53,7 +53,7 @@ myOwnsWindow(true)
|
|||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
if (myDC)
|
if (myDC)
|
||||||
CreateContext(Shared, VideoMode::GetMode(0).BitsPerPixel, ContextSettings(0, 0, 0));
|
CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0));
|
||||||
// ------------ TEMP ------------
|
// ------------ TEMP ------------
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user