diff --git a/src/SFML/Window/Linux/ContextGLX.cpp b/src/SFML/Window/Linux/ContextGLX.cpp new file mode 100644 index 00000000..86fc7bbe --- /dev/null +++ b/src/SFML/Window/Linux/ContextGLX.cpp @@ -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 +#include +#include +#include +#include +#include + + +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(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("glXSwapIntervalSGI"); + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast(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(Depth); + mySettings.StencilBits = static_cast(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 diff --git a/src/SFML/Window/Linux/ContextGLX.hpp b/src/SFML/Window/Linux/ContextGLX.hpp new file mode 100644 index 00000000..09f9288c --- /dev/null +++ b/src/SFML/Window/Linux/ContextGLX.hpp @@ -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 +#include +#include +#include + + +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 diff --git a/src/SFML/Window/Linux/DisplayRef.cpp b/src/SFML/Window/Linux/DisplayRef.cpp new file mode 100644 index 00000000..97ddf150 --- /dev/null +++ b/src/SFML/Window/Linux/DisplayRef.cpp @@ -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 +#include + + +//////////////////////////////////////////////////////////// +// 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 diff --git a/src/SFML/Window/Linux/DisplayRef.hpp b/src/SFML/Window/Linux/DisplayRef.hpp new file mode 100644 index 00000000..cf8a28a0 --- /dev/null +++ b/src/SFML/Window/Linux/DisplayRef.hpp @@ -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 + + +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 diff --git a/src/SFML/Window/Linux/VideoModeSupport.cpp b/src/SFML/Window/Linux/VideoModeSupport.cpp index d3287020..7f9f5a66 100644 --- a/src/SFML/Window/Linux/VideoModeSupport.cpp +++ b/src/SFML/Window/Linux/VideoModeSupport.cpp @@ -26,7 +26,7 @@ // Headers //////////////////////////////////////////////////////////// #include -#include +#include #include #include #include @@ -45,17 +45,15 @@ void VideoModeSupport::GetSupportedVideoModes(std::vector& Modes) // First, clear array to fill Modes.clear(); - // Get the display and screen from sfWindowImplUnix - WindowImplX11::OpenDisplay(false); - Display* Disp = WindowImplX11::ourDisplay; - int Screen = WindowImplX11::ourScreen; + // Get an access to the display + DisplayRef Disp; // Check if the XRandR extension is present int Version; - if (XQueryExtension(Disp, "RANDR", &Version, &Version, &Version)) + if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version)) { // Get the current configuration - XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp, RootWindow(Disp, Screen)); + XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay()))); if (Config) { // Get the available screen sizes @@ -99,17 +97,15 @@ VideoMode VideoModeSupport::GetDesktopVideoMode() { VideoMode DesktopMode; - // Get the display and screen from sfWindowImplUnix - WindowImplX11::OpenDisplay(false); - Display* Disp = WindowImplX11::ourDisplay; - int Screen = WindowImplX11::ourScreen; + // Get an access to the display + DisplayRef Disp; // Check if the XRandR extension is present int Version; - if (XQueryExtension(Disp, "RANDR", &Version, &Version, &Version)) + if (XQueryExtension(Disp.GetDisplay(), "RANDR", &Version, &Version, &Version)) { // Get the current configuration - XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp, RootWindow(Disp, Screen)); + XRRScreenConfiguration* Config = XRRGetScreenInfo(Disp.GetDisplay(), RootWindow(Disp.GetDisplay(), DefaultScreen(Disp.GetDisplay()))); if (Config) { // Get the current video mode diff --git a/src/SFML/Window/Linux/WindowImplX11.cpp b/src/SFML/Window/Linux/WindowImplX11.cpp index 590f90af..897b1971 100644 --- a/src/SFML/Window/Linux/WindowImplX11.cpp +++ b/src/SFML/Window/Linux/WindowImplX11.cpp @@ -27,8 +27,6 @@ //////////////////////////////////////////////////////////// #include // important to be included first (conflict with None) #include -#include -#include #include #include #include @@ -37,89 +35,37 @@ #include +//////////////////////////////////////////////////////////// +// Private data +//////////////////////////////////////////////////////////// +namespace +{ + WindowImplX11* FullscreenWindow = NULL; + unsigned long EventMask = FocusChangeMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask | + EnterWindowMask | LeaveWindowMask; +} + + namespace sf { 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 //////////////////////////////////////////////////////////// -WindowImplX11::WindowImplX11(WindowHandle Handle, WindowSettings& Params) : +WindowImplX11::WindowImplX11(WindowHandle Handle) : myWindow (0), myIsExternal (true), -myGLContext (NULL), myAtomClose (0), myOldVideoMode(-1), myHiddenCursor(0), myInputContext(NULL), myKeyRepeat (true) { - // Open the display at first call - if (!OpenDisplay()) - return; + // Get the display and screen + myDisplay = myDisplayRef.GetDisplay(); + myScreen = DefaultScreen(myDisplay); // Save the window handle myWindow = Handle; @@ -128,7 +74,7 @@ myKeyRepeat (true) { // Get the window size XWindowAttributes WindowAttributes; - if (XGetWindowAttributes(ourDisplay, myWindow, &WindowAttributes) == 0) + if (XGetWindowAttributes(myDisplay, myWindow, &WindowAttributes) == 0) { std::cerr << "Failed to get the window attributes" << std::endl; return; @@ -136,24 +82,8 @@ myKeyRepeat (true) myWidth = WindowAttributes.width; 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 - XSelectInput(ourDisplay, myWindow, ourEventMask & ~ButtonPressMask); + XSelectInput(myDisplay, myWindow, EventMask & ~ButtonPressMask); // Do some common initializations Initialize(); @@ -164,7 +94,7 @@ myKeyRepeat (true) //////////////////////////////////////////////////////////// /// 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), myIsExternal (false), myGLContext (NULL), @@ -174,17 +104,13 @@ myHiddenCursor(0), myInputContext(NULL), myKeyRepeat (true) { - // Open the display at first call - if (!OpenDisplay()) - return; - // Compute position and size int Left, Top; bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0; if (!Fullscreen) { - Left = (DisplayWidth(ourDisplay, ourScreen) - Mode.Width) / 2; - Top = (DisplayHeight(ourDisplay, ourScreen) - Mode.Height) / 2; + Left = (DisplayWidth(myDisplay, myScreen) - Mode.Width) / 2; + Top = (DisplayHeight(myDisplay, myScreen) - Mode.Height) / 2; } else { @@ -198,23 +124,14 @@ myKeyRepeat (true) if (Fullscreen) 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 XSetWindowAttributes Attributes; - Attributes.event_mask = ourEventMask; - Attributes.colormap = ColMap; + Attributes.event_mask = EventMask; Attributes.override_redirect = Fullscreen; // Create the window - myWindow = XCreateWindow(ourDisplay, - RootWindow(ourDisplay, ourScreen), + myWindow = XCreateWindow(myDisplay, + RootWindow(myDisplay, myScreen), Left, Top, Width, Height, 0, @@ -229,12 +146,12 @@ myKeyRepeat (true) } // 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) if (!Fullscreen) { - Atom WMHintsAtom = XInternAtom(ourDisplay, "_MOTIF_WM_HINTS", false); + Atom WMHintsAtom = XInternAtom(myDisplay, "_MOTIF_WM_HINTS", false); if (WMHintsAtom) { static const unsigned long MWM_HINTS_FUNCTIONS = 1 << 0; @@ -286,7 +203,7 @@ myKeyRepeat (true) } const unsigned char* HintsPtr = reinterpret_cast(&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 @@ -296,7 +213,7 @@ myKeyRepeat (true) XSizeHints.flags = PMinSize | PMaxSize; XSizeHints.min_width = XSizeHints.max_width = Width; 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 if (Fullscreen) { - XGrabPointer(ourDisplay, myWindow, true, 0, GrabModeAsync, GrabModeAsync, myWindow, None, CurrentTime); - XGrabKeyboard(ourDisplay, myWindow, true, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabPointer(myDisplay, myWindow, true, 0, GrabModeAsync, GrabModeAsync, myWindow, None, CurrentTime); + XGrabKeyboard(myDisplay, myWindow, true, GrabModeAsync, GrabModeAsync, CurrentTime); } } @@ -322,38 +239,14 @@ WindowImplX11::~WindowImplX11() // Destroy the input context if (myInputContext) - { XDestroyIC(myInputContext); - } // Destroy the window if (myWindow && !myIsExternal) { - XDestroyWindow(ourDisplay, myWindow); - XFlush(ourDisplay); + XDestroyWindow(myDisplay, myWindow); + 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 XEvent Event; - while (XCheckIfEvent(ourDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast(myWindow))) + while (XCheckIfEvent(myDisplay, &Event, &WindowImplX11::CheckEvent, reinterpret_cast(myWindow))) { // Filter repeated key events if (Event.type == KeyRelease) { - if (XPending(ourDisplay)) + if (XPending(myDisplay)) { XEvent NextEvent; - XPeekEvent(ourDisplay, &NextEvent); + XPeekEvent(myDisplay, &NextEvent); if ((NextEvent.type == KeyPress) && (NextEvent.xkey.keycode == Event.xkey.keycode) && (NextEvent.xkey.time == Event.xkey.time)) { if (!myKeyRepeat) - XNextEvent(ourDisplay, &NextEvent); + XNextEvent(myDisplay, &NextEvent); 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("glXSwapIntervalSGI"); - PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = reinterpret_cast(glXGetProcAddress(ProcAddress)); - if (glXSwapIntervalSGI) - glXSwapIntervalSGI(Enabled ? 1 : 0); -} - - //////////////////////////////////////////////////////////// /// /see WindowImpl::ShowMouseCursor //////////////////////////////////////////////////////////// void WindowImplX11::ShowMouseCursor(bool Show) { - XDefineCursor(ourDisplay, myWindow, Show ? None : myHiddenCursor); - XFlush(ourDisplay); + XDefineCursor(myDisplay, myWindow, Show ? None : myHiddenCursor); + XFlush(myDisplay); } @@ -434,8 +297,8 @@ void WindowImplX11::ShowMouseCursor(bool Show) //////////////////////////////////////////////////////////// void WindowImplX11::SetCursorPosition(unsigned int Left, unsigned int Top) { - XWarpPointer(ourDisplay, None, myWindow, 0, 0, 0, 0, Left, Top); - XFlush(ourDisplay); + XWarpPointer(myDisplay, None, myWindow, 0, 0, 0, 0, Left, Top); + XFlush(myDisplay); } @@ -444,8 +307,8 @@ void WindowImplX11::SetCursorPosition(unsigned int Left, unsigned int Top) //////////////////////////////////////////////////////////// void WindowImplX11::SetPosition(int Left, int Top) { - XMoveWindow(ourDisplay, myWindow, Left, Top); - XFlush(ourDisplay); + XMoveWindow(myDisplay, myWindow, Left, Top); + XFlush(myDisplay); } @@ -454,8 +317,8 @@ void WindowImplX11::SetPosition(int Left, int Top) //////////////////////////////////////////////////////////// void WindowImplX11::SetSize(unsigned int Width, unsigned int Height) { - XResizeWindow(ourDisplay, myWindow, Width, Height); - XFlush(ourDisplay); + XResizeWindow(myDisplay, myWindow, Width, Height); + XFlush(myDisplay); } @@ -465,11 +328,11 @@ void WindowImplX11::SetSize(unsigned int Width, unsigned int Height) void WindowImplX11::Show(bool State) { if (State) - XMapWindow(ourDisplay, myWindow); + XMapWindow(myDisplay, myWindow); 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 - Visual* DefVisual = DefaultVisual(ourDisplay, ourScreen); - unsigned int DefDepth = DefaultDepth(ourDisplay, ourScreen); - XImage* IconImage = XCreateImage(ourDisplay, DefVisual, DefDepth, ZPixmap, 0, (char*)IconPixels, Width, Height, 32, 0); + Visual* DefVisual = DefaultVisual(myDisplay, myScreen); + unsigned int DefDepth = DefaultDepth(myDisplay, myScreen); + XImage* IconImage = XCreateImage(myDisplay, DefVisual, DefDepth, ZPixmap, 0, (char*)IconPixels, Width, Height, 32, 0); if (!IconImage) { std::cerr << "Failed to set the window's icon" << std::endl; return; } - Pixmap IconPixmap = XCreatePixmap(ourDisplay, RootWindow(ourDisplay, ourScreen), Width, Height, DefDepth); + Pixmap IconPixmap = XCreatePixmap(myDisplay, RootWindow(myDisplay, myScreen), Width, Height, DefDepth); XGCValues Values; - GC IconGC = XCreateGC(ourDisplay, IconPixmap, 0, &Values); - XPutImage(ourDisplay, IconPixmap, IconGC, IconImage, 0, 0, 0, 0, Width, Height); - XFreeGC(ourDisplay, IconGC); + GC IconGC = XCreateGC(myDisplay, IconPixmap, 0, &Values); + XPutImage(myDisplay, IconPixmap, IconGC, IconImage, 0, 0, 0, 0, Width, Height); + XFreeGC(myDisplay, IconGC); XDestroyImage(IconImage); // 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 XWMHints* Hints = XAllocWMHints(); Hints->flags = IconPixmapHint | IconMaskHint; Hints->icon_pixmap = IconPixmap; Hints->icon_mask = MaskPixmap; - XSetWMHints(ourDisplay, myWindow, Hints); + XSetWMHints(myDisplay, myWindow, Hints); XFree(Hints); - XFlush(ourDisplay); + XFlush(myDisplay); } @@ -552,10 +415,10 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode) { // Check if the XRandR extension is present int Version; - if (XQueryExtension(ourDisplay, "RANDR", &Version, &Version, &Version)) + if (XQueryExtension(myDisplay, "RANDR", &Version, &Version, &Version)) { // Get the current configuration - XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen)); + XRRScreenConfiguration* Config = XRRGetScreenInfo(myDisplay, RootWindow(myDisplay, myScreen)); if (Config) { // Get the current rotation @@ -573,10 +436,10 @@ void WindowImplX11::SwitchToFullscreen(const VideoMode& Mode) if ((Sizes[i].width == static_cast(Mode.Width)) && (Sizes[i].height == static_cast(Mode.Height))) { // 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 - ourFullscreenWindow = this; + FullscreenWindow = this; 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(Depth); - Params.StencilBits = static_cast(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 //////////////////////////////////////////////////////////// void WindowImplX11::Initialize() { // Get the atom defining the close event - myAtomClose = XInternAtom(ourDisplay, "WM_DELETE_WINDOW", false); - XSetWMProtocols(ourDisplay, myWindow, &myAtomClose, 1); + myAtomClose = XInternAtom(myDisplay, "WM_DELETE_WINDOW", false); + XSetWMProtocols(myDisplay, myWindow, &myAtomClose, 1); // Create the input context - if (ourInputMethod) + XIM InputMethod = myDisplayRef.GetInputMethod(); + if (InputMethod) { - myInputContext = XCreateIC(ourInputMethod, + myInputContext = XCreateIC(InputMethod, XNClientWindow, myWindow, XNFocusWindow, myWindow, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, @@ -727,17 +486,14 @@ void WindowImplX11::Initialize() } // Show the window - XMapWindow(ourDisplay, myWindow); - XFlush(ourDisplay); + XMapWindow(myDisplay, myWindow); + XFlush(myDisplay); // Create the hiden cursor CreateHiddenCursor(); - // Set our context as the current OpenGL context for rendering - SetActive(); - // Flush the commands queue - XFlush(ourDisplay); + XFlush(myDisplay); } @@ -747,19 +503,19 @@ void WindowImplX11::Initialize() void WindowImplX11::CreateHiddenCursor() { // Create the cursor's pixmap (1x1 pixels) - Pixmap CursorPixmap = XCreatePixmap(ourDisplay, myWindow, 1, 1, 1); - GC GraphicsContext = XCreateGC(ourDisplay, CursorPixmap, 0, NULL); - XDrawPoint(ourDisplay, CursorPixmap, GraphicsContext, 0, 0); - XFreeGC(ourDisplay, GraphicsContext); + Pixmap CursorPixmap = XCreatePixmap(myDisplay, myWindow, 1, 1, 1); + GC GraphicsContext = XCreateGC(myDisplay, CursorPixmap, 0, NULL); + XDrawPoint(myDisplay, CursorPixmap, GraphicsContext, 0, 0); + XFreeGC(myDisplay, GraphicsContext); // Create the cursor, using the pixmap as both the shape and the mask of the cursor - XColor Color; - Color.flags = DoRed | DoGreen | DoBlue; - Color.red = Color.blue = Color.green = 0; - myHiddenCursor = XCreatePixmapCursor(ourDisplay, CursorPixmap, CursorPixmap, &Color, &Color, 0, 0); + XColor Color; + Color.flags = DoRed | DoGreen | DoBlue; + Color.red = Color.blue = Color.green = 0; + myHiddenCursor = XCreatePixmapCursor(myDisplay, CursorPixmap, CursorPixmap, &Color, &Color, 0, 0); // 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() { // Restore the previous video mode (in case we were running in fullscreen) - if (ourFullscreenWindow == this) + if (FullscreenWindow == this) { // Get current screen info - XRRScreenConfiguration* Config = XRRGetScreenInfo(ourDisplay, RootWindow(ourDisplay, ourScreen)); + XRRScreenConfiguration* Config = XRRGetScreenInfo(myDisplay, RootWindow(myDisplay, myScreen)); if (Config) { // Get the current rotation @@ -780,25 +536,18 @@ void WindowImplX11::CleanUp() XRRConfigCurrentConfiguration(Config, &CurrentRotation); // 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 XRRFreeScreenConfigInfo(Config); } // Reset the fullscreen window - ourFullscreenWindow = NULL; + FullscreenWindow = NULL; } // Unhide the mouse cursor (in case it was hidden) 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); } - -//////////////////////////////////////////////////////////// -/// 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 sf diff --git a/src/SFML/Window/Linux/WindowImplX11.hpp b/src/SFML/Window/Linux/WindowImplX11.hpp index b4506fce..b81f92d5 100644 --- a/src/SFML/Window/Linux/WindowImplX11.hpp +++ b/src/SFML/Window/Linux/WindowImplX11.hpp @@ -30,8 +30,8 @@ //////////////////////////////////////////////////////////// #include #include +#include #include -#include #include #include @@ -40,8 +40,6 @@ namespace sf { namespace priv { -class VideoModeSupport; - //////////////////////////////////////////////////////////// /// WindowImplX11 is the Linux (X11) implementation of WindowImpl //////////////////////////////////////////////////////////// @@ -49,21 +47,13 @@ class WindowImplX11 : public WindowImpl { public : - //////////////////////////////////////////////////////////// - /// Default constructor - /// (creates a dummy window to provide a valid OpenGL context) - /// - //////////////////////////////////////////////////////////// - WindowImplX11(); - //////////////////////////////////////////////////////////// /// Construct the window implementation from an existing 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 @@ -71,10 +61,9 @@ public : /// \param Mode : Video mode to use /// \param Title : Title of the window /// \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 @@ -92,32 +81,12 @@ public : private : - friend class VideoModeSupport; - - //////////////////////////////////////////////////////////// - /// /see WindowImpl::Display - /// - //////////////////////////////////////////////////////////// - virtual void Display(); - //////////////////////////////////////////////////////////// /// /see WindowImpl::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 /// @@ -168,20 +137,6 @@ private : //////////////////////////////////////////////////////////// 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 /// @@ -230,38 +185,14 @@ private : //////////////////////////////////////////////////////////// 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 //////////////////////////////////////////////////////////// + DisplayRef myDisplayRef; ///< Connection to the X server ::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 - GLXContext myGLContext; ///< OpenGL context attached to the window Atom myAtomClose; ///< Atom used to identify the close event 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 diff --git a/src/SFML/Window/Win32/ContextWGL.cpp b/src/SFML/Window/Win32/ContextWGL.cpp index fee29477..4dcf563b 100644 --- a/src/SFML/Window/Win32/ContextWGL.cpp +++ b/src/SFML/Window/Win32/ContextWGL.cpp @@ -53,7 +53,7 @@ myOwnsWindow(true) // Create the context if (myDC) - CreateContext(Shared, VideoMode::GetMode(0).BitsPerPixel, ContextSettings(0, 0, 0)); + CreateContext(Shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); // ------------ TEMP ------------ }