diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/utils/Screenshot.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/utils/Screenshot.cpp')
-rw-r--r-- | xbmc/utils/Screenshot.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/xbmc/utils/Screenshot.cpp b/xbmc/utils/Screenshot.cpp new file mode 100644 index 0000000..25ecbac --- /dev/null +++ b/xbmc/utils/Screenshot.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "Screenshot.h" + +#include "ServiceBroker.h" +#include "URL.h" +#include "Util.h" +#include "filesystem/File.h" +#include "guilib/LocalizeStrings.h" +#include "pictures/Picture.h" +#include "settings/SettingPath.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "settings/windows/GUIControlSettings.h" +#include "utils/JobManager.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +using namespace XFILE; + +std::vector<std::function<std::unique_ptr<IScreenshotSurface>()>> CScreenShot::m_screenShotSurfaces; + +void CScreenShot::Register(const std::function<std::unique_ptr<IScreenshotSurface>()>& createFunc) +{ + m_screenShotSurfaces.emplace_back(createFunc); +} + +void CScreenShot::TakeScreenshot(const std::string& filename, bool sync) +{ + auto surface = m_screenShotSurfaces.back()(); + + if (!surface) + { + CLog::Log(LOGERROR, "failed to create screenshot surface"); + return; + } + + if (!surface->Capture()) + { + CLog::Log(LOGERROR, "Screenshot {} failed", CURL::GetRedacted(filename)); + return; + } + + surface->CaptureVideo(true); + + CLog::Log(LOGDEBUG, "Saving screenshot {}", CURL::GetRedacted(filename)); + + //set alpha byte to 0xFF + for (int y = 0; y < surface->GetHeight(); y++) + { + unsigned char* alphaptr = surface->GetBuffer() - 1 + y * surface->GetStride(); + for (int x = 0; x < surface->GetWidth(); x++) + *(alphaptr += 4) = 0xFF; + } + + //if sync is true, the png file needs to be completely written when this function returns + if (sync) + { + if (!CPicture::CreateThumbnailFromSurface(surface->GetBuffer(), surface->GetWidth(), surface->GetHeight(), surface->GetStride(), filename)) + CLog::Log(LOGERROR, "Unable to write screenshot {}", CURL::GetRedacted(filename)); + + surface->ReleaseBuffer(); + } + else + { + //make sure the file exists to avoid concurrency issues + XFILE::CFile file; + if (file.OpenForWrite(filename)) + file.Close(); + else + CLog::Log(LOGERROR, "Unable to create file {}", CURL::GetRedacted(filename)); + + //write .png file asynchronous with CThumbnailWriter, prevents stalling of the render thread + //buffer is deleted from CThumbnailWriter + CThumbnailWriter* thumbnailwriter = new CThumbnailWriter(surface->GetBuffer(), surface->GetWidth(), surface->GetHeight(), surface->GetStride(), filename); + CServiceBroker::GetJobManager()->AddJob(thumbnailwriter, nullptr); + } +} + +void CScreenShot::TakeScreenshot() +{ + std::shared_ptr<CSettingPath> screenshotSetting = std::static_pointer_cast<CSettingPath>(CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(CSettings::SETTING_DEBUG_SCREENSHOTPATH)); + if (!screenshotSetting) + return; + + std::string strDir = screenshotSetting->GetValue(); + if (strDir.empty()) + { + if (!CGUIControlButtonSetting::GetPath(screenshotSetting, &g_localizeStrings)) + return; + + strDir = screenshotSetting->GetValue(); + } + + URIUtils::RemoveSlashAtEnd(strDir); + + if (!strDir.empty()) + { + std::string file = + CUtil::GetNextFilename(URIUtils::AddFileToFolder(strDir, "screenshot{:05}.png"), 65535); + + if (!file.empty()) + { + TakeScreenshot(file, false); + } + else + { + CLog::Log(LOGWARNING, "Too many screen shots or invalid folder"); + } + } +} |