chore: removed deprecated parameters and switched to argparse instead of getopt

fix: clamping mode wasn't applied by background properly, only globally
This commit is contained in:
Almamu 2025-04-21 17:27:13 +02:00
parent d163220156
commit c1fc105a22
16 changed files with 492 additions and 382 deletions

3
.gitmodules vendored
View File

@ -16,3 +16,6 @@
[submodule "src/External/kissfft"]
path = src/External/kissfft
url = https://github.com/mborgerding/kissfft.git
[submodule "src/External/argparse"]
path = src/External/argparse
url = https://github.com/p-ranav/argparse.git

View File

@ -110,6 +110,7 @@ add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
add_subdirectory(src/External/glslang-WallpaperEngine glslang)
add_subdirectory(src/External/SPIRV-Cross-WallpaperEngine spirv-cross)
add_subdirectory(src/External/kissfft kissfft)
add_subdirectory(src/External/argparse argparse)
# try to enable wayland builds when possible
pkg_check_modules(WAYLAND_SUPPORT wayland-cursor wayland-protocols egl wayland-egl)
@ -516,7 +517,8 @@ target_link_libraries (linux-wallpaperengine PUBLIC
spirv-cross-glsl
glfw
libcef_lib
libcef_dll_wrapper)
libcef_dll_wrapper
argparse)
COPY_FILES(linux-wallpaperengine "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${TARGET_OUTPUT_DIRECTORY}")
COPY_FILES(linux-wallpaperengine "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${TARGET_OUTPUT_DIRECTORY}")

1
src/External/argparse vendored Submodule

@ -0,0 +1 @@
Subproject commit d924b84eba1f0f0adf38b20b7b4829f6f65b6570

View File

