Skip to content

Commit

Permalink
GLSupport: factor out common GLX & EGL X11-code
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Dec 4, 2021
1 parent 74d8457 commit 1e09063
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 371 deletions.
5 changes: 3 additions & 2 deletions RenderSystems/GLSupport/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,23 @@ elseif (APPLE)
elseif (UNIX)
if(OGRE_GLSUPPORT_USE_EGL)
file(GLOB PLATFORM_HEADERS "include/EGL/X11/*.h" "include/EGL/*.h")
file(GLOB PLATFORM_SOURCES "src/EGL/X11/*.cpp" "src/EGL/*.cpp")
file(GLOB PLATFORM_SOURCES "src/EGL/X11/*.cpp" "src/EGL/*.cpp" "src/X11/*.cpp")

set(NATIVE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/EGL
${CMAKE_CURRENT_SOURCE_DIR}/include/EGL/X11)
set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${EGL_LIBRARIES})
else()
file(GLOB PLATFORM_HEADERS "include/GLX/*.h")
file(GLOB PLATFORM_SOURCES "src/GLX/*.cpp")
file(GLOB PLATFORM_SOURCES "src/GLX/*.cpp" "src/X11/*.cpp")

set(NATIVE_INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/GLX
${OPENGL_INCLUDE_DIR})

