From b69ce8ba577d17ff4281f310176d3a14b934dae4 Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Tue, 21 Mar 2023 07:07:36 +0100 Subject: [PATCH] Added support for running multiple X11 backgrounds off the same instance Window mode now has extra settings for setting the position and size Fixed audio not muting when --silent was used Signed-off-by: Alexis Maiquez --- CMakeLists.txt | 6 + .../Application/CApplicationContext.cpp | 63 +++- .../Application/CApplicationContext.h | 15 +- .../Application/CWallpaperApplication.cpp | 168 +++++++---- .../Application/CWallpaperApplication.h | 18 +- .../Assets/CCombinedContainer.cpp | 21 ++ .../Assets/CCombinedContainer.h | 1 + src/WallpaperEngine/Assets/CContainer.cpp | 5 + src/WallpaperEngine/Assets/CContainer.h | 9 + src/WallpaperEngine/Assets/CDirectory.cpp | 5 + src/WallpaperEngine/Assets/CDirectory.h | 1 + src/WallpaperEngine/Audio/CAudioContext.cpp | 1 - src/WallpaperEngine/Core/CObject.cpp | 2 +- src/WallpaperEngine/Core/CObject.h | 2 +- src/WallpaperEngine/Core/CProject.cpp | 6 +- src/WallpaperEngine/Core/CProject.h | 8 +- src/WallpaperEngine/Core/CScene.cpp | 6 +- src/WallpaperEngine/Core/CScene.h | 8 +- src/WallpaperEngine/Core/Objects/CEffect.cpp | 4 +- src/WallpaperEngine/Core/Objects/CEffect.h | 4 +- src/WallpaperEngine/Core/Objects/CImage.cpp | 2 +- src/WallpaperEngine/Core/Objects/CImage.h | 2 +- .../Core/Objects/CParticle.cpp | 4 +- src/WallpaperEngine/Core/Objects/CParticle.h | 2 +- .../Core/Objects/Images/CMaterial.cpp | 4 +- .../Core/Objects/Images/CMaterial.h | 4 +- src/WallpaperEngine/FileSystem/FileSystem.cpp | 4 +- src/WallpaperEngine/FileSystem/FileSystem.h | 2 +- src/WallpaperEngine/Render/CFBO.h | 1 + src/WallpaperEngine/Render/CObject.cpp | 2 +- src/WallpaperEngine/Render/CObject.h | 2 +- src/WallpaperEngine/Render/CRenderContext.cpp | 270 +++--------------- src/WallpaperEngine/Render/CRenderContext.h | 43 +-- src/WallpaperEngine/Render/CTextureCache.cpp | 24 +- src/WallpaperEngine/Render/CVideo.cpp | 5 +- src/WallpaperEngine/Render/CWallpaper.cpp | 4 +- src/WallpaperEngine/Render/CWallpaper.h | 2 +- .../Render/Drivers/COpenGLDriver.cpp | 6 + .../Render/Drivers/COpenGLDriver.h | 10 + .../Render/Drivers/CVideoDriver.h | 2 + .../Render/Drivers/Output/COutput.cpp | 23 ++ .../Render/Drivers/Output/COutput.h | 47 +++ .../Render/Drivers/Output/CWindowOutput.cpp | 77 +++++ .../Render/Drivers/Output/CWindowOutput.h | 25 ++ .../Render/Drivers/Output/CX11Output.cpp | 183 ++++++++++++ .../Render/Drivers/Output/CX11Output.h | 40 +++ src/WallpaperEngine/Render/Objects/CSound.cpp | 7 +- .../Render/Shaders/Compiler.cpp | 10 +- src/WallpaperEngine/Render/Shaders/Compiler.h | 4 +- 49 files changed, 787 insertions(+), 377 deletions(-) create mode 100644 src/WallpaperEngine/Render/Drivers/Output/COutput.cpp create mode 100644 src/WallpaperEngine/Render/Drivers/Output/COutput.h create mode 100644 src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp create mode 100644 src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h create mode 100644 src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp create mode 100644 src/WallpaperEngine/Render/Drivers/Output/CX11Output.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e6797e2..5f5f429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,12 @@ add_executable( src/WallpaperEngine/Render/Shaders/Compiler.h src/WallpaperEngine/Render/Shaders/Compiler.cpp + 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/CWindowOutput.cpp + src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h src/WallpaperEngine/Render/Drivers/COpenGLDriver.h src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp src/WallpaperEngine/Render/Drivers/CVideoDriver.h diff --git a/src/WallpaperEngine/Application/CApplicationContext.cpp b/src/WallpaperEngine/Application/CApplicationContext.cpp index 2665347..d288c9a 100644 --- a/src/WallpaperEngine/Application/CApplicationContext.cpp +++ b/src/WallpaperEngine/Application/CApplicationContext.cpp @@ -14,6 +14,8 @@ using namespace WallpaperEngine::Application; struct option long_options [] = { {"screen-root", required_argument, nullptr, 'r'}, + {"bg", required_argument, nullptr, 'b'}, + {"window", optional_argument, nullptr, 'w'}, {"pkg", required_argument, nullptr, 'p'}, {"dir", required_argument, nullptr, 'd'}, {"silent", no_argument, nullptr, 's'}, @@ -52,10 +54,21 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) : { int c; - while ((c = getopt_long (argc, argv, "r:p:d:shf:a:", long_options, nullptr)) != -1) + std::string lastScreen; + + while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w::", long_options, nullptr)) != -1) { switch (c) { + case 'b': + if (lastScreen.empty ()) + sLog.exception ("--bg has to go after a --screen-root argument"); + + // no need to check for previous screen being in the list, as it's the only way for this variable + // to have any value + this->screenSettings.insert_or_assign (lastScreen, this->validatePath (optarg)); + break; + case 'o': { std::string value = optarg; @@ -77,13 +90,41 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) : break; case 'r': - screens.emplace_back (optarg); + if (this->screenSettings.find (optarg) != this->screenSettings.end ()) + sLog.exception ("Cannot specify the same screen more than once: ", optarg); + if (this->windowMode == EXPLICIT_WINDOW) + sLog.exception ("Cannot run in both background and window mode"); + + this->windowMode = X11_BACKGROUND; + lastScreen = optarg; + this->screenSettings.insert_or_assign (lastScreen, ""); break; + case 'w': + if (this->windowMode == X11_BACKGROUND) + sLog.exception ("Cannot run in both background and window mode"); + + if (optarg != nullptr) + { + this->windowMode = EXPLICIT_WINDOW; + // read window geometry + char* pos = optarg; + + if (pos != nullptr) + this->windowGeometry.x = atoi (pos); + if ((pos = strchr (pos, '.')) != nullptr) + this->windowGeometry.y = atoi (pos + 1); + if ((pos = strchr (pos + 1, '.')) != nullptr) + this->windowGeometry.z = atoi (pos + 1); + if ((pos = strchr (pos + 1, '.')) != nullptr) + this->windowGeometry.w = atoi (pos + 1); + } + break; + case 'p': case 'd': sLog.error ("--dir/--pkg is deprecated and not used anymore"); - this->background = stringPathFixes (optarg); + this->background = this->validatePath (stringPathFixes (optarg)); break; case 's': @@ -110,6 +151,10 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) : this->takeScreenshot = true; this->screenshot = stringPathFixes (optarg); break; + + default: + sLog.out ("Default on path parsing: ", optarg); + break; } } @@ -117,7 +162,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) : { if (optind < argc && strlen (argv [optind]) > 0) { - this->background = argv [optind]; + this->background = this->validatePath (argv [optind]); } else { @@ -126,17 +171,16 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) : } // perform some extra validation on the inputs - this->validatePath (); this->validateAssets (); this->validateScreenshot (); } -void CApplicationContext::validatePath () +std::string CApplicationContext::validatePath (const std::string& path) { - if (this->background.find ('/') != std::string::npos) - return; + if (path.find ('/') == std::string::npos) + return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, path); - this->background = Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, this->background); + return path; } void CApplicationContext::validateAssets () @@ -191,6 +235,7 @@ void CApplicationContext::printHelp (const char* route) sLog.out ("\t--silent\t\t\t\t\tMutes all the sound the wallpaper might produce"); sLog.out ("\t--volume \t\t\tSets the volume for all the sounds in the background"); sLog.out ("\t--screen-root \tDisplay as screen's background"); + sLog.out ("\t--window \tRuns in window mode, geometry has to be XxYxWxH"); sLog.out ("\t--fps \t\t\tLimits the FPS to the given number, useful to keep battery consumption low"); sLog.out ("\t--assets-dir \t\t\tFolder where the assets are stored"); sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background"); diff --git a/src/WallpaperEngine/Application/CApplicationContext.h b/src/WallpaperEngine/Application/CApplicationContext.h index 9c3f47e..9dc6a0b 100644 --- a/src/WallpaperEngine/Application/CApplicationContext.h +++ b/src/WallpaperEngine/Application/CApplicationContext.h @@ -6,6 +6,8 @@ #include #include +#include + namespace WallpaperEngine::Application { class CApplicationContext @@ -13,7 +15,15 @@ namespace WallpaperEngine::Application public: CApplicationContext (int argc, char* argv[]); - std::vector screens; + enum WINDOW_MODE + { + NORMAL_WINDOW = 0, + X11_BACKGROUND = 1, + EXPLICIT_WINDOW = 2, + }; + + glm::ivec4 windowGeometry; + std::map screenSettings; std::map properties; std::string background; std::filesystem::path assets; @@ -24,9 +34,10 @@ namespace WallpaperEngine::Application bool audioEnabled; bool onlyListProperties; FREE_IMAGE_FORMAT screenshotFormat; + WINDOW_MODE windowMode; private: - void validatePath (); + std::string validatePath (const std::string& path); void validateAssets (); void validateScreenshot (); static void printHelp (const char* route); diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.cpp b/src/WallpaperEngine/Application/CWallpaperApplication.cpp index 763bdf2..59590ac 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.cpp +++ b/src/WallpaperEngine/Application/CWallpaperApplication.cpp @@ -5,9 +5,13 @@ #include "WallpaperEngine/Core/CVideo.h" #include "WallpaperEngine/Logging/CLog.h" #include "WallpaperEngine/Render/CRenderContext.h" +#include "WallpaperEngine/Render/Drivers/Output/CX11Output.h" +#include "WallpaperEngine/Render/Drivers/Output/CWindowOutput.h" +#include "Steam/FileSystem/FileSystem.h" #include + float g_Time; float g_TimeLast; bool g_KeepRunning = true; @@ -18,30 +22,32 @@ using namespace WallpaperEngine::Application; using namespace WallpaperEngine::Core; CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) : - m_context (context) + m_context (context), + m_defaultProject (nullptr) { // copy state to global variables for now g_AudioVolume = context.audioVolume; g_AudioEnabled = context.audioEnabled; - this->setupContainer (); - this->loadProject (); + this->loadProjects (); this->setupProperties (); } -void CWallpaperApplication::setupContainer () +void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const { - this->m_vfs.add (new CDirectory (this->m_context.background)); - this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "scene.pkg"); - this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "gifscene.pkg"); - this->m_vfs.add (new CDirectory (this->m_context.assets)); + std::filesystem::path basepath = bg; + + container.add (new CDirectory (basepath)); + container.addPkg (basepath / "scene.pkg"); + container.addPkg (basepath / "gifscene.pkg"); + container.add (new CDirectory (this->m_context.assets)); #if !NDEBUG - this->m_vfs.add (new CDirectory ("../share/")); + container.add (new CDirectory ("../share/")); #else this->m_vfs.add (new CDirectory (DATADIR)); #endif /* DEBUG */ // TODO: move this somewhere else? - CVirtualContainer* container = new CVirtualContainer (); + CVirtualContainer* virtualContainer = new CVirtualContainer (); // // Had to get a little creative with the effects to achieve the same bloom effect without any custom code @@ -50,7 +56,7 @@ void CWallpaperApplication::setupContainer () // // add the effect file for screen bloom - container->add ( + virtualContainer->add ( "effects/wpenginelinux/bloomeffect.json", "{" "\t\"name\":\"camerabloom_wpengine_linux\"," @@ -111,7 +117,7 @@ void CWallpaperApplication::setupContainer () ); // add some model for the image element even if it's going to waste rendering cycles - container->add ( + virtualContainer->add ( "models/wpenginelinux.json", "{" "\t\"material\":\"materials/wpenginelinux.json\"" @@ -119,7 +125,7 @@ void CWallpaperApplication::setupContainer () ); // models require materials, so add that too - container->add ( + virtualContainer->add ( "materials/wpenginelinux.json", "{" "\t\"passes\":" @@ -136,47 +142,74 @@ void CWallpaperApplication::setupContainer () "}" ); - this->m_vfs.add (container); + container.add (virtualContainer); } -void CWallpaperApplication::loadProject () +void CWallpaperApplication::loadProjects () { - this->m_project = CProject::fromFile ("project.json", this->m_vfs); - // go to the right folder so the videos will play - // TODO: stop doing chdir and use full path - if (this->m_project->getWallpaper ()->is ()) - chdir (this->m_context.background.c_str ()); + for (const auto& it : this->m_context.screenSettings) + { + // ignore the screen settings if there was no background specified + // the default will be used + if (it.second.empty()) + continue; + + this->m_projects.insert_or_assign ( + it.first, + this->loadProject (it.second) + ); + } + + // load the default project if required + if (!this->m_context.background.empty ()) + this->m_defaultProject = this->loadProject (this->m_context.background); +} + +CProject* CWallpaperApplication::loadProject (const std::string& bg) +{ + CCombinedContainer* container = new CCombinedContainer (); + + this->setupContainer (*container, bg); + + // TODO: Change this to pointer instead of reference + return CProject::fromFile ("project.json", container); +} + +void CWallpaperApplication::setupPropertiesForProject (CProject* project) +{ + // show properties if required + for (auto cur : project->getProperties ()) + { + // update the value of the property + auto override = this->m_context.properties.find (cur->getName ()); + + if (override != this->m_context.properties.end ()) + { + sLog.out ("Applying override value for ", cur->getName ()); + + cur->update (override->second); + } + + if (this->m_context.onlyListProperties) + sLog.out (cur->dump ()); + } } void CWallpaperApplication::setupProperties () { - // show properties if required - for (auto cur : this->m_project->getProperties ()) - { - // update the value of the property - auto override = this->m_context.properties.find (cur->getName ()); + for (const auto& it : this->m_projects) + this->setupPropertiesForProject (it.second); - if (override != this->m_context.properties.end ()) - { - sLog.out ("Applying override value for ", cur->getName ()); - - cur->update (override->second); - } - - if (this->m_context.onlyListProperties) - sLog.out (cur->dump ()); - } + if (this->m_defaultProject != nullptr) + this->setupPropertiesForProject (this->m_defaultProject); } -void CWallpaperApplication::takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format) +void CWallpaperApplication::takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format) { - GLint width, height; + // this should be getting called at the end of the frame, so the right thing should be bound already - // bind texture and get the size - glBindFramebuffer (GL_FRAMEBUFFER, wp->getWallpaperFramebuffer ()); - glBindTexture (GL_TEXTURE_2D, wp->getWallpaperTexture ()); - glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + int width = context.getOutput ()->getFullWidth (); + int height = context.getOutput ()->getFullHeight (); // make room for storing the pixel data uint8_t* buffer = new uint8_t [width * height * sizeof (uint8_t) * 3]; @@ -222,15 +255,42 @@ void CWallpaperApplication::show () // initialize audio context WallpaperEngine::Audio::CAudioContext audioContext (audioDriver); // initialize OpenGL driver - WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver (this->m_project->getTitle ().c_str ()); + WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine"); // initialize the input subsystem WallpaperEngine::Input::CInputContext inputContext (videoDriver); + // output requested + WallpaperEngine::Render::Drivers::Output::COutput* output; + + // initialize the requested output + switch (this->m_context.windowMode) + { + case CApplicationContext::EXPLICIT_WINDOW: + case CApplicationContext::NORMAL_WINDOW: + output = new WallpaperEngine::Render::Drivers::Output::CWindowOutput (this->m_context, videoDriver); + break; + + case CApplicationContext::X11_BACKGROUND: + output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver); + break; + } + // initialize render context - WallpaperEngine::Render::CRenderContext context (this->m_context.screens, videoDriver, inputContext, this->m_vfs, *this); - // ensure the context knows what wallpaper to render - context.setWallpaper ( - WallpaperEngine::Render::CWallpaper::fromWallpaper (this->m_project->getWallpaper (), context, audioContext) - ); + WallpaperEngine::Render::CRenderContext context (output, videoDriver, inputContext, *this); + + // set all the specific wallpapers required + for (const auto& it : this->m_projects) + { + context.setWallpaper ( + it.first, + WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), context, audioContext) + ); + } + + // set the default rendering wallpaper if available + if (this->m_defaultProject != nullptr) + context.setDefaultWallpaper ( + WallpaperEngine::Render::CWallpaper::fromWallpaper (this->m_defaultProject->getWallpaper (), context, audioContext) + ); float startTime, endTime, minimumTime = 1.0f / this->m_context.maximumFPS; @@ -255,7 +315,7 @@ void CWallpaperApplication::show () if (this->m_context.takeScreenshot && videoDriver.getFrameCounter () == 5) { - this->takeScreenshot (context.getWallpaper (), this->m_context.screenshot, this->m_context.screenshotFormat); + this->takeScreenshot (context, this->m_context.screenshot, this->m_context.screenshotFormat); // disable screenshot just in case the counter overflows this->m_context.takeScreenshot = false; } @@ -272,4 +332,14 @@ void CWallpaperApplication::show () void CWallpaperApplication::signal (int signal) { g_KeepRunning = false; +} + +const std::map & CWallpaperApplication::getProjects () const +{ + return this->m_projects; +} + +CProject* CWallpaperApplication::getDefaultProject () const +{ + return this->m_defaultProject; } \ No newline at end of file diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.h b/src/WallpaperEngine/Application/CWallpaperApplication.h index 55e9d18..99ac8a2 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.h +++ b/src/WallpaperEngine/Application/CWallpaperApplication.h @@ -5,10 +5,12 @@ #include "WallpaperEngine/Assets/CCombinedContainer.h" #include "WallpaperEngine/Core/CProject.h" #include "WallpaperEngine/Render/CWallpaper.h" +#include "WallpaperEngine/Render/CRenderContext.h" namespace WallpaperEngine::Render { class CWallpaper; + class CRenderContext; } namespace WallpaperEngine::Application @@ -22,15 +24,19 @@ namespace WallpaperEngine::Application void show (); void signal (int signal); + const std::map & getProjects () const; + Core::CProject* getDefaultProject () const; - private: - void setupContainer (); - void loadProject (); + private: + void setupContainer (CCombinedContainer& container, const std::string& bg) const; + void loadProjects (); + Core::CProject* loadProject (const std::string& bg); void setupProperties (); - void takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format); + void setupPropertiesForProject (Core::CProject* project); + void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format); - Core::CProject* m_project; + Core::CProject* m_defaultProject; CApplicationContext& m_context; - CCombinedContainer m_vfs; + std::map m_projects; }; } diff --git a/src/WallpaperEngine/Assets/CCombinedContainer.cpp b/src/WallpaperEngine/Assets/CCombinedContainer.cpp index 32ee7ef..4a48591 100644 --- a/src/WallpaperEngine/Assets/CCombinedContainer.cpp +++ b/src/WallpaperEngine/Assets/CCombinedContainer.cpp @@ -37,6 +37,27 @@ void CCombinedContainer::addPkg (const std::filesystem::path& path) } } + +std::filesystem::path CCombinedContainer::resolveRealFile (std::string filename) const +{ + for (auto cur : this->m_containers) + { + try + { + // try to read the file on the current container, if the file doesn't exists + // an exception will be thrown + return cur->resolveRealFile (filename); + } + catch (CAssetLoadException& ex) + { + // not found in this container, next try + } + } + + // no container was able to load the file, abort! + throw CAssetLoadException (filename, "Cannot resolve file in any of the containers"); +} + const void* CCombinedContainer::readFile (std::string filename, uint32_t* length) const { for (auto cur : this->m_containers) diff --git a/src/WallpaperEngine/Assets/CCombinedContainer.h b/src/WallpaperEngine/Assets/CCombinedContainer.h index af5435c..663eef1 100644 --- a/src/WallpaperEngine/Assets/CCombinedContainer.h +++ b/src/WallpaperEngine/Assets/CCombinedContainer.h @@ -21,6 +21,7 @@ namespace WallpaperEngine::Assets void add (CContainer* container); void addPkg (const std::filesystem::path& path); + std::filesystem::path resolveRealFile (std::string filename) const override; const void* readFile (std::string filename, uint32_t* length = nullptr) const override; private: diff --git a/src/WallpaperEngine/Assets/CContainer.cpp b/src/WallpaperEngine/Assets/CContainer.cpp index 144ac79..4eb5fa3 100644 --- a/src/WallpaperEngine/Assets/CContainer.cpp +++ b/src/WallpaperEngine/Assets/CContainer.cpp @@ -9,6 +9,11 @@ using namespace WallpaperEngine::Assets; +std::filesystem::path CContainer::resolveRealFile (std::string filename) const +{ + throw CAssetLoadException (filename, "Cannot resolve physical file in this container"); +} + const ITexture* CContainer::readTexture (std::string filename) const { // get the texture's filename (usually .tex) diff --git a/src/WallpaperEngine/Assets/CContainer.h b/src/WallpaperEngine/Assets/CContainer.h index e3d84fe..4426a56 100644 --- a/src/WallpaperEngine/Assets/CContainer.h +++ b/src/WallpaperEngine/Assets/CContainer.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "WallpaperEngine/Assets/ITexture.h" @@ -8,6 +9,14 @@ namespace WallpaperEngine::Assets class CContainer { public: + /** + * Resolves the full path to the specified file in the filesystem + * + * @param filename + * @return + */ + virtual std::filesystem::path resolveRealFile (std::string filename) const; + /** * Reads the given file from the container and returns it's data * Additionally sets a length parameter to return back the file's length diff --git a/src/WallpaperEngine/Assets/CDirectory.cpp b/src/WallpaperEngine/Assets/CDirectory.cpp index a40d088..97c479d 100644 --- a/src/WallpaperEngine/Assets/CDirectory.cpp +++ b/src/WallpaperEngine/Assets/CDirectory.cpp @@ -24,6 +24,11 @@ CDirectory::CDirectory (std::filesystem::path basepath) : CDirectory::~CDirectory () = default; +std::filesystem::path CDirectory::resolveRealFile (std::string filename) const +{ + return std::filesystem::path (this->m_basepath) / filename; +} + const void* CDirectory::readFile (std::string filename, uint32_t* length) const { std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename; diff --git a/src/WallpaperEngine/Assets/CDirectory.h b/src/WallpaperEngine/Assets/CDirectory.h index 589d42c..09cdf3f 100644 --- a/src/WallpaperEngine/Assets/CDirectory.h +++ b/src/WallpaperEngine/Assets/CDirectory.h @@ -16,6 +16,7 @@ namespace WallpaperEngine::Assets explicit CDirectory (std::filesystem::path basepath); ~CDirectory (); + std::filesystem::path resolveRealFile (std::string filename) const override; const void* readFile (std::string filename, uint32_t* length) const override; private: std::filesystem::path m_basepath; diff --git a/src/WallpaperEngine/Audio/CAudioContext.cpp b/src/WallpaperEngine/Audio/CAudioContext.cpp index f3af8cf..9b1947c 100644 --- a/src/WallpaperEngine/Audio/CAudioContext.cpp +++ b/src/WallpaperEngine/Audio/CAudioContext.cpp @@ -7,7 +7,6 @@ using namespace WallpaperEngine::Audio::Drivers; CAudioContext::CAudioContext (CAudioDriver& driver) : m_driver (driver) { - } void CAudioContext::addStream (CAudioStream* stream) diff --git a/src/WallpaperEngine/Core/CObject.cpp b/src/WallpaperEngine/Core/CObject.cpp index 3f2d101..7307f88 100644 --- a/src/WallpaperEngine/Core/CObject.cpp +++ b/src/WallpaperEngine/Core/CObject.cpp @@ -35,7 +35,7 @@ CObject::CObject ( { } -CObject* CObject::fromJSON (json data, CScene* scene, const CContainer& container) +CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container) { std::string json = data.dump (); diff --git a/src/WallpaperEngine/Core/CObject.h b/src/WallpaperEngine/Core/CObject.h index 962b67b..0ad7731 100644 --- a/src/WallpaperEngine/Core/CObject.h +++ b/src/WallpaperEngine/Core/CObject.h @@ -33,7 +33,7 @@ namespace WallpaperEngine::Core { friend class CScene; public: - static CObject* fromJSON (json data, CScene* scene, const CContainer& container); + static CObject* fromJSON (json data, CScene* scene, CContainer* container); template const T* as () const { assert (is ()); return (const T*) this; } template T* as () { assert (is ()); return (T*) this; } diff --git a/src/WallpaperEngine/Core/CProject.cpp b/src/WallpaperEngine/Core/CProject.cpp index 3c22c35..412c2f4 100644 --- a/src/WallpaperEngine/Core/CProject.cpp +++ b/src/WallpaperEngine/Core/CProject.cpp @@ -9,14 +9,14 @@ using namespace WallpaperEngine::Core; using namespace WallpaperEngine::Assets; -CProject::CProject (std::string title, std::string type, CContainer& container) : +CProject::CProject (std::string title, std::string type, CContainer* container) : m_title (std::move (title)), m_type (std::move (type)), m_container (container) { } -CProject* CProject::fromFile (const std::string& filename, CContainer& container) +CProject* CProject::fromFile (const std::string& filename, CContainer* container) { json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)); @@ -85,7 +85,7 @@ const std::vector& CProject::getProperties () const return this->m_properties; } -CContainer& CProject::getContainer () +CContainer* CProject::getContainer () { return this->m_container; } diff --git a/src/WallpaperEngine/Core/CProject.h b/src/WallpaperEngine/Core/CProject.h index 605354b..0c024cc 100644 --- a/src/WallpaperEngine/Core/CProject.h +++ b/src/WallpaperEngine/Core/CProject.h @@ -16,7 +16,7 @@ namespace WallpaperEngine::Core class CProject { public: - static CProject* fromFile (const std::string& filename, CContainer& container); + static CProject* fromFile (const std::string& filename, CContainer* container); CWallpaper* getWallpaper () const; @@ -24,10 +24,10 @@ namespace WallpaperEngine::Core const std::string& getType () const; const std::vector& getProperties () const; - CContainer& getContainer (); + CContainer* getContainer (); protected: - CProject (std::string title, std::string type, CContainer& container); + CProject (std::string title, std::string type, CContainer* container); void setWallpaper (CWallpaper* wallpaper); void insertProperty (Projects::CProperty* property); @@ -37,6 +37,6 @@ namespace WallpaperEngine::Core std::string m_title; std::string m_type; CWallpaper* m_wallpaper; - CContainer& m_container; + CContainer* m_container; }; } diff --git a/src/WallpaperEngine/Core/CScene.cpp b/src/WallpaperEngine/Core/CScene.cpp index 9014b30..6cbcf63 100644 --- a/src/WallpaperEngine/Core/CScene.cpp +++ b/src/WallpaperEngine/Core/CScene.cpp @@ -10,7 +10,7 @@ using namespace WallpaperEngine::Core; CScene::CScene ( CProject& project, - CContainer& container, + CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor, CUserSettingBoolean* bloom, @@ -52,7 +52,7 @@ CScene::CScene ( { } -CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer& container) +CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer* container) { std::string stringContent = WallpaperEngine::FileSystem::loadFullFile (filename, container); json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)); @@ -128,7 +128,7 @@ void CScene::insertObject (CObject* object) } } -CContainer& CScene::getContainer () +CContainer* CScene::getContainer () { return this->m_container; } diff --git a/src/WallpaperEngine/Core/CScene.h b/src/WallpaperEngine/Core/CScene.h index b7d0765..d327d7f 100644 --- a/src/WallpaperEngine/Core/CScene.h +++ b/src/WallpaperEngine/Core/CScene.h @@ -17,7 +17,7 @@ namespace WallpaperEngine::Core class CScene : public CWallpaper { public: - static CScene* fromFile (const std::string& filename, CProject& project, CContainer& container); + static CScene* fromFile (const std::string& filename, CProject& project, CContainer* container); const std::map& getObjects () const; const std::vector& getObjectsByRenderOrder () const; @@ -46,7 +46,7 @@ namespace WallpaperEngine::Core CScene ( CProject& project, - CContainer& container, + CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor, CUserSettingBoolean* bloom, @@ -71,9 +71,9 @@ namespace WallpaperEngine::Core void insertObject (CObject* object); - CContainer& getContainer (); + CContainer* getContainer (); private: - CContainer& m_container; + CContainer* m_container; Scenes::CCamera* m_camera; // data from general section on the json diff --git a/src/WallpaperEngine/Core/Objects/CEffect.cpp b/src/WallpaperEngine/Core/Objects/CEffect.cpp index 717e5d7..4cb2530 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Core/Objects/CEffect.cpp @@ -36,7 +36,7 @@ CEffect::CEffect ( { } -CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer& container) +CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container) { auto file_it = jsonFindRequired (data, "file", "Object effect must have a file"); auto effectpasses_it = data.find ("passes"); @@ -202,7 +202,7 @@ void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect->insertDependency (cur); } -void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer& container) +void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container) { for (const auto& cur : (*passes_it)) { diff --git a/src/WallpaperEngine/Core/Objects/CEffect.h b/src/WallpaperEngine/Core/Objects/CEffect.h index 6a15414..6d67ae6 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.h +++ b/src/WallpaperEngine/Core/Objects/CEffect.h @@ -35,7 +35,7 @@ namespace WallpaperEngine::Core::Objects CUserSettingBoolean* visible ); - static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer& container); + static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container); const std::vector& getDependencies () const; const std::vector& getMaterials () const; @@ -48,7 +48,7 @@ namespace WallpaperEngine::Core::Objects static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass); static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect); static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect); - static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer& container); + static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container); void insertDependency (const std::string& dep); void insertMaterial (Images::CMaterial* material); diff --git a/src/WallpaperEngine/Core/Objects/CImage.cpp b/src/WallpaperEngine/Core/Objects/CImage.cpp index fa9be7b..dc50ea9 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.cpp +++ b/src/WallpaperEngine/Core/Objects/CImage.cpp @@ -44,7 +44,7 @@ CImage::CImage ( WallpaperEngine::Core::CObject* CImage::fromJSON ( CScene* scene, json data, - const CContainer& container, + CContainer* container, CUserSettingBoolean* visible, uint32_t id, std::string name, diff --git a/src/WallpaperEngine/Core/Objects/CImage.h b/src/WallpaperEngine/Core/Objects/CImage.h index 409368c..4c775a5 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.h +++ b/src/WallpaperEngine/Core/Objects/CImage.h @@ -29,7 +29,7 @@ namespace WallpaperEngine::Core::Objects static CObject* fromJSON ( CScene* scene, json data, - const CContainer& container, + CContainer* container, CUserSettingBoolean* visible, uint32_t id, std::string name, diff --git a/src/WallpaperEngine/Core/Objects/CParticle.cpp b/src/WallpaperEngine/Core/Objects/CParticle.cpp index 6c5b014..61e1303 100644 --- a/src/WallpaperEngine/Core/Objects/CParticle.cpp +++ b/src/WallpaperEngine/Core/Objects/CParticle.cpp @@ -8,7 +8,7 @@ using namespace WallpaperEngine::Core::Objects; CParticle* CParticle::fromFile ( CScene* scene, const std::string& filename, - const CContainer& container, + CContainer* container, CUserSettingBoolean* visible, uint32_t id, std::string name, @@ -34,10 +34,8 @@ CParticle* CParticle::fromFile ( ); if (controlpoint_it != data.end ()) - { for (const auto& cur : (*controlpoint_it)) particle->insertControlPoint (Particles::CControlPoint::fromJSON (cur)); - } for (const auto& cur : (*emitter_it)) particle->insertEmitter (Particles::CEmitter::fromJSON (cur)); diff --git a/src/WallpaperEngine/Core/Objects/CParticle.h b/src/WallpaperEngine/Core/Objects/CParticle.h index 151ced8..ebb4c5e 100644 --- a/src/WallpaperEngine/Core/Objects/CParticle.h +++ b/src/WallpaperEngine/Core/Objects/CParticle.h @@ -19,7 +19,7 @@ namespace WallpaperEngine::Core::Objects static CParticle* fromFile ( CScene* scene, const std::string& filename, - const CContainer& container, + CContainer* container, CUserSettingBoolean* visible, uint32_t id, std::string name, diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp index 43da6a3..a85f348 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp @@ -16,13 +16,13 @@ CMaterial::CMaterial (std::string name) : { } -CMaterial* CMaterial::fromFile (const std::string& filename, const CContainer& container) +CMaterial* CMaterial::fromFile (const std::string& filename, CContainer* container) { return fromJSON ( filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)) ); } -CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, const CContainer& container) +CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container) { return fromJSON ( filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h index 2b044cb..5d2cc67 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h @@ -14,9 +14,9 @@ namespace WallpaperEngine::Core::Objects::Images class CMaterial { public: - static CMaterial* fromFile (const std::string& filename, const CContainer& container); + static CMaterial* fromFile (const std::string& filename, CContainer* container); static CMaterial* fromJSON (const std::string& name, json data); - static CMaterial* fromFile (const std::string& filename, const std::string& target, const CContainer& container); + static CMaterial* fromFile (const std::string& filename, const std::string& target, CContainer* container); static CMaterial* fromJSON (const std::string& name, json data, const std::string& target); void insertPass (Materials::CPass* mass); diff --git a/src/WallpaperEngine/FileSystem/FileSystem.cpp b/src/WallpaperEngine/FileSystem/FileSystem.cpp index 42c6aed..482a88b 100644 --- a/src/WallpaperEngine/FileSystem/FileSystem.cpp +++ b/src/WallpaperEngine/FileSystem/FileSystem.cpp @@ -5,10 +5,10 @@ using namespace WallpaperEngine; -std::string FileSystem::loadFullFile (const std::string& file, const WallpaperEngine::Assets::CContainer& containers) +std::string FileSystem::loadFullFile (const std::string& file, WallpaperEngine::Assets::CContainer* containers) { uint32_t length = 0; - const void* contents = containers.readFile (file, &length); + const void* contents = containers->readFile (file, &length); // build a new buffer that can fit in the string char* filedata = new char [length + 1]; diff --git a/src/WallpaperEngine/FileSystem/FileSystem.h b/src/WallpaperEngine/FileSystem/FileSystem.h index 46e2747..70668d2 100644 --- a/src/WallpaperEngine/FileSystem/FileSystem.h +++ b/src/WallpaperEngine/FileSystem/FileSystem.h @@ -17,5 +17,5 @@ namespace WallpaperEngine::FileSystem * @param file * @return */ - std::string loadFullFile (const std::string& file, const WallpaperEngine::Assets::CContainer& containers); + std::string loadFullFile (const std::string& file, WallpaperEngine::Assets::CContainer* containers); } diff --git a/src/WallpaperEngine/Render/CFBO.h b/src/WallpaperEngine/Render/CFBO.h index d7372f1..c99134f 100644 --- a/src/WallpaperEngine/Render/CFBO.h +++ b/src/WallpaperEngine/Render/CFBO.h @@ -12,6 +12,7 @@ namespace WallpaperEngine::Render { public: CFBO (std::string name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight); + // TODO: ADD DESTRUCTOR TO FREE RESOURCES const std::string& getName () const; const float& getScale () const; diff --git a/src/WallpaperEngine/Render/CObject.cpp b/src/WallpaperEngine/Render/CObject.cpp index f8184d3..10b74cd 100644 --- a/src/WallpaperEngine/Render/CObject.cpp +++ b/src/WallpaperEngine/Render/CObject.cpp @@ -20,7 +20,7 @@ CScene* CObject::getScene () const return this->m_scene; } -const CContainer& CObject::getContainer () const +CContainer* CObject::getContainer () const { return this->getScene ()->getContainer (); } diff --git a/src/WallpaperEngine/Render/CObject.h b/src/WallpaperEngine/Render/CObject.h index 0e787fb..8b84d3c 100644 --- a/src/WallpaperEngine/Render/CObject.h +++ b/src/WallpaperEngine/Render/CObject.h @@ -21,7 +21,7 @@ namespace WallpaperEngine::Render virtual void render () = 0; CScene* getScene () const; - const CContainer& getContainer () const; + CContainer* getContainer () const; int getId () const; protected: diff --git a/src/WallpaperEngine/Render/CRenderContext.cpp b/src/WallpaperEngine/Render/CRenderContext.cpp index 4f8439d..e3f706b 100644 --- a/src/WallpaperEngine/Render/CRenderContext.cpp +++ b/src/WallpaperEngine/Render/CRenderContext.cpp @@ -12,190 +12,39 @@ #include "CRenderContext.h" #include "CVideo.h" -#define DEFAULT_WINDOW_WIDTH 1280 -#define DEFAULT_WINDOW_HEIGHT 720 - using namespace WallpaperEngine::Render; -XErrorHandler originalErrorHandler; - -void CustomXIOErrorExitHandler (Display* dsp, void* userdata) +CRenderContext::CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app) : + m_defaultWallpaper (nullptr), + m_output (output), + m_driver (driver), + m_app (app), + m_input (input), + m_textureCache (new CTextureCache (*this)) { - auto context = static_cast (userdata); - -#if !NDEBUG - sLog.debugerror ("Critical XServer error detected. Attempting to recover..."); -#endif /* DEBUG */ - - // refetch all the resources - context->initialize (); } -int CustomXErrorHandler (Display* dpy, XErrorEvent* event) +void CRenderContext::render () { -#if !NDEBUG - sLog.debugerror ("Detected X error"); -#endif /* DEBUG */ + bool firstFrame = true; + bool renderFrame = true; - // call the original handler so we can keep some information reporting - originalErrorHandler (dpy, event); - - return 0; -} - -int CustomXIOErrorHandler (Display* dsp) -{ -#if !NDEBUG - sLog.debugerror ("Detected X error"); -#endif /* DEBUG */ - - return 0; -} - -CRenderContext::CRenderContext (std::vector screens, CVideoDriver& driver, CInputContext& input, CContainer& container, CWallpaperApplication& app) : - m_wallpaper (nullptr), - m_screens (std::move (screens)), - m_driver (driver), - m_container (container), - m_app (app), - m_input (input), - m_textureCache (new CTextureCache (*this)), - m_display (nullptr), - m_pixmap (0), - m_gc (nullptr), - m_image (nullptr), - m_imageData (nullptr), - m_fbo (nullptr) -{ - this->initialize (); -} - -void CRenderContext::initialize () -{ - if (this->m_screens.empty ()) - this->setupWindow (); - else - this->setupScreens (); -} - -void CRenderContext::setupWindow () -{ - this->m_driver.showWindow (); - this->m_driver.resizeWindow ({DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT}); -} - -void CRenderContext::setupScreens () -{ - this->m_viewports.clear (); - - 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 */ - originalErrorHandler = XSetErrorHandler (CustomXErrorHandler); - XSetIOErrorHandler (CustomXIOErrorHandler); - - int xrandr_result, xrandr_error; - - if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error)) - { - sLog.error ("XRandr is not present, cannot detect specified screens, running in window mode"); - return; - } - - Window root = DefaultRootWindow (this->m_display); - int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); - int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); - XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, DefaultRootWindow (this->m_display)); - - // there are some situations where xrandr returns null (like screen not using the extension) - if (screenResources == nullptr) - return; - - // create the pixmap and gc used for this display, most situations only have one "display" - this->m_pixmap = XCreatePixmap (this->m_display, DefaultRootWindow (this->m_display), fullWidth, fullHeight, 24); - this->m_gc = XCreateGC (this->m_display, this->m_pixmap, 0, nullptr); - // fill the whole pixmap with black for now - XFillRectangle (this->m_display, this->m_pixmap, this->m_gc, 0, 0, fullWidth, fullHeight); - - for (int i = 0; i < screenResources->noutput; i ++) - { - XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]); - - // there are some situations where xrandr returns null (like screen not using the extension) - if (info == nullptr || info->connection != RR_Connected) - continue; - - for (const auto& cur : this->m_screens) - { - if (strcmp (info->name, cur.c_str ()) != 0) - continue; - - XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc); - - sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height); - - this->m_viewports.push_back ({{crtc->x, crtc->y, crtc->width, crtc->height}, cur}); - - XRRFreeCrtcInfo (crtc); - } - - XRRFreeOutputInfo (info); - } - - XRRFreeScreenResources (screenResources); - - // create the fbo that will handle the screen - this->m_fbo = new CFBO( - "_sc_FullFrameBuffer", - ITexture::TextureFormat::ARGB8888, - ITexture::TextureFlags::NoFlags, - 1.0, - fullWidth, fullHeight, - fullWidth, fullHeight - ); - - // set the window background so the pixmap is drawn - XSetWindowBackgroundPixmap(this->m_display, root, this->m_pixmap); - - this->m_imageData = new char [fullWidth * fullHeight * 4]; - - // create the image for X11 to be able to copy it over - this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, fullWidth, fullHeight, 32, 0); -} - -CRenderContext::~CRenderContext () -{ - if (!this->m_screens.empty ()) - { - // free any used resource - XDestroyImage (this->m_image); - XFreeGC (this->m_display, this->m_gc); - XFreePixmap (this->m_display, this->m_pixmap); - XCloseDisplay (this->m_display); - } -} - -void CRenderContext::renderScreens () -{ - bool firstFrame = true; - bool renderFrame = true; - int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); - int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); - Window root = DefaultRootWindow (this->m_display); - - for (const auto& cur : this->m_viewports) + for (const auto& cur : this->m_output->getViewports ()) { #if !NDEBUG - std::string str = "Rendering to screen " + cur.name; + std::string str = "Rendering to output " + cur.first; glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ()); #endif /* DEBUG */ - // render the background - this->m_wallpaper->render (cur.viewport, false, renderFrame, firstFrame); + // search the background in the viewport selection + auto ref = this->m_wallpapers.find (cur.first); + + // render the background + if (ref != this->m_wallpapers.end ()) + ref->second->render (cur.second.viewport, this->m_output->renderVFlip (), renderFrame, firstFrame); + else + this->m_defaultWallpaper->render (cur.second.viewport, this->m_output->renderVFlip (), renderFrame, firstFrame); // scenes need to render a new frame for each viewport as they produce different results // but videos should only be rendered once per group of viewports firstFrame = false; @@ -205,61 +54,27 @@ void CRenderContext::renderScreens () } // read the full texture into the image - glReadPixels (0, 0, fullWidth, fullHeight, GL_BGRA, GL_UNSIGNED_BYTE, (void*) this->m_imageData); - - // put the image back into the screen - XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, fullWidth, fullHeight); - - // _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to - // edit the background. Without these, other programs will clear the screen. - // it also forces the compositor to refresh the background (tested with picom) - Atom prop_root = XInternAtom(this->m_display, "_XROOTPMAP_ID", False); - Atom prop_esetroot = XInternAtom(this->m_display, "ESETROOT_PMAP_ID", False); - XChangeProperty(this->m_display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); - XChangeProperty(this->m_display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); - - XClearWindow(this->m_display, root); - XFlush(this->m_display); -} - -void CRenderContext::renderWindow () -{ - // render the background to the window directly - this->m_wallpaper->render ({0, 0, this->m_driver.getFramebufferSize ()}, true); -} - -void CRenderContext::render () -{ - if (this->m_wallpaper == nullptr) - return; - - if (this->m_viewports.empty ()) - this->renderWindow (); - else - this->renderScreens (); + if (this->m_output->haveImageBuffer ()) + glReadPixels ( + 0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (), + GL_BGRA, GL_UNSIGNED_BYTE, + this->m_output->getImageBuffer () + ); + // update the output with the given image + this->m_output->updateRender (); + // finally swap buffers this->m_driver.swapBuffers (); } -void CRenderContext::setWallpaper (CWallpaper* wallpaper) +void CRenderContext::setDefaultWallpaper (CWallpaper* wallpaper) { - this->m_wallpaper = wallpaper; + this->m_defaultWallpaper = wallpaper; +} - // update the wallpaper's texcoords based on the mode we're running - if (!this->m_screens.empty ()) - { - GLfloat texCoords [] = { - 0.0f, 1.0f, - 1.0f, 1.0f, - 0.0f, 0.0f, - 0.0f, 0.0f, - 1.0f, 1.0f, - 1.0f, 0.0f - }; - - this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords)); - this->m_wallpaper->setDestinationFramebuffer (this->m_fbo->getFramebuffer ()); - } +void CRenderContext::setWallpaper (const std::string& display, CWallpaper* wallpaper) +{ + this->m_wallpapers.insert_or_assign (display, wallpaper); } CInputContext& CRenderContext::getInputContext () const @@ -267,21 +82,16 @@ CInputContext& CRenderContext::getInputContext () const return this->m_input; } -CWallpaper* CRenderContext::getWallpaper () const -{ - return this->m_wallpaper; -} - -const CContainer& CRenderContext::getContainer () const -{ - return this->m_container; -} - const CWallpaperApplication& CRenderContext::getApp () const { return this->m_app; } +const COutput* CRenderContext::getOutput () const +{ + return this->m_output; +} + const ITexture* CRenderContext::resolveTexture (const std::string& name) { return this->m_textureCache->resolve (name); diff --git a/src/WallpaperEngine/Render/CRenderContext.h b/src/WallpaperEngine/Render/CRenderContext.h index 56ee581..d7881d3 100644 --- a/src/WallpaperEngine/Render/CRenderContext.h +++ b/src/WallpaperEngine/Render/CRenderContext.h @@ -9,12 +9,19 @@ #include "WallpaperEngine/Input/CInputContext.h" #include "WallpaperEngine/Input/CMouseInput.h" #include "WallpaperEngine/Render/Drivers/CVideoDriver.h" +#include "WallpaperEngine/Render/Drivers/Output/COutput.h" #include using namespace WallpaperEngine::Application; using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Input; using namespace WallpaperEngine::Render::Drivers; +using namespace WallpaperEngine::Render::Drivers::Output; + +namespace WallpaperEngine::Render::Drivers::Output +{ + class COutput; +} namespace WallpaperEngine::Render::Drivers { @@ -34,45 +41,23 @@ namespace WallpaperEngine::Render class CRenderContext { public: - CRenderContext (std::vector screens, CVideoDriver& driver, CInputContext& input, CContainer& container, CWallpaperApplication& app); - ~CRenderContext (); + CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app); - void initialize (); void render (); - void setWallpaper (CWallpaper* wallpaper); + void setDefaultWallpaper (CWallpaper* wallpaper); + void setWallpaper (const std::string& display, CWallpaper* wallpaper); CInputContext& getInputContext () const; - void setMouse (CMouseInput* mouse); - CWallpaper* getWallpaper () const; - const CContainer& getContainer () const; const CWallpaperApplication& getApp () const; + const COutput* getOutput () const; const ITexture* resolveTexture (const std::string& name); private: - void setupScreens (); - void setupWindow (); - - void renderScreens (); - void renderWindow (); - - struct viewport - { - glm::ivec4 viewport; - std::string name; - }; - - Display* m_display; - Pixmap m_pixmap; - GC m_gc; - XImage* m_image; CVideoDriver& m_driver; - char* m_imageData; - CFBO* m_fbo; - std::vector m_screens; - std::vector m_viewports; - CWallpaper* m_wallpaper; + std::map m_wallpapers; + CWallpaper* m_defaultWallpaper; CInputContext& m_input; - CContainer& m_container; CWallpaperApplication& m_app; CTextureCache* m_textureCache; + const COutput* m_output; }; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CTextureCache.cpp b/src/WallpaperEngine/Render/CTextureCache.cpp index f9d0622..41a066f 100644 --- a/src/WallpaperEngine/Render/CTextureCache.cpp +++ b/src/WallpaperEngine/Render/CTextureCache.cpp @@ -1,6 +1,9 @@ #include "CTextureCache.h" +#include "WallpaperEngine/Assets/CAssetLoadException.h" + using namespace WallpaperEngine::Render; +using namespace WallpaperEngine::Assets; CTextureCache::CTextureCache (CRenderContext& context) : m_context (context) @@ -17,11 +20,26 @@ const ITexture* CTextureCache::resolve (const std::string& filename) if (found != this->m_textureCache.end ()) return (*found).second; - const ITexture* texture = this->m_context.getContainer ().readTexture (filename); + // search for the texture in all the different containers just in case + for (auto it : this->m_context.getApp ().getProjects ()) + { + const ITexture* texture = it.second->getContainer ()->readTexture (filename); - this->store (filename, texture); + this->store (filename, texture); - return texture; + return texture; + } + + if (this->m_context.getApp ().getDefaultProject () != nullptr) + { + const ITexture* texture = this->m_context.getApp ().getDefaultProject ()->getContainer ()->readTexture (filename); + + this->store (filename, texture); + + return texture; + } + + throw CAssetLoadException (filename, "Cannot find file"); } void CTextureCache::store (std::string name, const ITexture* texture) diff --git a/src/WallpaperEngine/Render/CVideo.cpp b/src/WallpaperEngine/Render/CVideo.cpp index 58f3021..2b19f66 100644 --- a/src/WallpaperEngine/Render/CVideo.cpp +++ b/src/WallpaperEngine/Render/CVideo.cpp @@ -54,8 +54,11 @@ CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& aud if (mpv_render_context_create (&this->m_mpvGl, this->m_mpv, params) < 0) sLog.exception ("Failed to initialize MPV's GL context"); + std::filesystem::path videopath = this->getVideo ()->getProject ().getContainer ()->resolveRealFile (this->getVideo ()->getFilename ()); + + // build the path to the video file const char* command [] = { - "loadfile", this->getVideo ()->getFilename ().c_str (), nullptr + "loadfile", videopath.c_str (), nullptr }; if (mpv_command (this->m_mpv, command) < 0) diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index 4871d99..e74a503 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -61,9 +61,9 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend CWallpaper::~CWallpaper () = default; -const CContainer& CWallpaper::getContainer () const +CContainer* CWallpaper::getContainer () const { - return this->m_context.getContainer (); + return this->m_wallpaperData->getProject ().getContainer (); } WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData () const diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index d1a0075..5029b15 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/src/WallpaperEngine/Render/CWallpaper.h @@ -38,7 +38,7 @@ namespace WallpaperEngine::Render /** * @return The container to resolve files for this wallpaper */ - const CContainer& getContainer () const; + CContainer* getContainer () const; /** * @return The current context rendering this wallpaper diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp index 7ebfae6..8a4c2df 100644 --- a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp +++ b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp @@ -62,6 +62,12 @@ void COpenGLDriver::resizeWindow (glm::ivec2 size) glfwSetWindowSize (this->m_window, size.x, size.y); } +void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos) +{ + glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y); + glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w); +} + void COpenGLDriver::showWindow () { glfwShowWindow (this->m_window); diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h index 9ece21c..e421b4f 100644 --- a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h +++ b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h @@ -3,9 +3,17 @@ #include #include #include "WallpaperEngine/Render/Drivers/CVideoDriver.h" +#include "WallpaperEngine/Application/CApplicationContext.h" + +namespace WallpaperEngine::Application +{ + class CApplicationContext; +} namespace WallpaperEngine::Render::Drivers { + using namespace WallpaperEngine::Application; + class COpenGLDriver : public CVideoDriver { public: @@ -15,6 +23,7 @@ namespace WallpaperEngine::Render::Drivers float getRenderTime () override; bool closeRequested () override; void resizeWindow (glm::ivec2 size) override; + void resizeWindow (glm::ivec4 sizeandpos) override; void showWindow () override; void hideWindow () override; glm::ivec2 getFramebufferSize () override; @@ -22,6 +31,7 @@ namespace WallpaperEngine::Render::Drivers uint32_t getFrameCounter () override; GLFWwindow* getWindow (); + private: GLFWwindow* m_window; uint32_t m_frameCounter; diff --git a/src/WallpaperEngine/Render/Drivers/CVideoDriver.h b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h index 5da1d4d..4d159df 100644 --- a/src/WallpaperEngine/Render/Drivers/CVideoDriver.h +++ b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h @@ -1,5 +1,6 @@ #pragma once +#include #include namespace WallpaperEngine::Render::Drivers @@ -10,6 +11,7 @@ namespace WallpaperEngine::Render::Drivers virtual float getRenderTime () = 0; virtual bool closeRequested () = 0; virtual void resizeWindow (glm::ivec2 size) = 0; + virtual void resizeWindow (glm::ivec4 size) = 0; virtual void showWindow () = 0; virtual void hideWindow () = 0; virtual glm::ivec2 getFramebufferSize () = 0; diff --git a/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp new file mode 100644 index 0000000..fcfcf72 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/COutput.cpp @@ -0,0 +1,23 @@ +#include "COutput.h" + +using namespace WallpaperEngine::Render::Drivers::Output; + +COutput::COutput (CApplicationContext& context) : + m_context (context) +{ +} + +const std::map & COutput::getViewports () const +{ + return this->m_viewports; +} + +int COutput::getFullWidth () const +{ + return this->m_fullWidth; +} + +int COutput::getFullHeight () const +{ + return this->m_fullHeight; +} diff --git a/src/WallpaperEngine/Render/Drivers/Output/COutput.h b/src/WallpaperEngine/Render/Drivers/Output/COutput.h new file mode 100644 index 0000000..934924c --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/COutput.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include + +#include "WallpaperEngine/Application/CApplicationContext.h" + +using namespace WallpaperEngine::Application; + +namespace WallpaperEngine::Application +{ + class CApplicationContext; +} + +namespace WallpaperEngine::Render::Drivers::Output +{ + class COutput + { + public: + COutput (CApplicationContext& context); + + virtual void reset () = 0; + + int getFullWidth () const; + int getFullHeight () const; + + struct ScreenInfo + { + glm::ivec4 viewport; + std::string name; + }; + + virtual bool renderVFlip () const = 0; + virtual bool renderMultiple () const = 0; + virtual bool haveImageBuffer () const = 0; + const std::map & getViewports () const; + virtual void* getImageBuffer () const = 0; + virtual void updateRender () const = 0; + + protected: + mutable int m_fullWidth; + mutable int m_fullHeight; + mutable std::map m_viewports; + CApplicationContext& m_context; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp new file mode 100644 index 0000000..f4bd914 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp @@ -0,0 +1,77 @@ +#include "CWindowOutput.h" +#include "WallpaperEngine/Logging/CLog.h" + +using namespace WallpaperEngine::Render::Drivers::Output; + +CWindowOutput::CWindowOutput (CApplicationContext& context, CVideoDriver& driver) : + COutput (context), + m_driver (driver) +{ + if ( + this->m_context.windowMode != Application::CApplicationContext::NORMAL_WINDOW && + this->m_context.windowMode != Application::CApplicationContext::EXPLICIT_WINDOW) + sLog.exception ("Inititalizing window output when not in output mode, how did you get here?!"); + + // window should be visible + driver.showWindow (); + + if (this->m_context.windowMode == Application::CApplicationContext::EXPLICIT_WINDOW) + { + this->m_fullWidth = this->m_context.windowGeometry.z; + this->m_fullHeight = this->m_context.windowGeometry.w; + this->repositionWindow (); + } + else + { + // take the size from the driver (default window size) + this->m_fullWidth = this->m_driver.getFramebufferSize ().x; + this->m_fullHeight = this->m_driver.getFramebufferSize ().y; + } + + // register the default viewport + this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"}; +} + +void CWindowOutput::repositionWindow () +{ + // reposition the window + this->m_driver.resizeWindow (this->m_context.windowGeometry); +} + +void CWindowOutput::reset () +{ + if (this->m_context.windowMode == Application::CApplicationContext::EXPLICIT_WINDOW) + this->repositionWindow (); +} + +bool CWindowOutput::renderVFlip () const +{ + return true; +} + +bool CWindowOutput::renderMultiple () const +{ + return false; +} + +bool CWindowOutput::haveImageBuffer () const +{ + return false; +} + +void* CWindowOutput::getImageBuffer () const +{ + return nullptr; +} +void CWindowOutput::updateRender () const +{ + if (this->m_context.windowMode != Application::CApplicationContext::NORMAL_WINDOW) + return; + + // take the size from the driver (default window size) + this->m_fullWidth = this->m_driver.getFramebufferSize ().x; + this->m_fullHeight = this->m_driver.getFramebufferSize ().y; + + // update the default viewport + this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"}; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h b/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h new file mode 100644 index 0000000..1e2f0e6 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h @@ -0,0 +1,25 @@ +#pragma once + +#include "WallpaperEngine/Render/Drivers/CVideoDriver.h" +#include "COutput.h" + +namespace WallpaperEngine::Render::Drivers::Output +{ + class CWindowOutput : public COutput + { + public: + CWindowOutput (CApplicationContext& context, CVideoDriver& driver); + + void reset () override; + bool renderVFlip () const override; + bool renderMultiple () const override; + bool haveImageBuffer () const override; + void* getImageBuffer () const override; + void updateRender () const override; + + private: + void repositionWindow (); + + CVideoDriver& m_driver; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp new file mode 100644 index 0000000..7b1d2cf --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp @@ -0,0 +1,183 @@ +#include "common.h" +#include "CX11Output.h" + +#include +#include +#include + +using namespace WallpaperEngine::Render::Drivers::Output; + +XErrorHandler originalErrorHandler; + +void CustomXIOErrorExitHandler (Display* dsp, void* userdata) +{ + auto context = static_cast (userdata); + +#if !NDEBUG + sLog.debugerror ("Critical XServer error detected. Attempting to recover..."); +#endif /* DEBUG */ + + // refetch all the resources + context->reset (); +} + +int CustomXErrorHandler (Display* dpy, XErrorEvent* event) +{ +#if !NDEBUG + sLog.debugerror ("Detected X error"); +#endif /* DEBUG */ + + // call the original handler so we can keep some information reporting + originalErrorHandler (dpy, event); + + return 0; +} + +int CustomXIOErrorHandler (Display* dsp) +{ +#if !NDEBUG + sLog.debugerror ("Detected X error"); +#endif /* DEBUG */ + + return 0; +} + +CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver) : + COutput (context), + m_driver (driver) +{ + this->m_display = XOpenDisplay (nullptr); + this->loadScreenInfo (); +} +CX11Output::~CX11Output () +{ + this->free (); + XCloseDisplay (this->m_display); +} + +void CX11Output::reset () +{ + // first free whatever we have right now + this->free (); + // re-load screen info + this->loadScreenInfo (); +} + +void CX11Output::free () +{ + // free all the resources we've got + XDestroyImage (this->m_image); + XFreeGC (this->m_display, this->m_gc); + XFreePixmap (this->m_display, this->m_pixmap); + delete this->m_imageData; +} + +void* CX11Output::getImageBuffer () const +{ + return this->m_imageData; +} + +bool CX11Output::renderVFlip () const +{ + return false; +} + +bool CX11Output::renderMultiple () const +{ + return this->m_viewports.size () > 1; +} + +bool CX11Output::haveImageBuffer () const +{ + return true; +} + +void CX11Output::loadScreenInfo () +{ + // reset the viewports + this->m_viewports.clear (); + + // set the error handling to try and recover from X disconnections +#ifdef HAVE_XSETIOERROREXITHANDLER + XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this); +#endif /* HAVE_XSETIOERROREXITHANDLER */ + originalErrorHandler = XSetErrorHandler (CustomXErrorHandler); + XSetIOErrorHandler (CustomXIOErrorHandler); + + int xrandr_result, xrandr_error; + + if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error)) + { + sLog.error ("XRandr is not present, cannot detect specified screens, running in window mode"); + return; + } + + this->m_root = DefaultRootWindow (this->m_display); + this->m_fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); + this->m_fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); + XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, DefaultRootWindow (this->m_display)); + + if (screenResources == nullptr) + { + sLog.error ("Cannot detect screen sizes using xrandr, running in window mode"); + 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; + + // only keep info of registered screens + if (this->m_context.screenSettings.find (info->name) == this->m_context.screenSettings.end ()) + continue; + + XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc); + + sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height); + + this->m_viewports [info->name] = + { + {crtc->x, crtc->y, crtc->width, crtc->height}, + info->name + }; + + XRRFreeCrtcInfo (crtc); + } + + XRRFreeScreenResources (screenResources); + + // create pixmap so we can draw things in there + this->m_pixmap = XCreatePixmap (this->m_display, this->m_root, this->m_fullWidth, this->m_fullHeight, 24); + this->m_gc = XCreateGC (this->m_display, this->m_pixmap, 0, nullptr); + // pre-fill it with black + XFillRectangle (this->m_display, this->m_pixmap, this->m_gc, 0, 0, this->m_fullWidth, this->m_fullHeight); + // set the window background as our pixmap + XSetWindowBackgroundPixmap (this->m_display, this->m_root, this->m_pixmap); + // allocate space for the image's data + this->m_imageData = new char [this->m_fullWidth * this->m_fullHeight * 4]; + // create an image so we can copy it over + this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, this->m_fullWidth, this->m_fullHeight, 32, 0); + // setup driver's render changing the window's size + this->m_driver.resizeWindow ({this->m_fullWidth, this->m_fullHeight}); +} + +void CX11Output::updateRender () const +{ + // put the image back into the screen + XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, this->m_fullWidth, this->m_fullHeight); + + // _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to + // edit the background. Without these, other programs will clear the screen. + // it also forces the compositor to refresh the background (tested with picom) + Atom prop_root = XInternAtom(this->m_display, "_XROOTPMAP_ID", False); + Atom prop_esetroot = XInternAtom(this->m_display, "ESETROOT_PMAP_ID", False); + XChangeProperty(this->m_display, this->m_root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); + XChangeProperty(this->m_display, this->m_root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); + + XClearWindow(this->m_display, this->m_root); + XFlush(this->m_display); +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h new file mode 100644 index 0000000..5ef8218 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/Output/CX11Output.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include + +#include + +#include "WallpaperEngine/Render/Drivers/CVideoDriver.h" +#include "COutput.h" + +namespace WallpaperEngine::Render::Drivers::Output +{ + class CX11Output : public COutput + { + public: + CX11Output (CApplicationContext& context, CVideoDriver& driver); + ~CX11Output (); + + void reset () override; + + bool renderVFlip () const override; + bool renderMultiple () const override; + bool haveImageBuffer () const override; + void* getImageBuffer () const override; + void updateRender () const override; + + private: + void loadScreenInfo (); + void free (); + + Display* m_display; + Pixmap m_pixmap; + Window m_root; + GC m_gc; + char* m_imageData; + XImage* m_image; + CVideoDriver& m_driver; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/CSound.cpp b/src/WallpaperEngine/Render/Objects/CSound.cpp index 64a2265..5f1819b 100644 --- a/src/WallpaperEngine/Render/Objects/CSound.cpp +++ b/src/WallpaperEngine/Render/Objects/CSound.cpp @@ -2,13 +2,16 @@ #include "CSound.h" +extern bool g_AudioEnabled; + using namespace WallpaperEngine::Render::Objects; CSound::CSound (CScene* scene, Core::Objects::CSound* sound) : CObject (scene, Type, sound), m_sound (sound) { - this->load (); + if (g_AudioEnabled) + this->load (); } void CSound::load () @@ -16,7 +19,7 @@ void CSound::load () for (const auto& cur : this->m_sound->getSounds ()) { uint32_t filesize = 0; - const void* filebuffer = this->getContainer ().readFile (cur, &filesize); + const void* filebuffer = this->getContainer ()->readFile (cur, &filesize); auto stream = new Audio::CAudioStream (this->getScene ()->getAudioContext (), filebuffer, filesize); diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index ecdbd04..b5a80d5 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -29,7 +29,7 @@ using namespace WallpaperEngine::Assets; namespace WallpaperEngine::Render::Shaders { Compiler::Compiler ( - const CContainer& container, + CContainer* container, std::string filename, Type type, std::map * combos, @@ -50,11 +50,11 @@ namespace WallpaperEngine::Render::Shaders m_baseCombos () { if (type == Type_Vertex) - this->m_content = this->m_container.readVertexShader (this->m_file); + this->m_content = this->m_container->readVertexShader (this->m_file); else if (type == Type_Pixel) - this->m_content = this->m_container.readFragmentShader (this->m_file); + this->m_content = this->m_container->readFragmentShader (this->m_file); else if (type == Type_Include) - this->m_content = this->m_container.readIncludeShader (this->m_file); + this->m_content = this->m_container->readIncludeShader (this->m_file); // clone the combos into the baseCombos to keep track of values that must be embedded no matter what for (const auto& cur : *this->m_combos) @@ -650,7 +650,7 @@ namespace WallpaperEngine::Render::Shaders file += ".json"; std::string tmp = file; - std::string patchContents = this->m_container.readFileAsString (file); + std::string patchContents = this->m_container->readFileAsString (file); json data = json::parse (patchContents); auto patches = data.find ("patches"); diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.h b/src/WallpaperEngine/Render/Shaders/Compiler.h index 707cdb2..99670b8 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.h +++ b/src/WallpaperEngine/Render/Shaders/Compiler.h @@ -51,7 +51,7 @@ namespace WallpaperEngine::Render::Shaders * @param recursive Whether the compiler should add base definitions or not */ Compiler ( - const CContainer& container, + CContainer* container, std::string filename, Type type, std::map* combos, @@ -264,7 +264,7 @@ namespace WallpaperEngine::Render::Shaders /** * The container to load files from */ - const CContainer& m_container; + CContainer* m_container; /** * List of textures that the shader expects (inferred from sampler2D and it's JSON data) */