소스 검색

- removed dependency on std::filesystem
~ moved some things into CContext so main is a bit cleaner
~ moved wallpaper object creation into CWallpaper so main is a bit cleaner

Signed-off-by: Alexis Maiquez <almamu@almamu.com>

Alexis Maiquez 4 년 전
부모
커밋
f4955f1531

+ 2 - 0
CMakeLists.txt

@@ -36,6 +36,8 @@ add_executable(
         wallengine
         main.cpp
 
+        src/WallpaperEngine/Assets/CPackageLoadException.cpp
+        src/WallpaperEngine/Assets/CPackageLoadException.h
         src/WallpaperEngine/Assets/CAssetLoadException.cpp
         src/WallpaperEngine/Assets/CAssetLoadException.h
         src/WallpaperEngine/Assets/CContainer.h

+ 19 - 82
main.cpp

@@ -6,25 +6,20 @@
 #include <FreeImage.h>
 #include <sys/stat.h>
 #include <GL/glew.h>
-#include <GL/glx.h>
-#include <filesystem>
 #include <csignal>
 #include <GLFW/glfw3.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
 #include "WallpaperEngine/Core/CProject.h"
 #include "WallpaperEngine/Render/CWallpaper.h"
 #include "WallpaperEngine/Render/CContext.h"
-#include "WallpaperEngine/Render/CScene.h"
-#include "WallpaperEngine/Render/CVideo.h"
 
 #include "WallpaperEngine/Assets/CPackage.h"
 #include "WallpaperEngine/Assets/CDirectory.h"
 #include "WallpaperEngine/Assets/CCombinedContainer.h"
+#include "WallpaperEngine/Assets/CPackageLoadException.h"
 
 float g_Time;
+bool g_KeepRunning = true;
 
 using namespace WallpaperEngine::Core::Types;
 
@@ -58,24 +53,9 @@ std::string stringPathFixes(const std::string& s)
     return std::move (str);
 }
 
-void free_display_wallpaper(int sig)
+void signalhandler(int sig)
 {
-    Display* display = XOpenDisplay (nullptr);
-    Window root = DefaultRootWindow(display);
-    // create a blank pm to reset compositors values, compositors will render as a blank X window.
-    Pixmap pm = XCreatePixmap(display, root, 1, 1, 1);
-    Atom prop_root = XInternAtom(display, "_XROOTPMAP_ID", False);
-    Atom prop_esetroot = XInternAtom(display, "ESETROOT_PMAP_ID", False);
-    XChangeProperty(display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pm, 1);
-    XChangeProperty(display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &pm, 1);
-    XFreePixmap(display, pm);
-    // set background to black. Only needed if no compositors are running
-    XSetWindowBackground(display, root, 0);
-    // sync changes before exiting
-    XClearWindow(display, root);
-    XFlush(display);
-    XCloseDisplay(display);
-    exit(sig);
+    g_KeepRunning = false;
 }
 
 int main (int argc, char* argv[])
@@ -132,9 +112,6 @@ int main (int argc, char* argv[])
         }
     }
 
-    // increment the option index (useful for when no options were found)
-    // option_index ++;
-
     if (path.empty () == true)
     {
         if (optind < argc && strlen (argv [optind]) > 0)
@@ -169,13 +146,9 @@ int main (int argc, char* argv[])
 
     // ensure the path has a trailing slash
 
-    // Attach signals for unexpected killing of program by user. We need to reset the 
-    // screen otherwise the background will remain the last frame on sigterm or sigint.
-    if (!screens.empty())
-    {
-        std::signal(SIGINT, free_display_wallpaper);
-        std::signal(SIGTERM, free_display_wallpaper);
-    }
+    // attach signals so if a stop is requested the X11 resources are freed and the program shutsdown gracefully
+    std::signal(SIGINT, signalhandler);
+    std::signal(SIGTERM, signalhandler);
 
     // first of all, initialize the window
     if (glfwInit () == GLFW_FALSE)
@@ -192,10 +165,6 @@ int main (int argc, char* argv[])
     glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 2);
     glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 1);
 
-    // will hide the window if we are drawing to X
-    if (!screens.empty())
-        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
-
     auto containers = new WallpaperEngine::Assets::CCombinedContainer ();
 
     // update the used path with the full one
@@ -213,7 +182,7 @@ int main (int argc, char* argv[])
         containers->add (new WallpaperEngine::Assets::CPackage (scene_path));
         std::cout << "Detected scene.pkg file at " << scene_path << ". Adding to list of searchable paths" << std::endl;
     }
