- 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>
This commit is contained in:
Alexis Maiquez 2022-02-28 14:54:45 +01:00
parent 009321572e
commit f4955f1531
9 changed files with 96 additions and 93 deletions

View File

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

101
main.cpp
View File

@ -6,25 +6,20 @@
#include <FreeImage.h> #include <FreeImage.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/glx.h>
#include <filesystem>
#include <csignal> #include <csignal>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "WallpaperEngine/Core/CProject.h" #include "WallpaperEngine/Core/CProject.h"
#include "WallpaperEngine/Render/CWallpaper.h" #include "WallpaperEngine/Render/CWallpaper.h"
#include "WallpaperEngine/Render/CContext.h" #include "WallpaperEngine/Render/CContext.h"
#include "WallpaperEngine/Render/CScene.h"
#include "WallpaperEngine/Render/CVideo.h"
#include "WallpaperEngine/Assets/CPackage.h" #include "WallpaperEngine/Assets/CPackage.h"
#include "WallpaperEngine/Assets/CDirectory.h" #include "WallpaperEngine/Assets/CDirectory.h"
#include "WallpaperEngine/Assets/CCombinedContainer.h" #include "WallpaperEngine/Assets/CCombinedContainer.h"
#include "WallpaperEngine/Assets/CPackageLoadException.h"
float g_Time; float g_Time;
bool g_KeepRunning = true;
using namespace WallpaperEngine::Core::Types; using namespace WallpaperEngine::Core::Types;
@ -58,24 +53,9 @@ std::string stringPathFixes(const std::string& s)
return std::move (str); return std::move (str);
} }
void free_display_wallpaper(int sig) void signalhandler(int sig)
{ {
Display* display = XOpenDisplay (nullptr); g_KeepRunning = false;
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);
} }
int main (int argc, char* argv[]) 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 (path.empty () == true)
{ {
if (optind < argc && strlen (argv [optind]) > 0) if (optind < argc && strlen (argv [optind]) > 0)
@ -169,13 +146,9 @@ int main (int argc, char* argv[])
// ensure the path has a trailing slash // ensure the path has a trailing slash
// Attach signals for unexpected killing of program by user. We need to reset the // attach signals so if a stop is requested the X11 resources are freed and the program shutsdown gracefully
// screen otherwise the background will remain the last frame on sigterm or sigint. std::signal(SIGINT, signalhandler);
if (!screens.empty()) std::signal(SIGTERM, signalhandler);
{
std::signal(SIGINT, free_display_wallpaper);
std::signal(SIGTERM, free_display_wallpaper);
}
// first of all, initialize the window // first of all, initialize the window
if (glfwInit () == GLFW_FALSE) if (glfwInit () == GLFW_FALSE)
@ -192,10 +165,6 @@ int main (int argc, char* argv[])
glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 1); 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 (); auto containers = new WallpaperEngine::Assets::CCombinedContainer ();
// update the used path with the full one // 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)); 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; 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 // 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; 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 // add containers to the list
containers->add (new WallpaperEngine::Assets::CDirectory ("./assets/")); 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 (); // auto projection = project->getWallpaper ()->as <WallpaperEngine::Core::CScene> ()->getOrthogonalProjection ();
// create the window! // create the window!
// TODO: DO WE NEED TO PASS MONITOR HERE OR ANYTHING? // TODO: DO WE NEED TO PASS MONITOR HERE OR ANYTHING?
@ -245,9 +210,6 @@ int main (int argc, char* argv[])
return 2; return 2;
} }
// initialize inputs
CMouseInput* mouseInput = new CMouseInput (window);
glfwMakeContextCurrent (window); glfwMakeContextCurrent (window);
// TODO: FIGURE THESE OUT BASED ON THE SCREEN // TODO: FIGURE THESE OUT BASED ON THE SCREEN
@ -266,33 +228,17 @@ int main (int argc, char* argv[])
} }
// initialize custom context class // 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 // initialize mouse support
context->setMouse (mouseInput); context->setMouse (new CMouseInput (window));
// set the default viewport // set the default viewport
context->setDefaultViewport ({0, 0, windowWidth, windowHeight}); context->setDefaultViewport ({0, 0, windowWidth, windowHeight});
// parse the project.json file
if (project->getType () == "scene") auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers);
{
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");
}
// ensure the context knows what wallpaper to render // ensure the context knows what wallpaper to render
context->setWallpaper (wallpaper); context->setWallpaper (
WallpaperEngine::Render::CWallpaper::fromWallpaper (project->getWallpaper (), containers, context)
);
if (shouldEnableAudio == true) 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 // TODO: FIGURE OUT THE REQUIRED INPUT MODE, AS SOME WALLPAPERS USE THINGS LIKE MOUSE POSITION
// glfwSetInputMode (window, GLFW_STICKY_KEYS, GL_TRUE); // glfwSetInputMode (window, GLFW_STICKY_KEYS, GL_TRUE);
// enable depth text double startTime, endTime, minimumTime = 1.0 / maximumFPS;
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_LESS);
// cull anything that doesn't look at the camera (might be useful to disable in the future) while (glfwWindowShouldClose (window) == 0 && g_KeepRunning == true)
glDisable (GL_CULL_FACE);
double minimumTime = 1.0 / maximumFPS;
double startTime = 0.0;
double endTime = 0.0;
while (glfwWindowShouldClose (window) == 0)
{ {
// get the real framebuffer size // get the real framebuffer size
glfwGetFramebufferSize (window, &windowWidth, &windowHeight); glfwGetFramebufferSize (window, &windowWidth, &windowHeight);
@ -334,8 +271,6 @@ int main (int argc, char* argv[])
g_Time = (float) glfwGetTime (); g_Time = (float) glfwGetTime ();
// get the start time of the frame // get the start time of the frame
startTime = glfwGetTime (); startTime = glfwGetTime ();
// update our inputs first
mouseInput->update ();
// render the scene // render the scene
context->render (); context->render ();
// do buffer swapping // do buffer swapping
@ -350,6 +285,8 @@ int main (int argc, char* argv[])
usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC);
} }
// free context
delete context;
// terminate gl // terminate gl
glfwTerminate (); glfwTerminate ();
// terminate SDL // terminate SDL

