Added support for taking a screenshot after wallpaper's up (useful for pywal and other ricing rools)

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2022-11-05 11:00:51 +01:00
parent fa67fa5b00
commit 087a0976ae
2 changed files with 104 additions and 4 deletions

View File

@ -131,6 +131,21 @@ To reduce the performance hit to your system you can reduce (or increase) the FP
./linux-wallpaperengine --fps 30 ./linux-wallpaperengine --fps 30
``` ```
## 5.6. Audio
### 5.6.1. Disable audio
It's possible to disable the audio of the background with the silent argument
```
./linux-wallpaperengine --silent
```
## 5.7. Taking a screenshot
It is possible to take a screenshot of the screen's content at the moment a background is loaded up and rendered. Useful for usage with tools like pywal to further customize your environment:
```
./linux-wallpaperengine --screenshot /path/to/screenshot/name.png
```
PNG, BMP and JPEG are supported.
## 6. Example background ## 6. Example background
This was the first background to even be compatible with the software. And It's not 100% compatible yet. Both textures and shaders are properly loaded, but there are still particles missing. This was the first background to even be compatible with the software. And It's not 100% compatible yet. Both textures and shaders are properly loaded, but there are still particles missing.

View File

@ -53,7 +53,8 @@ void print_help (const char* route)
<< " --volume <amount>\tSets the volume for all the sounds in the background" << std::endl << " --volume <amount>\tSets the volume for all the sounds in the background" << std::endl
<< " --screen-root <screen name>\tDisplay as screen's background" << std::endl << " --screen-root <screen name>\tDisplay as screen's background" << std::endl
<< " --fps <maximum-fps>\tLimits the FPS to the given number, useful to keep battery consumption low" << std::endl << " --fps <maximum-fps>\tLimits the FPS to the given number, useful to keep battery consumption low" << std::endl
<< " --assets-dir <path>\tFolder where the assets are stored" << std::endl; << " --assets-dir <path>\tFolder where the assets are stored" << std::endl
<< " --screenshot\t\tTakes a screenshot of the background" << std::endl;
} }
std::string stringPathFixes(const std::string& s) std::string stringPathFixes(const std::string& s)
@ -262,14 +263,65 @@ CVirtualContainer* buildVirtualContainer ()
return container; return container;
} }
void takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::string& filename, FREE_IMAGE_FORMAT format)
{
GLint width, height;
// 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);
// make room for storing the pixel data
uint8_t* buffer = new uint8_t [width * height * sizeof (uint8_t) * 3];
uint8_t* pixel = buffer;
// read the image into the buffer
glReadPixels (0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
// build the output file with FreeImage
FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24);
RGBQUAD color;
// now get access to the pixels
for (int y = height; y > 0; y --)
{
for (int x = 0; x < width; x ++)
{
color.rgbRed = *pixel ++;
color.rgbGreen = *pixel ++;
color.rgbBlue = *pixel ++;
// set the pixel in the destination
FreeImage_SetPixelColor (bitmap, x, y, &color);
}
}
// finally save the file
FreeImage_Save (format, bitmap, filename.c_str (), 0);
// free all the used memory
delete[] buffer;
FreeImage_Unload (bitmap);
// unbind the textures
glBindTexture (GL_TEXTURE_2D, GL_NONE);
}
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
std::vector <std::string> screens; std::vector <std::string> screens;
int maximumFPS = 30; int maximumFPS = 30;
bool shouldEnableAudio = true; bool shouldEnableAudio = true;
bool shouldTakeScreenshot = false;
FREE_IMAGE_FORMAT screenshotFormat = FIF_UNKNOWN;
std::string path; std::string path;
std::string assetsDir; std::string assetsDir;
std::string screenshotPath;
static struct option long_options [] = { static struct option long_options [] = {
{"screen-root", required_argument, 0, 'r'}, {"screen-root", required_argument, 0, 'r'},
@ -280,6 +332,7 @@ int main (int argc, char* argv[])
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{"fps", required_argument, 0, 'f'}, {"fps", required_argument, 0, 'f'},
{"assets-dir", required_argument, 0, 'a'}, {"assets-dir", required_argument, 0, 'a'},
{"screenshot", required_argument, 0, 'c'},
{nullptr, 0, 0, 0} {nullptr, 0, 0, 0}
}; };
@ -321,6 +374,11 @@ int main (int argc, char* argv[])
case 'v': case 'v':
g_AudioVolume = atoi (optarg); g_AudioVolume = atoi (optarg);
break; break;
case 'c':
shouldTakeScreenshot = true;
screenshotPath = stringPathFixes (optarg);
break;
} }
} }
@ -337,6 +395,22 @@ int main (int argc, char* argv[])
} }
} }
// validate screenshot file just to make sure
if (shouldTakeScreenshot == true)
{
// ensure the file is one of the supported formats
std::string extension = screenshotPath.substr (screenshotPath.find_last_of (".") + 1);
if (extension == "bmp")
screenshotFormat = FIF_BMP;
else if (extension == "png")
screenshotFormat = FIF_PNG;
else if (extension == "jpg" || extension == "jpeg")
screenshotFormat = FIF_JPEG;
else
throw std::runtime_error ("Unsupported screenshot format...");
}
// attach signals so if a stop is requested the X11 resources are freed and the program shutsdown gracefully // attach signals so if a stop is requested the X11 resources are freed and the program shutsdown gracefully
std::signal(SIGINT, signalhandler); std::signal(SIGINT, signalhandler);
std::signal(SIGTERM, signalhandler); std::signal(SIGTERM, signalhandler);
@ -504,6 +578,8 @@ int main (int argc, char* argv[])
double startTime, endTime, minimumTime = 1.0 / maximumFPS; double startTime, endTime, minimumTime = 1.0 / maximumFPS;
uint32_t frameCounter = 0;
while (glfwWindowShouldClose (window) == 0 && g_KeepRunning == true) while (glfwWindowShouldClose (window) == 0 && g_KeepRunning == true)
{ {
// get the real framebuffer size // get the real framebuffer size
@ -526,6 +602,15 @@ int main (int argc, char* argv[])
// ensure the frame time is correct to not overrun FPS // ensure the frame time is correct to not overrun FPS
if ((endTime - startTime) < minimumTime) if ((endTime - startTime) < minimumTime)
usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC);
frameCounter ++;
if (frameCounter == 5 && shouldTakeScreenshot == true)
{
takeScreenshot (context->getWallpaper (), screenshotPath, screenshotFormat);
// disable screenshot just in case the counter overflows
shouldTakeScreenshot = false;
}
} }
// ensure this is updated as sometimes it might not come from a signal // ensure this is updated as sometimes it might not come from a signal