#include "UniversalSwitch.hpp"
#include "Singleton.hpp"
#include "Window.hpp"
+#include "ecore.hpp"
#include <efl_util.h>
#include <cairo.h>
class ScreenshotActivity : public UIActivity, private RegisterActivity<ScreenshotActivity>
{
public:
+ ScreenshotActivity();
+ bool process() override;
+
constexpr static const char *activityType = "SCREENSHOT";
- ScreenshotActivity()
- : UIActivity(activityType), screenshotHandle(nullptr), tbmSurface(nullptr), surface(nullptr),
- size(Singleton<UniversalSwitch>::instance().getMainWindow()->getDimensions().size)
- {}
- ~ScreenshotActivity()
- {
- if (surface)
- cairo_surface_destroy(surface);
+private:
+ static void capture(const std::string &, Size);
+ static std::string generateFileName();
- if (tbmSurface)
- tbm_surface_destroy(tbmSurface);
+ ecore::Timer timer;
+ static constexpr double DELAY = 0.5;
+};
- if (screenshotHandle)
- efl_util_screenshot_deinitialize(screenshotHandle);
- }
+ScreenshotActivity::ScreenshotActivity() : UIActivity(activityType) {}
- bool process() override
- {
- char *path = nullptr;
- if (storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_IMAGES, &path))
- ERROR("storage_get_directory failed");
-
- if (path) {
- filename = path + ("/" + generateFileName());
- free(path);
- capture();
- }
+bool ScreenshotActivity::process()
+{
+ char *path = nullptr;
+ storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_IMAGES, &path);
+ auto directory = std::string {path};
+ free(path);
+
+ if (directory.empty()) {
+ ERROR("No storage path");
return true;
}
-private:
- void capture()
- {
- screenshotHandle = efl_util_screenshot_initialize(size.width, size.height);
- if (!screenshotHandle) {
- ERROR("Screenshot initialization failed");
- return;
- }
-
- tbmSurface = efl_util_screenshot_take_tbm_surface(screenshotHandle);
- if (!tbmSurface) {
- ERROR("Taking surface failed");
- return;
- }
-
- tbm_surface_info_s surfaceInfo;
- auto error = tbm_surface_get_info(tbmSurface, &surfaceInfo);
- if (error != TBM_SURFACE_ERROR_NONE) {
- ERROR("Get surface info failed");
- return;
- }
-
- if (surfaceInfo.num_planes < 1) {
- ERROR("No planes in surface");
- return;
- }
-
- auto &plane = surfaceInfo.planes[0];
- surface = cairo_image_surface_create_for_data(plane.ptr, CAIRO_FORMAT_ARGB32, size.width, size.height, plane.stride);
- if (!surface) {
- ERROR("Create cairo surface failed");
- return;
- }
-
- error = cairo_surface_write_to_png(surface, filename.c_str());
- if (error != CAIRO_STATUS_SUCCESS) {
- ERROR("Captured image failed %d", error);
- return;
- }
-
- DEBUG("Captured image: width = %d, height = %d, filename = %s", size.width, size.height, filename.c_str());
+ auto filename = directory + "/" + generateFileName();
+ timer.reset(DELAY, [this, filename]() {
+ auto mainWindow = Singleton<UniversalSwitch>::instance().getMainWindow();
+ if (mainWindow)
+ capture(filename, mainWindow->getDimensions().size);
+ else
+ ERROR("No main window");
+
+ completed = true;
+ return ecore::TimerRepetitionPolicy::cancel;
+ });
+
+ return false;
+}
+
+
+void ScreenshotActivity::capture(const std::string &filename, Size size)
+{
+ auto screenshotHandle = std::unique_ptr<_efl_util_screenshot_h, int (*)(_efl_util_screenshot_h *)> {
+ efl_util_screenshot_initialize(size.width, size.height), efl_util_screenshot_deinitialize
+ };
+
+ if (!screenshotHandle) {
+ ERROR("Screenshot initialization failed");
+ return;
}
- std::string generateFileName()
- {
- auto now = std::chrono::system_clock::now();
- auto formated = std::chrono::system_clock::to_time_t(now);
+ auto tbmSurface = std::unique_ptr<_tbm_surface, int (*)(_tbm_surface *)> {
+ efl_util_screenshot_take_tbm_surface(screenshotHandle.get()), tbm_surface_destroy
+ };
- std::stringstream ss;
- ss << std::put_time(std::localtime(&formated), "%Y%m%d-%H%M%S") << ".png";
- return ss.str();
+ if (!tbmSurface) {
+ ERROR("Taking surface failed");
+ return;
}
- efl_util_screenshot_h screenshotHandle;
- tbm_surface_h tbmSurface;
- cairo_surface_t *surface;
- Size size;
- std::string filename;
-};
+ tbm_surface_info_s surfaceInfo;
+ auto error = tbm_surface_get_info(tbmSurface.get(), &surfaceInfo);
+
+ if (error != TBM_SURFACE_ERROR_NONE) {
+ ERROR("Get surface info failed");
+ return;
+ }
+
+ if (surfaceInfo.num_planes < 1) {
+ ERROR("No planes in surface");
+ return;
+ }
+
+ auto &plane = surfaceInfo.planes[0];
+ auto surface = std::unique_ptr<cairo_surface_t, void (*)(cairo_surface_t *)> {
+ cairo_image_surface_create_for_data(plane.ptr, CAIRO_FORMAT_ARGB32, size.width, size.height, plane.stride), cairo_surface_destroy
+ };
+
+ if (!surface) {
+ ERROR("Create cairo surface failed");
+ return;
+ }
+
+ error = cairo_surface_write_to_png(surface.get(), filename.c_str());
+
+ if (error != CAIRO_STATUS_SUCCESS) {
+ ERROR("Captured image failed %d", error);
+ return;
+ }
+
+ DEBUG("Captured image: width = %d, height = %d, filename = %s", size.width, size.height, filename.c_str());
+}
+
+std::string ScreenshotActivity::generateFileName()
+{
+ auto now = std::chrono::system_clock::now();
+ auto formated = std::chrono::system_clock::to_time_t(now);
+
+ std::stringstream ss;
+ ss << std::put_time(std::localtime(&formated), "%Y%m%d-%H%M%S") << ".png";
+ return ss.str();
+}
\ No newline at end of file