set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${OPENGL_gl_LIBRARY})
endif()
list(APPEND NATIVE_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src/X11/")
endif ()

file(GLOB GLSUPPORT_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
Expand Down
58 changes: 6 additions & 52 deletions RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ THE SOFTWARE.

#include "OgreX11EGLSupport.h"
#include "OgreX11EGLWindow.h"
#include "OgreX11.h"

#include "OgreGLUtil.h"

#include <X11/extensions/Xrandr.h>

namespace Ogre {
GLNativeSupport* getGLSupport(int profile)
{
Expand All @@ -53,71 +52,30 @@ namespace Ogre {
// A connection that is NOT shared to enable independent event processing:
mNativeDisplay = getNativeDisplay();

int dummy;

if(mNativeDisplay == EGL_DEFAULT_DISPLAY)
{
// fake video mode
mCurrentMode.width = 0;
mCurrentMode.height = 0;
mCurrentMode.refreshRate = 0;
mOriginalMode = mCurrentMode;
mVideoModes.push_back(mCurrentMode);
}
else if (XQueryExtension(mNativeDisplay, "RANDR", &dummy, &dummy, &dummy))
else
{
XRRScreenConfiguration *screenConfig;

screenConfig = XRRGetScreenInfo(mNativeDisplay, DefaultRootWindow(mNativeDisplay));

if (screenConfig)
{
XRRScreenSize *screenSizes;
int nSizes = 0;
Rotation currentRotation;
int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, &currentRotation);

screenSizes = XRRConfigSizes(screenConfig, &nSizes);

mCurrentMode.width = screenSizes[currentSizeID].width;
mCurrentMode.height = screenSizes[currentSizeID].height;
mCurrentMode.refreshRate = XRRConfigCurrentRate(screenConfig);

mOriginalMode = mCurrentMode;

for (int sizeID = 0; sizeID < nSizes; sizeID++)
{
short *rates;
int nRates = 0;

rates = XRRConfigRates(screenConfig, sizeID, &nRates);

for (int rate = 0; rate < nRates; rate++)
{
VideoMode mode;

mode.width = screenSizes[sizeID].width;
mode.height = screenSizes[sizeID].height;
mode.refreshRate = rates[rate];

mVideoModes.push_back(mode);
}
}
XRRFreeScreenConfigInfo(screenConfig);
}
getXVideoModes(mNativeDisplay, mCurrentMode, mVideoModes);
}

if(mVideoModes.empty()) // none of the above worked
{
mCurrentMode.width = DisplayWidth(mNativeDisplay, DefaultScreen(mNativeDisplay));
mCurrentMode.height = DisplayHeight(mNativeDisplay, DefaultScreen(mNativeDisplay));
mCurrentMode.refreshRate = 0;

mOriginalMode = mCurrentMode;

mVideoModes.push_back(mCurrentMode);
}

mOriginalMode = mCurrentMode;

EGLConfig *glConfigs;
int config, nConfigs = 0;

Expand Down Expand Up @@ -156,17 +114,13 @@ namespace Ogre {
{
if (!mNativeDisplay)
{
mNativeDisplay = (NativeDisplayType)XOpenDisplay(NULL);
mNativeDisplay = getXDisplay(NULL, mAtomDeleteWindow, mAtomFullScreen, mAtomState);

if (mNativeDisplay == EGL_DEFAULT_DISPLAY)
{
LogManager::getSingleton().logWarning("Couldn't open X display");
return mNativeDisplay;
}

mAtomDeleteWindow = XInternAtom((Display*)mNativeDisplay, "WM_DELETE_WINDOW", True);
mAtomFullScreen = XInternAtom((Display*)mNativeDisplay, "_NET_WM_STATE_FULLSCREEN", True);
mAtomState = XInternAtom((Display*)mNativeDisplay, "_NET_WM_STATE", True);
}

return mNativeDisplay;
Expand Down
145 changes: 9 additions & 136 deletions RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,7 @@ THE SOFTWARE.

#include "OgreX11EGLSupport.h"
#include "OgreX11EGLWindow.h"

#include <iostream>
#include <algorithm>
#include <climits>

extern "C"
{
static int safeXErrorHandler(Display *display, XErrorEvent *event)
{
// Ignore all XErrorEvents
return 0;
}


int (*oldXErrorHandler)(Display *, XErrorEvent*);
}

#include "OgreX11.h"

namespace Ogre {
X11EGLWindow::X11EGLWindow(X11EGLSupport *glsupport)
Expand All @@ -63,19 +47,14 @@ namespace Ogre {

X11EGLWindow::~X11EGLWindow()
{

mNativeDisplay = mGLSupport->getNativeDisplay();
// Ignore fatal XErrorEvents from stale handles.
oldXErrorHandler = XSetErrorHandler(safeXErrorHandler);

if (mWindow && mIsTopLevel)
{
XDestroyWindow((Display*)mNativeDisplay, (Window)mWindow);
destroyXWindow(mNativeDisplay, mWindow);
}

XSetErrorHandler(oldXErrorHandler);
mWindow = 0;

}

void X11EGLWindow::getCustomAttribute( const String& name, void* pData )
Expand Down Expand Up @@ -138,23 +117,7 @@ namespace Ogre {
}
}

// Ignore fatal XErrorEvents during parameter validation:
oldXErrorHandler = XSetErrorHandler(safeXErrorHandler);

// Validate parentWindowHandle
if (mParentWindow != DefaultRootWindow((Display*)mNativeDisplay))
{
XWindowAttributes windowAttrib;

if (!XGetWindowAttributes((Display*)mNativeDisplay, mParentWindow, &windowAttrib) ||
windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay))
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"Invalid parentWindowHandle (wrong server or screen)");
}
}

XSetErrorHandler(oldXErrorHandler);
validateParentWindow(mNativeDisplay, mParentWindow);

mIsTopLevel = (!mIsExternal && mParentWindow == DefaultRootWindow((Display*)mNativeDisplay));

Expand All @@ -163,86 +126,15 @@ namespace Ogre {
void X11EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title )
{
mEglDisplay = mGLSupport->getGLDisplay();//todo
XSetWindowAttributes attr;
ulong mask;
XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig(mEglConfig);

attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap((Display*)mNativeDisplay,
DefaultRootWindow((Display*)mNativeDisplay),
visualInfo->visual,
AllocNone);
attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;

if(mIsFullScreen && mGLSupport->mAtomFullScreen == None)
{
LogManager::getSingleton().logMessage("X11EGLWindow::switchFullScreen: Your WM has no fullscreen support");

// A second best approach for outdated window managers
attr.backing_store = NotUseful;
attr.save_under = False;
attr.override_redirect = True;
mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect;
left = top = 0;
}

// Create window on server
mWindow = (NativeWindowType)XCreateWindow((Display*)mNativeDisplay,
mParentWindow,
left, top, width, height,
0, visualInfo->depth,
InputOutput,
visualInfo->visual, mask, &attr);
XFree(visualInfo);

if(!mWindow)
{
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
"Unable to create an X NativeWindowType",
"EGLWindow::create");
}
mWindow = createXWindow(mNativeDisplay, mParentWindow, visualInfo, left, top, width, height,
mGLSupport->mAtomFullScreen, mIsFullScreen);

if (mIsTopLevel)
{
XWMHints *wmHints;
XSizeHints *sizeHints;

// Is this really necessary ? Which broken WM might need it?
if ((wmHints = XAllocWMHints()) != NULL)
{
wmHints->initial_state = NormalState;
wmHints->input = True;
wmHints->flags = StateHint | InputHint;
}

// Is this really necessary ? Which broken WM might need it?
if ((sizeHints = XAllocSizeHints()) != NULL)
{
sizeHints->flags = USPosition;
}

XTextProperty titleprop;
char *lst = const_cast<char*>(title.c_str());
XStringListToTextProperty((char **)&lst, 1, &titleprop);
XSetWMProperties((Display*)mNativeDisplay, (Window)mWindow, &titleprop,
NULL, NULL, 0, sizeHints, wmHints, NULL);

XFree(titleprop.value);
XFree(wmHints);
XFree(sizeHints);

XSetWMProtocols((Display*)mNativeDisplay, (Window)mWindow, &mGLSupport->mAtomDeleteWindow, 1);

XWindowAttributes windowAttrib;

XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib);

left = windowAttrib.x;
top = windowAttrib.y;
width = windowAttrib.width;
height = windowAttrib.height;
finaliseTopLevel(mNativeDisplay, mWindow, left, top, width, height, title, mGLSupport->mAtomDeleteWindow);
}

mEglSurface = createSurfaceFromWindow(mGLSupport->getGLDisplay(), mWindow);
Expand Down Expand Up @@ -311,28 +203,9 @@ namespace Ogre {
if (mClosed || !mWindow)
return;

XWindowAttributes windowAttrib;

Window parent, root, *children;
uint nChildren;

XQueryTree((Display*)mNativeDisplay, (Window)mWindow, &root, &parent, &children, &nChildren);

if (children)
XFree(children);

XGetWindowAttributes((Display*)mNativeDisplay, parent, &windowAttrib);

if (mIsTopLevel && !mIsFullScreen)
{
// offset from window decorations
mLeft = windowAttrib.x;
mTop = windowAttrib.y;
// w/ h of the actual renderwindow
XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib);
}

resize(windowAttrib.width, windowAttrib.height);
uint width, height;
queryRect(mNativeDisplay, mWindow, mLeft, mTop, width, height, mIsTopLevel && !mIsFullScreen);
resize(width, height);
}
void X11EGLWindow::switchFullScreen(bool fullscreen)
{
Expand Down
Loading

0 comments on commit 1e09063

Please sign in to comment.