-    catch(std::filesystem::filesystem_error ex)
+    catch (CPackageLoadException ex)
     {
         // ignore this error, the package file was not found
         std::cout << "No scene.pkg file found at " << path << ". Defaulting to normal folder storage" << std::endl;
@@ -228,10 +197,6 @@ int main (int argc, char* argv[])
     // add containers to the list
     containers->add (new WallpaperEngine::Assets::CDirectory ("./assets/"));
 
-    // parse the project.json file
-    auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers);
-    WallpaperEngine::Render::CWallpaper* wallpaper;
-
     // auto projection = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
     // create the window!
     // TODO: DO WE NEED TO PASS MONITOR HERE OR ANYTHING?
@@ -245,9 +210,6 @@ int main (int argc, char* argv[])
         return 2;
     }
 
-    // initialize inputs
-    CMouseInput* mouseInput = new CMouseInput (window);
-
     glfwMakeContextCurrent (window);
 
     // TODO: FIGURE THESE OUT BASED ON THE SCREEN
@@ -266,33 +228,17 @@ int main (int argc, char* argv[])
     }
 
     // initialize custom context class
-    WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens);
+    WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens, window);
     // initialize mouse support
-    context->setMouse (mouseInput);
+    context->setMouse (new CMouseInput (window));
     // set the default viewport
     context->setDefaultViewport ({0, 0, windowWidth, windowHeight});
-
-    if (project->getType () == "scene")
-    {
-        WallpaperEngine::Core::CScene* scene = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ();
-        wallpaper = new WallpaperEngine::Render::CScene (scene, containers, context);
-    }
-    else if (project->getType () == "video")
-    {
-        // special steps, running a video needs a root directory change, files are not loaded from the container classes
-        // as they're streamed from disk
-        chdir (path.c_str ());
-
-        WallpaperEngine::Core::CVideo* video = project->getWallpaper ()->as <WallpaperEngine::Core::CVideo> ();
-        wallpaper = new WallpaperEngine::Render::CVideo (video, containers, context);
-    }
-    else
-    {
-        throw std::runtime_error ("Unsupported wallpaper type");
-    }
-
+    // parse the project.json file
+    auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers);
     // ensure the context knows what wallpaper to render
-    context->setWallpaper (wallpaper);
+    context->setWallpaper (
+        WallpaperEngine::Render::CWallpaper::fromWallpaper (project->getWallpaper (), containers, context)
+    );
 
     if (shouldEnableAudio == true)
     {
@@ -313,18 +259,9 @@ int main (int argc, char* argv[])
     // TODO: FIGURE OUT THE REQUIRED INPUT MODE, AS SOME WALLPAPERS USE THINGS LIKE MOUSE POSITION
     // glfwSetInputMode (window, GLFW_STICKY_KEYS, GL_TRUE);
 
-    // enable depth text
-    glEnable (GL_DEPTH_TEST);
-    glDepthFunc (GL_LESS);
-
-    // cull anything that doesn't look at the camera (might be useful to disable in the future)
-    glDisable (GL_CULL_FACE);
-
-    double minimumTime = 1.0 / maximumFPS;
-    double startTime = 0.0;
-    double endTime = 0.0;
+    double startTime, endTime, minimumTime = 1.0 / maximumFPS;
 
-    while (glfwWindowShouldClose (window) == 0)
+    while (glfwWindowShouldClose (window) == 0 && g_KeepRunning == true)
     {
         // get the real framebuffer size
         glfwGetFramebufferSize (window, &windowWidth, &windowHeight);
@@ -334,8 +271,6 @@ int main (int argc, char* argv[])
         g_Time = (float) glfwGetTime ();
         // get the start time of the frame
         startTime = glfwGetTime ();
-        // update our inputs first
-        mouseInput->update ();
         // render the scene
         context->render ();
         // do buffer swapping
@@ -350,6 +285,8 @@ int main (int argc, char* argv[])
             usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC);
     }
 
+    // free context
+    delete context;
     // terminate gl
     glfwTerminate ();
     // terminate SDL

+ 2 - 6
src/WallpaperEngine/Assets/CPackage.cpp

@@ -1,12 +1,8 @@
-//
-// Created by almamu on 8/8/21.
-//
-
 #include "CPackage.h"
 #include "CAssetLoadException.h"
+#include "CPackageLoadException.h"
 
 #include <utility>
-#include <filesystem>
 
 using namespace WallpaperEngine::Assets;
 
@@ -55,7 +51,7 @@ void CPackage::init ()
     FILE* fp = fopen (this->m_path.c_str (), "rb+");
 
     if (fp == nullptr)
-        throw std::filesystem::filesystem_error ("Cannot find package file", std::error_code());
+        throw CPackageLoadException (this->m_path, std::to_string (errno));
 
     // first validate header
     this->validateHeader (fp);

+ 13 - 0
src/WallpaperEngine/Assets/CPackageLoadException.cpp