@ -5,98 +5,289 @@
#include <cstdlib>
#include <cstring>
#include <getopt.h>
#include <iostream>
#include <argparse/argparse.hpp>
#define WORKSHOP_APP_ID 431960
#define APP_DIRECTORY "wallpaper_engine"
using namespace WallpaperEngine::Application;
struct option long_options [] = {
{"screen-root", required_argument, nullptr, 'r'}, {"bg", required_argument, nullptr, 'b'},
{"window", required_argument, nullptr, 'w'}, {"pkg", required_argument, nullptr, 'p'},
{"dir", required_argument, nullptr, 'd'}, {"silent", no_argument, nullptr, 's'},
{"volume", required_argument, nullptr, 'v'}, {"help", no_argument, nullptr, 'h'},
{"fps", required_argument, nullptr, 'f'}, {"assets-dir", required_argument, nullptr, 'a'},
{"screenshot", required_argument, nullptr, 'c'}, {"list-properties", no_argument, nullptr, 'l'},
{"set-property", required_argument, nullptr, 'o'}, {"noautomute", no_argument, nullptr, 'm'},
{"no-audio-processing", no_argument, nullptr, 'g'}, {"no-fullscreen-pause", no_argument, nullptr, 'n'},
{"disable-mouse", no_argument, nullptr, 'e'}, {"scaling", required_argument, nullptr, 't'},
{"clamping", required_argument, nullptr, 't'}, {"screenshot-delay", required_argument, nullptr, 'y'},
{"dump-structure", no_argument, nullptr, 'z'}, {nullptr, 0, nullptr, 0}
};
/* std::hash::operator() isn't constexpr, so it can't be used to get hash values as compile-time constants
* So here is customHash. It skips all spaces, so hashes for " find " and "fi nd" are the same
* Basicly got it from here: https://stackoverflow.com/questions/8317508/hash-function-for-a-string
*/
constexpr size_t customHash (const char* str) {
constexpr size_t A = 54059; /* a prime */
constexpr size_t B = 76963; /* another prime */
constexpr size_t C = 86969; /* yet another prime */
constexpr size_t FIRSTH = 37; /* also prime */
size_t hash = FIRSTH;
while (*str) {
if (*str != ' ') // Skip spaces
hash = (hash * A) ^ (*str * B);
++str;
}
return hash % C;
}
std::string stringPathFixes (const std::string& s) {
if (s.empty ())
return s;
std::string str (s);
// remove single-quotes from the arguments
if (str [0] == '\'' && str [str.size () - 1] == '\'')
str.erase (str.size () - 1, 1).erase (0, 1);
return str;
}
CApplicationContext::CApplicationContext (int argc, char* argv []) :
m_argc (argc),
m_argv (argv) {
// setup structs with sane default values for now
this->settings = {
.general =
{
.onlyListProperties = false,
.dumpStructure = false,
.assets = "",
.defaultBackground = "",
.screenBackgrounds = {},
.properties = {},
},
.render =
{
.mode = NORMAL_WINDOW,
.maximumFPS = 30,
.pauseOnFullscreen = true,
.window =
{
.geometry = {},
.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs,
},
},
.audio = {.enabled = true, .volume = 15, .automute = true, .audioprocessing = true},
.mouse =
{
.enabled = true,
},
.screenshot =
{
.take = false,
.path = "",
},
};
m_argv (argv),
settings ({
.general = {
.onlyListProperties = false,
.dumpStructure = false,
.assets = "",
.defaultBackground = "",
.screenBackgrounds = {},
.properties = {},
.screenScalings = {},
.screenClamps = {},
},
.render = {
.mode = NORMAL_WINDOW,
.maximumFPS = 30,
.pauseOnFullscreen = true,
.window =
{
.geometry = {},
.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs,
},
},
.audio = {
.enabled = true,
.volume = 15,
.automute = true,
.audioprocessing = true,
},
.mouse = {
.enabled = true,
},
.screenshot = {
.take = false,
.delay = 5,
.path = "",
},
}) {
std::string lastScreen;
// use std::out on this in case logging is disabled, this way it's easy to look at what is running
argparse::ArgumentParser program ("linux-wallpaperengine", "0.0", argparse::default_arguments::help);
auto& backgroundGroup = program.add_group ("Background options");
auto& backgroundMode = backgroundGroup.add_mutually_exclusive_group (false);
backgroundGroup.add_argument ("background id")
.help ("The background to use as default for screens with no background specified")
.action([this](const std::string& value) -> void {
this->settings.general.defaultBackground = translateBackground (value);
});
backgroundMode.add_argument ("-w", "--window")
.help ("Window geometry to use for the given screen")
.action ([this](const std::string& value) -> void {
if (this->settings.render.mode == DESKTOP_BACKGROUND) {
sLog.exception ("Cannot run in both background and window mode");
}
if (this->settings.render.mode == EXPLICIT_WINDOW) {
sLog.exception ("Only one window at a time can be specified in explicit window mode");
}
this->settings.render.mode = EXPLICIT_WINDOW;
if (value.empty ()) {
sLog.exception ("Window geometry cannot be empty");
}
const char* str = value.c_str ();
const char* delim1 = strchr (str, 'x');
const char* delim2 = strchr (str, 'x');
const char* delim3 = strchr (str, 'x');
if (delim1 == nullptr || delim2 == nullptr || delim3 == nullptr) {
sLog.exception ("Window geometry must be in the format: XxYxWxH");
}
this->settings.render.window.geometry.x = strtol(str, nullptr, 10);
this->settings.render.window.geometry.y = strtol (delim1 + 1, nullptr, 10);
this->settings.render.window.geometry.z = strtol (delim2 + 1, nullptr, 10);
this->settings.render.window.geometry.w = strtol (delim3 + 1, nullptr, 10);
})
.append ();
backgroundMode.add_argument ("-r", "--screen-root")
.help ("The screen the following settings will have an effect on")
.action([this, &lastScreen](const std::string& value) -> void {
if (this->settings.general.screenBackgrounds.find (value) != this->settings.general.screenBackgrounds.end ()) {
sLog.exception ("Cannot specify the same screen more than once: ", value);
}
if (this->settings.render.mode == EXPLICIT_WINDOW) {
sLog.exception ("Cannot run in both background and window mode");
}
this->settings.render.mode = DESKTOP_BACKGROUND;
lastScreen = value;
this->settings.general.screenBackgrounds [lastScreen] = "";
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
this->settings.general.screenClamps [lastScreen] = this->settings.render.window.clamp;
})
.append ();
backgroundGroup.add_argument ("-b", "--bg")
.help ("After --screen-root, specifies the background to use for the given screen")
.action ([this, &lastScreen](const std::string& value) -> void {
this->settings.general.screenBackgrounds [lastScreen] = translateBackground (value);
// set the default background to the last one used
this->settings.general.defaultBackground = translateBackground (value);
})
.append ();
backgroundGroup.add_argument ("--scaling")
.help ("Scaling mode to use when rendering the background, this applies to the previous --window or --screen-root output, or the default background if no other background is specified")
.choices ("stretch", "fit", "fill", "default")
.action([this, &lastScreen](const std::string& value) -> void {
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling mode;
if (value == "stretch") {
mode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
} else if (value == "fit") {
mode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
} else if (value == "fill") {
mode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
} else if (value == "default") {
mode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
} else {
sLog.exception ("Invalid scaling mode: ", value);
}
if (this->settings.render.mode == DESKTOP_BACKGROUND) {
this->settings.general.screenScalings [lastScreen] = mode;
} else {
this->settings.render.window.scalingMode = mode;
}
})
.append ();
backgroundGroup.add_argument ("--clamp")
.help ("Clamp mode to use when rendering the background, this applies to the previous --window or --screen-root output, or the default background if no other background is specified")
.choices("clamp", "border", "repeat")
.action([this, &lastScreen](const std::string& value) -> void {
WallpaperEngine::Assets::ITexture::TextureFlags flags;
if (value == "clamp") {
flags = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
} else if (value == "border") {
flags = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
} else if (value == "repeat") {
flags = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
} else {
sLog.exception ("Invalid clamp mode: ", value);
}
if (this->settings.render.mode == DESKTOP_BACKGROUND) {
this->settings.general.screenClamps [lastScreen] = flags;
} else {
this->settings.render.window.clamp = flags;
}
});
auto& performanceGroup = program.add_group ("Performance options");
performanceGroup.add_argument ("-f", "--fps")
.help ("Limits the FPS to the given number, useful to keep battery consumption low")
.default_value (30)
.scan<'i', int> ();
performanceGroup.add_argument ("--no-fullscreen-pause")
.help ("Prevents the background pausing when an app is fullscreen")
.default_value (true)
.implicit_value (false)
.store_into (this->settings.render.pauseOnFullscreen);
auto& audioGroup = program.add_group ("Sound settings");
auto& audioSettingsGroup = audioGroup.add_mutually_exclusive_group (false);
audioSettingsGroup.add_argument ("-v", "--volume")
.help ("Volume for all the sounds in the background")
.default_value (15)
.store_into (this->settings.audio.volume);
audioSettingsGroup.add_argument ("-s", "--silent")
.help ("Mutes all the sound the wallpaper might produce")
.default_value (true)
.implicit_value (false)
.store_into (this->settings.audio.enabled);
audioGroup.add_argument ("--noautomute")
.help ("Disables the automute when an app is playing sound")
.default_value (true)
.implicit_value (false)
.store_into (this->settings.audio.automute);
audioGroup.add_argument ("--no-audio-processing")
.help ("Disables audio processing for backgrounds")
.default_value (true)
.implicit_value (false)
.store_into (this->settings.audio.audioprocessing);
auto& screenshotGroup = program.add_group ("Screenshot options");
screenshotGroup.add_argument ("--screenshot")
.help ("Takes a screenshot of the background for it's use with tools like PyWAL")
.default_value ("")
.action ([this](const std::string& value) -> void {
this->settings.screenshot.take = true;
this->settings.screenshot.path = value;
});
screenshotGroup.add_argument ("--screenshot-delay")
.help ("Frames to wait before taking the screenshot")
.default_value (5)
.store_into (this->settings.screenshot.delay);
auto& contentGroup = program.add_group ("Content options");
contentGroup.add_argument ("--assets-dir")
.help ("Folder where the assets are stored")
.default_value ("")
.action ([this](const std::string& value) -> void {
this->settings.general.assets = value;
});
auto& configurationGroup = program.add_group ("Wallpaper configuration options");
configurationGroup.add_argument ("--disable-mouse")
.help ("Disables mouse interaction with the backgrounds")
.default_value (true)
.implicit_value (false)
.store_into (this->settings.mouse.enabled);
configurationGroup.add_argument ("-l", "--list-properties")
.help ("List all the available properties and their configuration")
.default_value (false)
.implicit_value (true)
.store_into (this->settings.general.onlyListProperties);
configurationGroup.add_argument ("--set-property", "--property")
.help ("Overrides the default value of the given property")
.action([this](const std::string& value) -> void {
const std::string::size_type equals = value.find ('=');
// properties without value are treated as booleans for now
if (equals == std::string::npos)
this->settings.general.properties [value] = "1";
else
this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1);
});
auto& debuggingGroup = program.add_group ("Debugging options");
debuggingGroup.add_argument ("-z", "--dump-structure")
.help ("Dumps the structure of the backgrounds")
.default_value (false)
.implicit_value (true)
.store_into (this->settings.general.dumpStructure);
program.add_epilog (
"Usage examples:\n"
" linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --scaling fill --clamp border\n"
" Runs the background 2317494988 on screen HDMI-1, scaling it to fill the screen and clamping the UVs to the border\n\n"
" linux-wallpaperengine 2317494988\n"
" Previews the background 2317494988 on a window\n\n"
" linux-wallpaperengine --screen-root HDMI-1 --bg 2317494988 --screen-root HDMI-2 --bg 1108150151\n"
" Runs two backgrounds on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
" linux-wallpaperengine --screen-root HDMI-1 --screen-root HDMI-2 2317494988\n"
" Runs the background 2317494988 on two screens, one on HDMI-1 and the other on HDMI-2\n\n"
);
program.parse_args (argc, argv);
sLog.out(program.help ().str ());
this->settings.audio.volume = std::max(0, std::min (this->settings.audio.volume, 128));
this->settings.screenshot.delay = std::max (0, std::min (this->settings.screenshot.delay, 5));
// use std::cout on this in case logging is disabled, this way it's easy to look at what is running
std::stringbuf buffer;
std::ostream bufferStream (&buffer);
@ -108,157 +299,6 @@ CApplicationContext::CApplicationContext (int argc, char* argv []) :
}
std::cout << buffer.str() << std::endl;
int c;
std::string lastScreen;
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1) {
switch (c) {
case 'z': this->settings.general.dumpStructure = true; break;
case 'n': this->settings.render.pauseOnFullscreen = false; break;
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->settings.general.screenBackgrounds [lastScreen] = translateBackground (optarg);
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
// update default background if not set
if (this->settings.general.defaultBackground.empty()) {
this->settings.general.defaultBackground = translateBackground (optarg);
}
break;
case 'o': {
std::string value = optarg;
const std::string::size_type equals = value.find ('=');
// properties without value are treated as booleans for now
if (equals == std::string::npos)
this->settings.general.properties [value] = "1";
else
this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1);
} break;
case 'l': this->settings.general.onlyListProperties = true; break;
case 'r':
if (this->settings.general.screenBackgrounds.find (optarg) !=
this->settings.general.screenBackgrounds.end ())
sLog.exception ("Cannot specify the same screen more than once: ", optarg);
if (this->settings.render.mode == EXPLICIT_WINDOW)
sLog.exception ("Cannot run in both background and window mode");
this->settings.render.mode = DESKTOP_BACKGROUND;
lastScreen = optarg;
this->settings.general.screenBackgrounds [lastScreen] = "";
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
break;
case 'w':
if (this->settings.render.mode == DESKTOP_BACKGROUND)
sLog.exception ("Cannot run in both background and window mode");
if (optarg != nullptr) {
this->settings.render.mode = EXPLICIT_WINDOW;
// read window geometry
char* pos = optarg;
if (pos != nullptr)
this->settings.render.window.geometry.x = atoi (pos);
if ((pos = strchr (pos, 'x')) != nullptr)
this->settings.render.window.geometry.y = atoi (pos + 1);
if ((pos = strchr (pos + 1, 'x')) != nullptr)
this->settings.render.window.geometry.z = atoi (pos + 1);
if ((pos = strchr (pos + 1, 'x')) != nullptr)
this->settings.render.window.geometry.w = atoi (pos + 1);
}
break;
case 'p':
case 'd':
sLog.error ("--dir/--pkg is deprecated and not used anymore");
this->settings.general.defaultBackground = translateBackground (stringPathFixes (optarg));
break;
case 's': this->settings.audio.enabled = false; break;
case 'h':
printHelp (argv [0]);
std::exit (0);
break;
case 'f': this->settings.render.maximumFPS = atoi (optarg); break;
case 'a': this->settings.general.assets = stringPathFixes (optarg); break;
case 'v': this->settings.audio.volume = std::max (atoi (optarg), 128); break;
case 'c':
this->settings.screenshot.take = true;
this->settings.screenshot.path = stringPathFixes (optarg);
break;
case 'y': this->settings.screenshot.delay = std::min (atoi (optarg), 5); break;
case 'm': this->settings.audio.automute = false; break;
case 'g': this->settings.audio.audioprocessing = false; break;
case 'e': this->settings.mouse.enabled = false; break;
case 't': {
size_t hash = customHash (optarg);
// Use a switch statement with the hash
switch (hash) {
// --scale options
case customHash ("stretch"):
this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
break;
case customHash ("fit"):
this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
break;
case customHash ("fill"):
this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
break;
case customHash ("default"):
this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
break;
// --clamp options
case customHash ("clamp"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
break;
case customHash ("border"):
this->settings.render.window.clamp =
WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
break;
case customHash ("repeat"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
break;
default:
sLog.error ("Wrong argument:");
sLog.error (optarg);
sLog.exception ("Wrong argument provided for --scale or --clamp option.");
break;
}
} break;
default: sLog.out ("Default on path parsing: ", optarg); break;
}
}
if (this->settings.general.defaultBackground.empty ()) {
if (optind < argc && strlen (argv [optind]) > 0) {
this->settings.general.defaultBackground = translateBackground (argv [optind]);
}
}
// perform some extra validation on the inputs
this->validateAssets ();
this->validateScreenshot ();
@ -267,6 +307,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv []) :
this->state.general.keepRunning = true;
this->state.audio.enabled = this->settings.audio.enabled;
this->state.audio.volume = this->settings.audio.volume;
this->state.mouse.enabled = this->settings.mouse.enabled;
}
int CApplicationContext::getArgc () const {
@ -311,38 +352,3 @@ void CApplicationContext::validateScreenshot () const {
if (extension != ".bmp" && extension != ".png" && extension != ".jpeg" && extension != ".jpg")
sLog.exception ("Cannot determine screenshot format, unknown extension ", extension);
}
void CApplicationContext::printHelp (const char* route) {
sLog.out ("Usage: ", route, " [options] background_path/background_id");
sLog.out ("");
sLog.out ("where background_path/background_id can be:");
sLog.out ("\tthe ID of the background (for autodetection on your steam installation)");
sLog.out ("\ta full path to the background's folder");
sLog.out ("");
sLog.out ("options:");
sLog.out ("\t--silent\t\t\t\t\tMutes all the sound the wallpaper might produce");
sLog.out ("\t--volume <amount>\t\t\tSets the volume for all the sounds in the background");
sLog.out ("\t--noautomute\t\t\t\tDisables the automute when an app is playing sound");
sLog.out ("\t--no-audio-processing\t\t\t\tDisables audio processing for backgrounds");
sLog.out ("\t--screen-root <screen name>\tDisplay as screen's background");
sLog.out (
"\t--window <geometry>\tRuns in window mode, geometry has to be XxYxWxH and sets the position and size of the window");
sLog.out ("\t--fps <maximum-fps>\t\t\tLimits the FPS to the given number, useful to keep battery consumption low");
sLog.out ("\t--assets-dir <path>\t\t\tFolder where the assets are stored");
sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background");
sLog.out ("\t--list-properties\t\t\tList all the available properties and their possible values");
sLog.out ("\t--set-property <name=value>\tOverrides the default value of the given property");
sLog.out ("\t--no-fullscreen-pause\tPrevents the background pausing when an app is fullscreen");
sLog.out ("\t--disable-mouse\tDisables mouse interactions");
sLog.out (
"\t--bg <background_path/background_id>\tAfter --screen-root uses the specified background only on that screen");
sLog.out (
"\t--scaling <mode>\t Scaling mode for wallpaper. Can be stretch, fit, fill, default. Must be used before wallpaper provided.\n\
\t\t For default wallpaper last specified value will be used.\n\
\t\t Example: ./wallengine --scaling stretch --screen-root eDP-1 --bg 2667198601 --scaling fill --screen-root eDP-2 2667198602");
sLog.out (
"\t--clamping <mode>\t Clamping mode for all wallpapers. Can be clamp, border, repeat. Enables GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_REPEAT accordingly. Default is clamp.");
sLog.out ("\t--screenshot-delay <seconds>\t\tFrames to wait until the screenshot is taken");
sLog.out ("\t--dump-structure\t\t\tDumps the structure of the wallpaper");
sLog.out ("\t--help\t\t\t\t\tPrints this help");
}

View File

@ -48,6 +48,8 @@ class CApplicationContext {
std::map<std::string, std::string> properties;
/** The scaling mode for different screens */
std::map<std::string, WallpaperEngine::Render::CWallpaperState::TextureUVsScaling> screenScalings;
/** The clamping mode for different screens */
std::map<std::string, WallpaperEngine::Assets::ITexture::TextureFlags> screenClamps;
} general;
/**
@ -98,7 +100,7 @@ class CApplicationContext {
/** If an screenshot should be taken */
bool take;
/** The frames to wait until the screenshot is taken */
uint32_t delay;
int delay;
/** The path to where the screenshot must be saved */
std::filesystem::path path;
} screenshot;
@ -132,10 +134,5 @@ class CApplicationContext {
* @return
*/
static std::filesystem::path translateBackground (const std::string& bgIdOrPath);
/**
* Prints the normal help message
*/
static void printHelp (const char* route);
};
} // namespace WallpaperEngine::Application

