mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-13 21:02:34 +08:00
Separated X11 fullscreen code detection from the output driver as they don't have to work at the same time
Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
84f6018e1a
commit
cc7ec0561d
@ -108,14 +108,19 @@ add_executable(
|
||||
src/WallpaperEngine/Render/Helpers/CContextAware.cpp
|
||||
src/WallpaperEngine/Render/Helpers/CContextAware.h
|
||||
|
||||
src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.cpp
|
||||
src/WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h
|
||||
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.cpp
|
||||
src/WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h
|
||||
|
||||
src/WallpaperEngine/Render/Drivers/Output/COutput.cpp
|
||||
src/WallpaperEngine/Render/Drivers/Output/COutput.h
|
||||
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
|
||||
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
|
||||
src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp
|
||||
src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h
|
||||
src/WallpaperEngine/Render/Drivers/COpenGLDriver.h
|
||||
src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp
|
||||
src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h
|
||||
src/WallpaperEngine/Render/Drivers/CX11OpenGLDriver.cpp
|
||||
src/WallpaperEngine/Render/Drivers/CVideoDriver.h
|
||||
src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp
|
||||
src/WallpaperEngine/Render/CRenderContext.h
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.h"
|
||||
#include "WallpaperEngine/Render/Drivers/Output/CX11Output.h"
|
||||
#include "WallpaperEngine/Application/CApplicationState.h"
|
||||
#include "WallpaperEngine/Render/Drivers/Detectors/CX11FullScreenDetector.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@ -65,7 +66,7 @@ namespace WallpaperEngine::Application
|
||||
);
|
||||
|
||||
// TODO: move this somewhere else?
|
||||
CVirtualContainer* virtualContainer = new CVirtualContainer ();
|
||||
auto* virtualContainer = new CVirtualContainer ();
|
||||
|
||||
//
|
||||
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
|
||||
@ -183,7 +184,7 @@ namespace WallpaperEngine::Application
|
||||
|
||||
Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg)
|
||||
{
|
||||
CCombinedContainer* container = new CCombinedContainer ();
|
||||
auto* container = new CCombinedContainer ();
|
||||
|
||||
this->setupContainer (*container, bg);
|
||||
|
||||
@ -269,22 +270,24 @@ namespace WallpaperEngine::Application
|
||||
// initialize audio context
|
||||
WallpaperEngine::Audio::CAudioContext audioContext (audioDriver);
|
||||
// initialize OpenGL driver
|
||||
WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine");
|
||||
WallpaperEngine::Render::Drivers::CX11OpenGLDriver videoDriver ("wallpaperengine");
|
||||
// initialize the input subsystem
|
||||
WallpaperEngine::Input::CInputContext inputContext (videoDriver);
|
||||
// output requested
|
||||
WallpaperEngine::Render::Drivers::Output::COutput* output;
|
||||
// fullscreen detector is common for the different render modes
|
||||
WallpaperEngine::Render::Drivers::Detectors::CX11FullScreenDetector fullscreenDetector (videoDriver);
|
||||
|
||||
// initialize the requested output
|
||||
switch (this->m_context.settings.render.mode)
|
||||
{
|
||||
case CApplicationContext::EXPLICIT_WINDOW:
|
||||
case CApplicationContext::NORMAL_WINDOW:
|
||||
output = new WallpaperEngine::Render::Drivers::Output::CGLFWWindowOutput (this->m_context, videoDriver);
|
||||
output = new WallpaperEngine::Render::Drivers::Output::CGLFWWindowOutput (this->m_context, videoDriver, fullscreenDetector);
|
||||
break;
|
||||
|
||||
case CApplicationContext::X11_BACKGROUND:
|
||||
output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver);
|
||||
output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver, fullscreenDetector);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||
#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h"
|
||||
|
||||
namespace WallpaperEngine::Application
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace WallpaperEngine::Audio
|
||||
/**
|
||||
* @return The audio context in use for this audio stream
|
||||
*/
|
||||
CAudioContext& getAudioContext () const;
|
||||
[[nodiscard]] CAudioContext& getAudioContext () const;
|
||||
|
||||
/**
|
||||
* @return to the codec context, which provides information on the audio stream's format
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "CInputContext.h"
|
||||
#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h"
|
||||
|
||||
using namespace WallpaperEngine::Input;
|
||||
using namespace WallpaperEngine::Render::Drivers;
|
||||
|
||||
CInputContext::CInputContext (COpenGLDriver& videoDriver) :
|
||||
CInputContext::CInputContext (CX11OpenGLDriver& videoDriver) :
|
||||
m_mouse (videoDriver.getWindow ())
|
||||
{
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h"
|
||||
#include "CMouseInput.h"
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers
|
||||
{
|
||||
class COpenGLDriver;
|
||||
class CX11OpenGLDriver;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Input
|
||||
@ -13,10 +13,10 @@ namespace WallpaperEngine::Input
|
||||
class CInputContext
|
||||
{
|
||||
public:
|
||||
explicit CInputContext (Render::Drivers::COpenGLDriver& videoDriver);
|
||||
explicit CInputContext (Render::Drivers::CX11OpenGLDriver& videoDriver);
|
||||
void update ();
|
||||
|
||||
const CMouseInput& getMouseInput () const;
|
||||
[[nodiscard]] const CMouseInput& getMouseInput () const;
|
||||
|
||||
private:
|
||||
CMouseInput m_mouse;
|
||||
|
@ -22,6 +22,7 @@ namespace WallpaperEngine::Input
|
||||
* The virtual pointer's position
|
||||
*/
|
||||
glm::dvec2 position;
|
||||
|
||||
private:
|
||||
/**
|
||||
* The GLFW window to get mouse position from
|
||||
|
@ -6,6 +6,7 @@ using namespace WallpaperEngine;
|
||||
using namespace WallpaperEngine::Render;
|
||||
|
||||
CObject::CObject(CScene* scene, std::string type, Core::CObject *object) :
|
||||
Helpers::CContextAware (scene),
|
||||
m_scene (scene),
|
||||
m_object (object),
|
||||
m_type (std::move (type))
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Render/Helpers/CContextAware.h"
|
||||
|
||||
#include "CScene.h"
|
||||
|
||||
@ -10,7 +11,7 @@ namespace WallpaperEngine::Render
|
||||
{
|
||||
class CScene;
|
||||
|
||||
class CObject
|
||||
class CObject : public Helpers::CContextAware
|
||||
{
|
||||
public:
|
||||
template<class T> const T* as () const { assert (is<T>()); return (const T*) this; }
|
||||
|
@ -8,6 +8,10 @@ namespace WallpaperEngine::Render::Drivers
|
||||
class CVideoDriver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @return The window handle used by this video driver
|
||||
*/
|
||||
virtual void* getWindowHandle () const = 0;
|
||||
/**
|
||||
* @return The time that has passed since the driver started
|
||||
*/
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include "COpenGLDriver.h"
|
||||
#include "CX11OpenGLDriver.h"
|
||||
#include "common.h"
|
||||
#include <FreeImage.h>
|
||||
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
using namespace WallpaperEngine::Render::Drivers;
|
||||
|
||||
void CustomGLFWErrorHandler (int errorCode, const char* reason)
|
||||
@ -9,7 +12,7 @@ void CustomGLFWErrorHandler (int errorCode, const char* reason)
|
||||
sLog.error ("GLFW error ", errorCode, ": ", reason);
|
||||
}
|
||||
|
||||
COpenGLDriver::COpenGLDriver (const char* windowTitle) :
|
||||
CX11OpenGLDriver::CX11OpenGLDriver (const char* windowTitle) :
|
||||
m_frameCounter (0)
|
||||
{
|
||||
glfwSetErrorCallback (CustomGLFWErrorHandler);
|
||||
@ -48,44 +51,49 @@ COpenGLDriver::COpenGLDriver (const char* windowTitle) :
|
||||
FreeImage_Initialise (TRUE);
|
||||
}
|
||||
|
||||
COpenGLDriver::~COpenGLDriver ()
|
||||
CX11OpenGLDriver::~CX11OpenGLDriver ()
|
||||
{
|
||||
glfwTerminate ();
|
||||
FreeImage_DeInitialise();
|
||||
}
|
||||
|
||||
float COpenGLDriver::getRenderTime () const
|
||||
void* CX11OpenGLDriver::getWindowHandle () const
|
||||
{
|
||||
return reinterpret_cast <void*> (glfwGetX11Window (this->m_window));
|
||||
}
|
||||
|
||||
float CX11OpenGLDriver::getRenderTime () const
|
||||
{
|
||||
return (float) glfwGetTime ();
|
||||
}
|
||||
|
||||
bool COpenGLDriver::closeRequested ()
|
||||
bool CX11OpenGLDriver::closeRequested ()
|
||||
{
|
||||
return glfwWindowShouldClose (this->m_window);
|
||||
}
|
||||
|
||||
void COpenGLDriver::resizeWindow (glm::ivec2 size)
|
||||
void CX11OpenGLDriver::resizeWindow (glm::ivec2 size)
|
||||
{
|
||||
glfwSetWindowSize (this->m_window, size.x, size.y);
|
||||
}
|
||||
|
||||
void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos)
|
||||
void CX11OpenGLDriver::resizeWindow (glm::ivec4 sizeandpos)
|
||||
{
|
||||
glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y);
|
||||
glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w);
|
||||
}
|
||||
|
||||
void COpenGLDriver::showWindow ()
|
||||
void CX11OpenGLDriver::showWindow ()
|
||||
{
|
||||
glfwShowWindow (this->m_window);
|
||||
}
|
||||
|
||||
void COpenGLDriver::hideWindow ()
|
||||
void CX11OpenGLDriver::hideWindow ()
|
||||
{
|
||||
glfwHideWindow (this->m_window);
|
||||
}
|
||||
|
||||
glm::ivec2 COpenGLDriver::getFramebufferSize () const
|
||||
glm::ivec2 CX11OpenGLDriver::getFramebufferSize () const
|
||||
{
|
||||
glm::ivec2 size;
|
||||
|
||||
@ -94,7 +102,7 @@ glm::ivec2 COpenGLDriver::getFramebufferSize () const
|
||||
return size;
|
||||
}
|
||||
|
||||
void COpenGLDriver::swapBuffers ()
|
||||
void CX11OpenGLDriver::swapBuffers ()
|
||||
{
|
||||
// do buffer swapping first
|
||||
glfwSwapBuffers (this->m_window);
|
||||
@ -104,12 +112,12 @@ void COpenGLDriver::swapBuffers ()
|
||||
this->m_frameCounter ++;
|
||||
}
|
||||
|
||||
uint32_t COpenGLDriver::getFrameCounter () const
|
||||
uint32_t CX11OpenGLDriver::getFrameCounter () const
|
||||
{
|
||||
return this->m_frameCounter;
|
||||
}
|
||||
|
||||
GLFWwindow* COpenGLDriver::getWindow ()
|
||||
GLFWwindow* CX11OpenGLDriver::getWindow ()
|
||||
{
|
||||
return this->m_window;
|
||||
}
|
@ -14,12 +14,13 @@ namespace WallpaperEngine::Render::Drivers
|
||||
{
|
||||
using namespace WallpaperEngine::Application;
|
||||
|
||||
class COpenGLDriver : public CVideoDriver
|
||||
class CX11OpenGLDriver : public CVideoDriver
|
||||
{
|
||||
public:
|
||||
explicit COpenGLDriver (const char* windowTitle);
|
||||
~COpenGLDriver();
|
||||
explicit CX11OpenGLDriver (const char* windowTitle);
|
||||
~CX11OpenGLDriver();
|
||||
|
||||
void* getWindowHandle () const;
|
||||
float getRenderTime () const override;
|
||||
bool closeRequested () override;
|
||||
void resizeWindow (glm::ivec2 size) override;
|
@ -0,0 +1 @@
|
||||
#include "CFullScreenDetector.h"
|
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers::Detectors
|
||||
{
|
||||
class CFullScreenDetector
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @return If anything is fullscreen
|
||||
*/
|
||||
[[nodiscard]] virtual bool anythingFullscreen () const = 0;
|
||||
|
||||
/**
|
||||
* Restarts the fullscreen detector, specially useful if there's any resources tied to the output driver
|
||||
*/
|
||||
virtual void reset () = 0;
|
||||
};
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
#include "CX11FullScreenDetector.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers::Detectors
|
||||
{
|
||||
void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
|
||||
{
|
||||
auto context = static_cast <CX11FullScreenDetector*> (userdata);
|
||||
|
||||
sLog.debugerror ("Critical XServer error detected. Attempting to recover...");
|
||||
|
||||
// refetch all the resources
|
||||
context->reset ();
|
||||
}
|
||||
|
||||
int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
|
||||
{
|
||||
sLog.debugerror ("Detected X error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CustomXIOErrorHandler (Display* dsp)
|
||||
{
|
||||
sLog.debugerror ("Detected X error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CX11FullScreenDetector::CX11FullScreenDetector (CVideoDriver& driver) :
|
||||
m_driver (driver)
|
||||
{
|
||||
// do not use previous handler, it might stop the app under weird circumstances
|
||||
// these handlers might be replaced by other X11-specific functionality, they
|
||||
// should only be used to ignore X11 errors and nothing else
|
||||
// so this doesn't affect functionality
|
||||
XSetErrorHandler (CustomXErrorHandler);
|
||||
XSetIOErrorHandler (CustomXIOErrorHandler);
|
||||
|
||||
this->initialize ();
|
||||
}
|
||||
|
||||
CX11FullScreenDetector::~CX11FullScreenDetector ()
|
||||
{
|
||||
this->stop ();
|
||||
}
|
||||
|
||||
bool CX11FullScreenDetector::anythingFullscreen () const
|
||||
{
|
||||
// stop rendering if anything is fullscreen
|
||||
bool isFullscreen = false;
|
||||
XWindowAttributes attribs;
|
||||
Window _;
|
||||
Window* children;
|
||||
unsigned int nchildren;
|
||||
|
||||
isFullscreen = false;
|
||||
|
||||
if (!XQueryTree (this->m_display, this->m_root, &_, &_, &children, &nchildren))
|
||||
return false;
|
||||
|
||||
auto ourWindow = reinterpret_cast <Window> (this->m_driver.getWindowHandle ());
|
||||
Window parentWindow;
|
||||
|
||||
{
|
||||
Window root, * schildren = NULL;
|
||||
unsigned int num_children;
|
||||
|
||||
if (!XQueryTree (m_display, ourWindow, &root, &parentWindow, &schildren, &num_children))
|
||||
return false;
|
||||
|
||||
if (schildren)
|
||||
XFree ((char*) children);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nchildren; i++)
|
||||
{
|
||||
if (!XGetWindowAttributes (this->m_display, children [i], &attribs))
|
||||
continue;
|
||||
|
||||
// ignore ourselves
|
||||
if (ourWindow == children [i] || parentWindow == children [i])
|
||||
continue;
|
||||
|
||||
if (attribs.map_state != IsViewable)
|
||||
continue;
|
||||
|
||||
// compare width and height with the different screens we have
|
||||
for (const auto& screen : this->m_screens)
|
||||
{
|
||||
if (
|
||||
attribs.x == screen.viewport.x && attribs.y == screen.viewport.y &&
|
||||
attribs.width == screen.viewport.z && attribs.height == screen.viewport.w
|
||||
)
|
||||
{
|
||||
isFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XFree (children);
|
||||
|
||||
return isFullscreen;
|
||||
}
|
||||
|
||||
void CX11FullScreenDetector::reset ()
|
||||
{
|
||||
this->stop ();
|
||||
this->initialize ();
|
||||
}
|
||||
|
||||
void CX11FullScreenDetector::initialize ()
|
||||
{
|
||||
this->m_display = XOpenDisplay (nullptr);
|
||||
|
||||
// set the error handling to try and recover from X disconnections
|
||||
#ifdef HAVE_XSETIOERROREXITHANDLER
|
||||
XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this);
|
||||
#endif /* HAVE_XSETIOERROREXITHANDLER */
|
||||
|
||||
int xrandr_result, xrandr_error;
|
||||
|
||||
if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error))
|
||||
{
|
||||
sLog.error ("XRandr is not present, fullscreen detection might not work");
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_root = DefaultRootWindow (this->m_display);
|
||||
XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, this->m_root);
|
||||
|
||||
if (screenResources == nullptr)
|
||||
{
|
||||
sLog.error ("Cannot detect screen sizes using xrandr, fullscreen detection might not work");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < screenResources->noutput; i ++)
|
||||
{
|
||||
XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]);
|
||||
|
||||
// screen not in use, ignore it
|
||||
if (info == nullptr || info->connection != RR_Connected)
|
||||
continue;
|
||||
|
||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc);
|
||||
|
||||
// add the screen to the list of screens
|
||||
this->m_screens.push_back (
|
||||
{
|
||||
{crtc->x, crtc->y, crtc->width, crtc->height},
|
||||
info->name
|
||||
}
|
||||
);
|
||||
|
||||
XRRFreeCrtcInfo (crtc);
|
||||
}
|
||||
|
||||
XRRFreeScreenResources (screenResources);
|
||||
}
|
||||
|
||||
void CX11FullScreenDetector::stop ()
|
||||
{
|
||||
if (this->m_display == nullptr)
|
||||
return;
|
||||
|
||||
XCloseDisplay (this->m_display);
|
||||
this->m_display = nullptr;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include "CFullScreenDetector.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers::Detectors
|
||||
{
|
||||
class CX11FullScreenDetector : public CFullScreenDetector
|
||||
{
|
||||
public:
|
||||
CX11FullScreenDetector (CVideoDriver& driver);
|
||||
~CX11FullScreenDetector ();
|
||||
|
||||
[[nodiscard]] bool anythingFullscreen () const override;
|
||||
void reset () override;
|
||||
|
||||
private:
|
||||
void initialize ();
|
||||
void stop ();
|
||||
|
||||
struct ScreenInfo
|
||||
{
|
||||
glm::ivec4 viewport;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
Display* m_display;
|
||||
Window m_root;
|
||||
std::vector <ScreenInfo> m_screens;
|
||||
CVideoDriver& m_driver;
|
||||
};
|
||||
}
|
@ -2,10 +2,14 @@
|
||||
#include "CGLFWWindowOutput.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#define FULLSCREEN_CHECK_WAIT_TIME 250
|
||||
|
||||
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||
|
||||
CGLFWWindowOutput::CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver) :
|
||||
COutput (context),
|
||||
CGLFWWindowOutput::CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector) :
|
||||
COutput (context, detector),
|
||||
m_driver (driver)
|
||||
{
|
||||
if (
|
||||
@ -75,4 +79,8 @@ void CGLFWWindowOutput::updateRender () const
|
||||
|
||||
// update the default viewport
|
||||
this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"};
|
||||
|
||||
// check for fullscreen windows and wait until there's none fullscreen
|
||||
while (this->m_detector.anythingFullscreen () && this->m_context.state.general.keepRunning)
|
||||
usleep (FULLSCREEN_CHECK_WAIT_TIME);
|
||||
}
|
@ -8,7 +8,7 @@ namespace WallpaperEngine::Render::Drivers::Output
|
||||
class CGLFWWindowOutput : public COutput
|
||||
{
|
||||
public:
|
||||
CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver);
|
||||
CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector);
|
||||
|
||||
void reset () override;
|
||||
bool renderVFlip () const override;
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||
|
||||
COutput::COutput (CApplicationContext& context) :
|
||||
m_context (context)
|
||||
COutput::COutput (CApplicationContext& context, Detectors::CFullScreenDetector& detector) :
|
||||
m_context (context),
|
||||
m_detector (detector)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <glm/vec4.hpp>
|
||||
|
||||
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||
#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h"
|
||||
|
||||
using namespace WallpaperEngine::Application;
|
||||
|
||||
@ -13,12 +14,17 @@ namespace WallpaperEngine::Application
|
||||
class CApplicationContext;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers::Detectors
|
||||
{
|
||||
class CFullScreenDetector;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Render::Drivers::Output
|
||||
{
|
||||
class COutput
|
||||
{
|
||||
public:
|
||||
COutput (CApplicationContext& context);
|
||||
COutput (CApplicationContext& context, Detectors::CFullScreenDetector& detector);
|
||||
|
||||
virtual void reset () = 0;
|
||||
|
||||
@ -43,5 +49,6 @@ namespace WallpaperEngine::Render::Drivers::Output
|
||||
mutable int m_fullHeight;
|
||||
mutable std::map <std::string, ScreenInfo> m_viewports;
|
||||
CApplicationContext& m_context;
|
||||
Detectors::CFullScreenDetector& m_detector;
|
||||
};
|
||||
}
|
@ -24,9 +24,6 @@ int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
|
||||
{
|
||||
sLog.debugerror ("Detected X error");
|
||||
|
||||
// call the original handler so we can keep some information reporting
|
||||
// originalErrorHandler (dpy, event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -37,8 +34,8 @@ int CustomXIOErrorHandler (Display* dsp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver) :
|
||||
COutput (context),
|
||||
CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector) :
|
||||
COutput (context, detector),
|
||||
m_driver (driver)
|
||||
{
|
||||
// do not use previous handler, it might stop the app under weird circumstances
|
||||
@ -59,6 +56,8 @@ void CX11Output::reset ()
|
||||
this->free ();
|
||||
// re-load screen info
|
||||
this->loadScreenInfo ();
|
||||
// do the same for the detector
|
||||
this->m_detector.reset ();
|
||||
}
|
||||
|
||||
void CX11Output::free ()
|
||||
@ -187,46 +186,7 @@ void CX11Output::updateRender () const
|
||||
XClearWindow(this->m_display, this->m_root);
|
||||
XFlush(this->m_display);
|
||||
|
||||
// stop rendering if anything is fullscreen
|
||||
bool isFullscreen = false;
|
||||
XWindowAttributes attribs;
|
||||
Window _;
|
||||
Window* children;
|
||||
unsigned int nchildren;
|
||||
|
||||
do
|
||||
{
|
||||
isFullscreen = false;
|
||||
|
||||
if (!XQueryTree (this->m_display, this->m_root, &_, &_, &children, &nchildren))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < nchildren; i++)
|
||||
{
|
||||
if (!XGetWindowAttributes (this->m_display, children [i], &attribs))
|
||||
continue;
|
||||
|
||||
if (attribs.map_state != IsViewable)
|
||||
continue;
|
||||
|
||||
// compare width and height with the different screens we have
|
||||
for (const auto& screen : this->m_screens)
|
||||
{
|
||||
if (
|
||||
attribs.x == screen.viewport.x && attribs.y == screen.viewport.y &&
|
||||
attribs.width == screen.viewport.z && attribs.height == screen.viewport.w
|
||||
)
|
||||
{
|
||||
isFullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XFree (children);
|
||||
|
||||
// give the cpu some time to check again later
|
||||
// check for fullscreen windows and wait until there's none fullscreen
|
||||
while (this->m_detector.anythingFullscreen () && this->m_context.state.general.keepRunning)
|
||||
usleep (FULLSCREEN_CHECK_WAIT_TIME);
|
||||
}
|
||||
while (isFullscreen && this->m_context.state.general.keepRunning);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace WallpaperEngine::Render::Drivers::Output
|
||||
class CX11Output : public COutput
|
||||
{
|
||||
public:
|
||||
CX11Output (CApplicationContext& context, CVideoDriver& driver);
|
||||
CX11Output (CApplicationContext& context, CVideoDriver& driver, Detectors::CFullScreenDetector& detector);
|
||||
~CX11Output ();
|
||||
|
||||
void reset () override;
|
||||
|
@ -7,6 +7,11 @@ namespace WallpaperEngine::Render::Helpers
|
||||
{
|
||||
}
|
||||
|
||||
CContextAware::CContextAware (CContextAware* from) :
|
||||
CContextAware (from->getContext ())
|
||||
{
|
||||
}
|
||||
|
||||
CContextAware::CContextAware (CRenderContext& context) :
|
||||
m_context (context)
|
||||
{
|
||||
|
@ -17,6 +17,10 @@ namespace WallpaperEngine::Render
|
||||
* @param from Object to get the render context from
|
||||
*/
|
||||
CContextAware (CContextAware& from);
|
||||
/**
|
||||
* @param from Object to get the render context from
|
||||
*/
|
||||
explicit CContextAware (CContextAware* from);
|
||||
explicit CContextAware (CRenderContext& context);
|
||||
|
||||
/**
|
||||
|
@ -81,7 +81,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
||||
else
|
||||
{
|
||||
// get the first texture on the first pass (this one represents the image assigned to this object)
|
||||
this->m_texture = this->getScene ()->getContext ().resolveTexture (textureName);
|
||||
this->m_texture = this->getContext ().resolveTexture (textureName);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -8,7 +8,7 @@ CSound::CSound (CScene* scene, Core::Objects::CSound* sound) :
|
||||
CObject (scene, Type, sound),
|
||||
m_sound (sound)
|
||||
{
|
||||
if (this->getScene ()->getContext ().getApp ().getContext ().settings.audio.enabled)
|
||||
if (this->getContext ().getApp ().getContext ().settings.audio.enabled)
|
||||
this->load ();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ using namespace WallpaperEngine::Render::Objects;
|
||||
using namespace WallpaperEngine::Render::Objects::Effects;
|
||||
|
||||
CMaterial::CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material) :
|
||||
Helpers::CContextAware (effect->getImage ()),
|
||||
m_effect (effect),
|
||||
m_material (material)
|
||||
{
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "WallpaperEngine/Render/Objects/Effects/CPass.h"
|
||||
#include "WallpaperEngine/Render/Objects/CEffect.h"
|
||||
|
||||
#include "WallpaperEngine/Render/Helpers/CContextAware.h"
|
||||
|
||||
#include "CPass.h"
|
||||
|
||||
using namespace WallpaperEngine;
|
||||
@ -20,16 +22,16 @@ namespace WallpaperEngine::Render::Objects::Effects
|
||||
{
|
||||
class CPass;
|
||||
|
||||
class CMaterial
|
||||
class CMaterial : public Helpers::CContextAware
|
||||
{
|
||||
friend class CPass;
|
||||
public:
|
||||
CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material);
|
||||
|
||||
const std::vector<CPass*>& getPasses () const;
|
||||
CImage* getImage () const;
|
||||
const Core::Objects::Images::CMaterial* getMaterial () const;
|
||||
const CEffect* getEffect () const;
|
||||
[[nodiscard]] const std::vector<CPass*>& getPasses () const;
|
||||
[[nodiscard]] CImage* getImage () const;
|
||||
[[nodiscard]] const Core::Objects::Images::CMaterial* getMaterial () const;
|
||||
[[nodiscard]] const CEffect* getEffect () const;
|
||||
|
||||
private:
|
||||
void generatePasses ();
|
||||
|
@ -23,6 +23,7 @@ using namespace WallpaperEngine::Render::Objects::Effects;
|
||||
extern float g_Time;
|
||||
|
||||
CPass::CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass) :
|
||||
Helpers::CContextAware (material),
|
||||
m_material (material),
|
||||
m_pass (pass)
|
||||
{
|
||||
@ -132,7 +133,7 @@ void CPass::render ()
|
||||
if (texture->isAnimated ())
|
||||
{
|
||||
// calculate current texture and frame
|
||||
double currentRenderTime = fmod (static_cast <double> (this->getMaterial ()->getImage ()->getScene ()->getContext ().getDriver ().getRenderTime ()), this->m_material->getImage ()->getAnimationTime ());
|
||||
double currentRenderTime = fmod (static_cast <double> (this->getContext ().getDriver ().getRenderTime ()), this->m_material->getImage ()->getAnimationTime ());
|
||||
|
||||
for (const auto& frameCur : texture->getFrames ())
|
||||
{
|
||||
@ -522,7 +523,7 @@ void CPass::setupUniforms ()
|
||||
textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName);
|
||||
}
|
||||
else
|
||||
textureRef = this->getMaterial ()->getImage ()->getScene ()->getContext ().resolveTexture (textureName);
|
||||
textureRef = this->getContext ().resolveTexture (textureName);
|
||||
|
||||
this->m_finalTextures.insert (std::make_pair ((*fragCur).first, textureRef));
|
||||
}
|
||||
@ -551,7 +552,7 @@ void CPass::setupUniforms ()
|
||||
textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName);
|
||||
}
|
||||
else
|
||||
textureRef = this->getMaterial ()->getImage ()->getScene ()->getContext ().resolveTexture (textureName);
|
||||
textureRef = this->getContext ().resolveTexture (textureName);
|
||||
|
||||
this->m_finalTextures.insert (std::make_pair ((*vertCur).first, textureRef));
|
||||
}
|
||||
@ -695,7 +696,7 @@ void CPass::setupTextures ()
|
||||
else
|
||||
{
|
||||
this->m_textures.emplace_back (
|
||||
this->m_material->getImage ()->getScene ()->getContext ().resolveTexture ((*cur))
|
||||
this->m_material->getImage ()->getContext ().resolveTexture ((*cur))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "WallpaperEngine/Assets/ITexture.h"
|
||||
#include "WallpaperEngine/Render/CFBO.h"
|
||||
|
||||
#include "WallpaperEngine/Render/Helpers/CContextAware.h"
|
||||
|
||||
namespace WallpaperEngine::Render::Objects::Effects
|
||||
{
|
||||
using namespace WallpaperEngine::Assets;
|
||||
@ -18,7 +20,7 @@ namespace WallpaperEngine::Render::Objects::Effects
|
||||
|
||||
class CMaterial;
|
||||
|
||||
class CPass
|
||||
class CPass : public Helpers::CContextAware
|
||||
{
|
||||
public:
|
||||
CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass);
|
||||
|
Loading…
Reference in New Issue
Block a user