@@ -0,0 +1,13 @@
+#include "CPackageLoadException.h"
+
+using namespace WallpaperEngine::Assets;
+
+CPackageLoadException::CPackageLoadException(const std::string& filename, const std::string& extrainfo)
+        : m_message("Cannot load package " + filename + ": " + extrainfo)
+{
+}
+
+const char *CPackageLoadException::what() const noexcept
+{
+    return this->m_message.c_str ();
+}

+ 17 - 0
src/WallpaperEngine/Assets/CPackageLoadException.h

@@ -0,0 +1,17 @@
+#pragma once
+
+#include <exception>
+#include <string>
+
+namespace WallpaperEngine::Assets
+{
+    class CPackageLoadException : public std::exception
+    {
+    public:
+        CPackageLoadException(const std::string& message, const std::string& extrainfo = "");
+        const char* what() const noexcept override;
+
+    private:
+        std::string m_message;
+    };
+}

+ 20 - 4
src/WallpaperEngine/Render/CContext.cpp

@@ -11,11 +11,12 @@
 
 using namespace WallpaperEngine::Render;
 
-CContext::CContext (std::vector <std::string> screens) :
+CContext::CContext (std::vector <std::string> screens, GLFWwindow* window) :
     m_wallpaper (nullptr),
     m_screens (std::move (screens)),
     m_isRootWindow (m_screens.empty () == false),
-    m_defaultViewport ({0, 0, 1920, 1080})
+    m_defaultViewport ({0, 0, 1920, 1080}),
+    m_window (window)
 {
     this->initializeViewports ();
 }
@@ -25,6 +26,9 @@ void CContext::initializeViewports ()
     if (this->m_isRootWindow == false || this->m_screens.empty () == true)
         return;
 
+    // hide the glfw window if the viewports are to be detected
+    glfwHideWindow (this->m_window);
+
     this->m_display = XOpenDisplay (nullptr);
 
     int xrandr_result, xrandr_error;
@@ -94,9 +98,18 @@ void CContext::initializeViewports ()
 
     // 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);
+}
 
-    // Cause of issue for issue #59 origial issue
-    // glfwWindowHintPointer (GLFW_NATIVE_PARENT_HANDLE, reinterpret_cast <void*> (DefaultRootWindow (display)));
+CContext::~CContext()
+{
+    if (this->m_screens.empty () == false)
+    {
+        // 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 CContext::render ()
@@ -104,6 +117,9 @@ void CContext::render ()
     if (this->m_wallpaper == nullptr)
         return;
 
+    // ensure mouse information is up to date before drawing any frame
+    this->m_mouse->update ();
+
     if (this->m_viewports.empty () == false)
     {
         bool firstFrame = true;

+ 3 - 1
src/WallpaperEngine/Render/CContext.h

@@ -16,7 +16,8 @@ namespace WallpaperEngine::Render
     class CContext
     {
     public:
-        CContext (std::vector <std::string> screens);
+        CContext (std::vector <std::string> screens, GLFWwindow* window);
+        ~CContext ();
 
         void initializeViewports ();
         void render ();
@@ -30,6 +31,7 @@ namespace WallpaperEngine::Render
         Pixmap m_pixmap;
         GC m_gc;
         XImage* m_image;
+        GLFWwindow* m_window;
         char* m_imageData;
         CFBO* m_fbo;
         std::vector <std::string> m_screens;

+ 10 - 0
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -355,4 +355,14 @@ CFBO* CWallpaper::findFBO (const std::string& name) const
 CFBO* CWallpaper::getFBO () const
 {
     return this->m_sceneFBO;
+}
+
+CWallpaper* CWallpaper::fromWallpaper (Core::CWallpaper* wallpaper, CContainer* containers, CContext* context)
+{
+    if (wallpaper->is <Core::CScene> () == true)
+        return new WallpaperEngine::Render::CScene (wallpaper->as <Core::CScene> (), containers, context);
+    else if (wallpaper->is <Core::CVideo> () == true)
+        return new WallpaperEngine::Render::CVideo (wallpaper->as <Core::CVideo> (), containers, context);
+    else
+        throw std::runtime_error ("Unsupported wallpaper type");
 }

+ 10 - 0
src/WallpaperEngine/Render/CWallpaper.h

@@ -75,6 +75,7 @@ namespace WallpaperEngine::Render
          * Updates the texcoord used for drawing to the used framebuffer
          */
         void updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const;
+
         /**
          * Updates the destination framebuffer for this wallpaper
          *
@@ -82,6 +83,15 @@ namespace WallpaperEngine::Render
          */
         void setDestinationFramebuffer (GLuint framebuffer);
 
+        /**
+         * Creates a new instance of CWallpaper based on the information provided by the read backgrounds
+         *
+         * @param wallpaper
+         *
+         * @return
+         */
+        static CWallpaper* fromWallpaper (Core::CWallpaper* wallpaper, CContainer* containers, CContext* context);
+
     protected:
         /**
          * Renders a frame of the wallpaper