View File

@ -436,7 +436,8 @@ void CWallpaperApplication::prepareOutputs () {
background,
WallpaperEngine::Render::CWallpaper::fromWallpaper (
info->getWallpaper (), *m_renderContext, *m_audioContext, *m_browserContext,
this->m_context.settings.general.screenScalings [background]
this->m_context.settings.general.screenScalings [background],
this->m_context.settings.general.screenClamps [background]
)
);
}

View File

@ -10,8 +10,11 @@
using namespace WallpaperEngine::Render;
CWallpaper::CWallpaper (const Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context,
CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper::CWallpaper (
const Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context,CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode
) :
CContextAware (context),
m_wallpaperData (wallpaperData),
m_sceneFBO (nullptr),
@ -25,7 +28,7 @@ CWallpaper::CWallpaper (const Core::CWallpaper* wallpaperData, std::string type,
m_destFramebuffer (GL_NONE),
m_type (std::move (type)),
m_audioContext (audioContext),
m_state (scalingMode) {
m_state (scalingMode, clampMode) {
// generate the VAO to stop opengl from complaining
glGenVertexArrays (1, &this->m_vaoBuffer);
glBindVertexArray (this->m_vaoBuffer);
@ -237,11 +240,12 @@ void CWallpaper::setPause (bool newState) {}
void CWallpaper::setupFramebuffers () {
const uint32_t width = this->getWidth ();
const uint32_t height = this->getHeight ();
const ITexture::TextureFlags clamp = this->getContext ().getApp ().getContext ().settings.render.window.clamp;
const ITexture::TextureFlags clamp = this->m_state.getClampingMode ();
// create framebuffer for the scene
this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, clamp, 1.0, width,
height, width, height);
this->m_sceneFBO = this->createFBO (
"_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, clamp, 1.0, width,
height, width, height);
this->aliasFBO ("_rt_MipMappedFrameBuffer", this->m_sceneFBO);
}
@ -281,16 +285,20 @@ CFBO* CWallpaper::getFBO () const {
return this->m_sceneFBO;
}
CWallpaper* CWallpaper::fromWallpaper (const Core::CWallpaper* wallpaper, CRenderContext& context,
CAudioContext& audioContext, WebBrowser::CWebBrowserContext& browserContext,
const CWallpaperState::TextureUVsScaling& scalingMode) {
if (wallpaper->is<Core::Wallpapers::CScene> ())
return new WallpaperEngine::Render::Wallpapers::CScene (wallpaper->as<Core::Wallpapers::CScene> (), context, audioContext, scalingMode);
if (wallpaper->is<Core::Wallpapers::CVideo> ())
return new WallpaperEngine::Render::Wallpapers::CVideo (wallpaper->as<Core::Wallpapers::CVideo> (), context, audioContext, scalingMode);
else if (wallpaper->is<Core::Wallpapers::CWeb> ())
return new WallpaperEngine::Render::Wallpapers::CWeb (wallpaper->as<Core::Wallpapers::CWeb> (), context, audioContext, browserContext,
scalingMode);
else
CWallpaper* CWallpaper::fromWallpaper (
const Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext,
WebBrowser::CWebBrowserContext& browserContext, const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode
) {
if (wallpaper->is<Core::Wallpapers::CScene> ()) {
return new WallpaperEngine::Render::Wallpapers::CScene (
wallpaper->as<Core::Wallpapers::CScene> (), context, audioContext, scalingMode, clampMode);
} else if (wallpaper->is<Core::Wallpapers::CVideo> ()) {
return new WallpaperEngine::Render::Wallpapers::CVideo (
wallpaper->as<Core::Wallpapers::CVideo> (), context, audioContext, scalingMode, clampMode);
} else if (wallpaper->is<Core::Wallpapers::CWeb> ()) {
return new WallpaperEngine::Render::Wallpapers::CWeb (
wallpaper->as<Core::Wallpapers::CWeb> (), context, audioContext, browserContext, scalingMode, clampMode);
} else
sLog.exception ("Unsupported wallpaper type");
}

View File

@ -30,17 +30,17 @@ class CContextAware;
class CWallpaper : public Helpers::CContextAware {
public:
template <class T> const T* as () const {
template <class T> [[nodiscard]]const T* as () const {
assert (is<T> ());
return reinterpret_cast<const T*> (this);
}
template <class T> T* as () {
template <class T> [[nodiscard]] T* as () {
assert (is<T> ());
return reinterpret_cast<T*> (this);
}
template <class T> bool is () const {
template <class T> [[nodiscard]] bool is () const {
return this->m_type == T::Type;
}
@ -87,8 +87,9 @@ class CWallpaper : public Helpers::CContextAware {
* @param textureHeight
* @return
*/
CFBO* createFBO (const std::string& name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale,
uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
CFBO* createFBO (
const std::string& name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale,
uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
/**
* Creates an alias of an existing fbo
@ -146,13 +147,16 @@ class CWallpaper : public Helpers::CContextAware {
*
* @return
*/
static CWallpaper* fromWallpaper (const Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext,
WebBrowser::CWebBrowserContext& browserContext,
const CWallpaperState::TextureUVsScaling& scalingMode);
static CWallpaper* fromWallpaper (
const Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext,
WebBrowser::CWebBrowserContext& browserContext, const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
protected:
CWallpaper (const Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode);
CWallpaper (
const Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
/**
* Renders a frame of the wallpaper

View File

@ -1,9 +1,22 @@
#include "CWallpaperState.h"
#include "WallpaperEngine/Assets/ITexture.h"
#include "WallpaperEngine/Logging/CLog.h"
#include <algorithm>
using namespace WallpaperEngine::Render;
CWallpaperState::CWallpaperState (
const TextureUVsScaling& textureUVsMode, const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode) :
m_textureUVsMode (textureUVsMode) {}
bool CWallpaperState::hasChanged (
const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth,const int& projectionHeight
) const {
return this->viewport.width != viewport.z || this->viewport.height != viewport.w ||
this->projection.width != projectionWidth || this->projection.height != projectionHeight ||
this->vflip != vflip;
}
// Reset UVs to 0/1 values
void CWallpaperState::resetUVs () {
this->UVs.ustart = 0;
@ -123,6 +136,34 @@ template <CWallpaperState::TextureUVsScaling T> void CWallpaperState::updateText
This message is for developers, if you are just user it's a bug.");
}
CWallpaperState::TextureUVsScaling CWallpaperState::getTextureUVsScaling () const {
return this->m_textureUVsMode;
}
WallpaperEngine::Assets::ITexture::TextureFlags CWallpaperState::getClampingMode () const {
return this->m_clampingMode;
}
void CWallpaperState::setTextureUVsStrategy (CWallpaperState::TextureUVsScaling strategy) {
this->m_textureUVsMode = strategy;
}
int CWallpaperState::getViewportWidth () const {
return this->viewport.width;
}
int CWallpaperState::getViewportHeight () const {
return this->viewport.height;
}
int CWallpaperState::getProjectionWidth () const {
return this->projection.width;
}
int CWallpaperState::getProjectionHeight () const {
return this->projection.height;
}
void CWallpaperState::updateState (const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth,
const int& projectionHeight) {
this->viewport.width = viewport.z;

View File

@ -4,6 +4,8 @@
#include <GLFW/glfw3.h>
#include <glm/vec4.hpp>
#include "WallpaperEngine/Assets/ITexture.h"
namespace WallpaperEngine::Render {
/**
* Represents current wallpaper state
@ -18,66 +20,93 @@ class CWallpaperState {
StretchUVs,
};
CWallpaperState (const TextureUVsScaling& textureUVsMode) : m_textureUVsMode (textureUVsMode) {};
CWallpaperState (
const TextureUVsScaling& textureUVsMode, const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
// Compares saved state values with passed arguments
bool hasChanged (const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth,
const int& projectionHeight) const {
return this->viewport.width != viewport.z || this->viewport.height != viewport.w ||
this->projection.width != projectionWidth || this->projection.height != projectionHeight ||
this->vflip != vflip;
}
/**
* Checks if any of the given values has changed
* @param viewport
* @param vflip
* @param projectionWidth
* @param projectionHeight
* @return
*/
[[nodiscard]] bool hasChanged (
const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth, const int& projectionHeight) const;
// Reset UVs to 0/1 values
/**
* Resets UVs to 0/1 values.
*/
void resetUVs ();
// Update Us coordinates for current viewport and projection
/**
* Updates UVs coordinates for current viewport and projection
*
* @param projectionWidth
* @param projectionHeight
*/
void updateUs (const int& projectionWidth, const int& projectionHeight);
// Update Vs coordinates for current viewport and projection
/**
* Updates Vs coordinates for current viewport and projection
*
* @param projectionWidth
* @param projectionHeight
*/
void updateVs (const int& projectionWidth, const int& projectionHeight);
// Get texture UV coordinates
auto getTextureUVs () const {
/**
* @return Texture UV coordinates for current viewport and projection
*/
[[nodiscard]] auto getTextureUVs () const {
return UVs;
};
// Set texture UV coordinates according to texture scaling mode
/**
* Updates UVs coordinates for current viewport and projection
*/
template <CWallpaperState::TextureUVsScaling> void updateTextureUVs ();
// Updates state with provided values
void updateState (const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth,
const int& projectionHeight);
// @return The texture scaling mode
TextureUVsScaling getTextureUVsScaling () const {
return m_textureUVsMode;
};
/**
* @return The texture scaling mode
*/
[[nodiscard]] TextureUVsScaling getTextureUVsScaling () const;
// Set texture scaling mode
void setTextureUVsStrategy (const TextureUVsScaling strategy) {
m_textureUVsMode = strategy;
};
/**
* @return The texture clamping mode.
*/
[[nodiscard]] WallpaperEngine::Assets::ITexture::TextureFlags getClampingMode () const;
// @return The width of viewport
int getViewportWidth () const {
return viewport.width;
};
/**
* Sets the texture scaling mode
*
* @param strategy
*/
void setTextureUVsStrategy (TextureUVsScaling strategy);
// @return The height of viewport
int getViewportHeight () const {
return viewport.height;
};
/**
* @return The width of viewport
*/
[[nodiscard]] int getViewportWidth () const;
// @return The width of viewport
int getProjectionWidth () const {
return projection.width;
};
/**
* @return The height of viewport
*/
[[nodiscard]] int getViewportHeight () const;
// @return The height of viewport
int getProjectionHeight () const {
return projection.height;
};
/**
* @return The width of the projection
*/
[[nodiscard]] int getProjectionWidth () const;
/**
* @return The height of the projection
*/
[[nodiscard]] int getProjectionHeight () const;
private:
// Cached UVs value for texture coordinates. No need to recalculate if viewport and projection haven't changed.
@ -105,5 +134,6 @@ class CWallpaperState {
// Texture scaling mode
TextureUVsScaling m_textureUVsMode = TextureUVsScaling::DefaultUVs;
WallpaperEngine::Assets::ITexture::TextureFlags m_clampingMode = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
};
} // namespace WallpaperEngine::Render

View File

@ -16,9 +16,12 @@ using namespace WallpaperEngine;
using namespace WallpaperEngine::Render;
using namespace WallpaperEngine::Render::Wallpapers;
CScene::CScene (const Core::Wallpapers::CScene* scene, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper (scene, Type, context, audioContext, scalingMode),
CScene::CScene (
const Core::Wallpapers::CScene* scene, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode
) :
CWallpaper (scene, Type, context, audioContext, scalingMode, clampMode),
m_mousePosition (),
m_mousePositionLast (),
m_parallaxDisplacement () {

View File

@ -14,8 +14,10 @@ class CObject;
namespace WallpaperEngine::Render::Wallpapers {
class CScene final : public CWallpaper {
public:
CScene (const Core::Wallpapers::CScene* scene, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode);
CScene (
const Core::Wallpapers::CScene* scene, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
CCamera* getCamera () const;

View File

@ -11,9 +11,12 @@ void* get_proc_address (void* ctx, const char* name) {
return static_cast<CVideo*> (ctx)->getContext ().getDriver ().getProcAddress (name);
}
CVideo::CVideo (const Core::Wallpapers::CVideo* video, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper (video, Type, context, audioContext, scalingMode),
CVideo::CVideo (
const Core::Wallpapers::CVideo* video, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode
) :
CWallpaper (video, Type, context, audioContext, scalingMode, clampMode),
m_mpvGl (nullptr),
m_paused (false),
m_width (16),

View File

@ -10,8 +10,10 @@
namespace WallpaperEngine::Render::Wallpapers {
class CVideo final : public CWallpaper {
public:
CVideo (const Core::Wallpapers::CVideo* video, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode);
CVideo (
const Core::Wallpapers::CVideo* video, CRenderContext& context, CAudioContext& audioContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
const Core::Wallpapers::CVideo* getVideo () const;

View File

@ -10,9 +10,12 @@ using namespace WallpaperEngine::Render::Wallpapers;
using namespace WallpaperEngine::WebBrowser;
using namespace WallpaperEngine::WebBrowser::CEF;
CWeb::CWeb (const Core::Wallpapers::CWeb* web, CRenderContext& context, CAudioContext& audioContext, CWebBrowserContext& browserContext,
const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper (web, Type, context, audioContext, scalingMode),
CWeb::CWeb (
const Core::Wallpapers::CWeb* web, CRenderContext& context, CAudioContext& audioContext,
CWebBrowserContext& browserContext, const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode
) :
CWallpaper (web, Type, context, audioContext, scalingMode, clampMode),
m_browserContext (browserContext),
m_browser (),
m_client (),

View File

@ -21,41 +21,45 @@ class CRenderHandler;
}
namespace WallpaperEngine::Render::Wallpapers {
class CWeb : public CWallpaper
{
public:
CWeb (const Core::Wallpapers::CWeb* scene, CRenderContext& context, CAudioContext& audioContext, WallpaperEngine::WebBrowser::CWebBrowserContext& browserContext, const CWallpaperState::TextureUVsScaling& scalingMode);
~CWeb() override;
[[nodiscard]] int getWidth () const override { return this->m_width; }
class CWeb : public CWallpaper
{
public:
CWeb (
const Core::Wallpapers::CWeb* scene, CRenderContext& context, CAudioContext& audioContext,
WallpaperEngine::WebBrowser::CWebBrowserContext& browserContext,
const CWallpaperState::TextureUVsScaling& scalingMode,
const WallpaperEngine::Assets::ITexture::TextureFlags& clampMode);
~CWeb() override;
[[nodiscard]] int getWidth () const override { return this->m_width; }
[[nodiscard]] int getHeight () const override { return this->m_height; }
[[nodiscard]] int getHeight () const override { return this->m_height; }
void setSize (int width, int height);
void setSize (int width, int height);
protected:
void renderFrame (glm::ivec4 viewport) override;
void updateMouse (glm::ivec4 viewport);
const Core::Wallpapers::CWeb* getWeb () const {
return this->getWallpaperData ()->as<Core::Wallpapers::CWeb> ();
}
protected:
void renderFrame (glm::ivec4 viewport) override;
void updateMouse (glm::ivec4 viewport);
const Core::Wallpapers::CWeb* getWeb () const {
return this->getWallpaperData ()->as<Core::Wallpapers::CWeb> ();
}
friend class CWallpaper;
friend class CWallpaper;
static const std::string Type;
static const std::string Type;
private:
WallpaperEngine::WebBrowser::CWebBrowserContext& m_browserContext;
CefRefPtr<CefBrowser> m_browser;
CefRefPtr<WallpaperEngine::WebBrowser::CEF::CBrowserClient> m_client;
WallpaperEngine::WebBrowser::CEF::CRenderHandler* m_renderHandler = nullptr;
private:
WallpaperEngine::WebBrowser::CWebBrowserContext& m_browserContext;
CefRefPtr<CefBrowser> m_browser;
CefRefPtr<WallpaperEngine::WebBrowser::CEF::CBrowserClient> m_client;
WallpaperEngine::WebBrowser::CEF::CRenderHandler* m_renderHandler = nullptr;
int m_width;
int m_height;
int m_width;
int m_height;
WallpaperEngine::Input::MouseClickStatus m_leftClick;
WallpaperEngine::Input::MouseClickStatus m_rightClick;
WallpaperEngine::Input::MouseClickStatus m_leftClick;
WallpaperEngine::Input::MouseClickStatus m_rightClick;
glm::vec2 m_mousePosition;
glm::vec2 m_mousePositionLast;
};
glm::vec2 m_mousePosition;
glm::vec2 m_mousePositionLast;
};
}