View File

@ -1,12 +1,8 @@
//
// Created by almamu on 8/8/21.
//
#include "CPackage.h" #include "CPackage.h"
#include "CAssetLoadException.h" #include "CAssetLoadException.h"
#include "CPackageLoadException.h"
#include <utility> #include <utility>
#include <filesystem>
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
@ -55,7 +51,7 @@ void CPackage::init ()
FILE* fp = fopen (this->m_path.c_str (), "rb+"); FILE* fp = fopen (this->m_path.c_str (), "rb+");
if (fp == nullptr) 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 // first validate header
this->validateHeader (fp); this->validateHeader (fp);

View File

@ -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 ();
}

View File

@ -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;
};
}

View File

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

View File

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

View File

@ -355,4 +355,14 @@ CFBO* CWallpaper::findFBO (const std::string& name) const
CFBO* CWallpaper::getFBO () const CFBO* CWallpaper::getFBO () const
{ {
return this->m_sceneFBO; 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");
} }

View File

@ -75,6 +75,7 @@ namespace WallpaperEngine::Render
* Updates the texcoord used for drawing to the used framebuffer * Updates the texcoord used for drawing to the used framebuffer
*/ */
void updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const; void updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const;
/** /**
* Updates the destination framebuffer for this wallpaper * Updates the destination framebuffer for this wallpaper
* *
@ -82,6 +83,15 @@ namespace WallpaperEngine::Render
*/ */
void setDestinationFramebuffer (GLuint framebuffer); 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: protected:
/** /**
* Renders a frame of the wallpaper * Renders a frame of the wallpaper