[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / utils / Screenshot.cpp
blob25ecbac0803f05bd1ee7150239bb06a14bc24fb6
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "Screenshot.h"
11 #include "ServiceBroker.h"
12 #include "URL.h"
13 #include "Util.h"
14 #include "filesystem/File.h"
15 #include "guilib/LocalizeStrings.h"
16 #include "pictures/Picture.h"
17 #include "settings/SettingPath.h"
18 #include "settings/Settings.h"
19 #include "settings/SettingsComponent.h"
20 #include "settings/windows/GUIControlSettings.h"
21 #include "utils/JobManager.h"
22 #include "utils/URIUtils.h"
23 #include "utils/log.h"
25 using namespace XFILE;
27 std::vector<std::function<std::unique_ptr<IScreenshotSurface>()>> CScreenShot::m_screenShotSurfaces;
29 void CScreenShot::Register(const std::function<std::unique_ptr<IScreenshotSurface>()>& createFunc)
31 m_screenShotSurfaces.emplace_back(createFunc);
34 void CScreenShot::TakeScreenshot(const std::string& filename, bool sync)
36 auto surface = m_screenShotSurfaces.back()();
38 if (!surface)
40 CLog::Log(LOGERROR, "failed to create screenshot surface");
41 return;
44 if (!surface->Capture())
46 CLog::Log(LOGERROR, "Screenshot {} failed", CURL::GetRedacted(filename));
47 return;
50 surface->CaptureVideo(true);
52 CLog::Log(LOGDEBUG, "Saving screenshot {}", CURL::GetRedacted(filename));
54 //set alpha byte to 0xFF
55 for (int y = 0; y < surface->GetHeight(); y++)
57 unsigned char* alphaptr = surface->GetBuffer() - 1 + y * surface->GetStride();
58 for (int x = 0; x < surface->GetWidth(); x++)
59 *(alphaptr += 4) = 0xFF;
62 //if sync is true, the png file needs to be completely written when this function returns
63 if (sync)
65 if (!CPicture::CreateThumbnailFromSurface(surface->GetBuffer(), surface->GetWidth(), surface->GetHeight(), surface->GetStride(), filename))
66 CLog::Log(LOGERROR, "Unable to write screenshot {}", CURL::GetRedacted(filename));
68 surface->ReleaseBuffer();
70 else
72 //make sure the file exists to avoid concurrency issues
73 XFILE::CFile file;
74 if (file.OpenForWrite(filename))
75 file.Close();
76 else
77 CLog::Log(LOGERROR, "Unable to create file {}", CURL::GetRedacted(filename));
79 //write .png file asynchronous with CThumbnailWriter, prevents stalling of the render thread
80 //buffer is deleted from CThumbnailWriter
81 CThumbnailWriter* thumbnailwriter = new CThumbnailWriter(surface->GetBuffer(), surface->GetWidth(), surface->GetHeight(), surface->GetStride(), filename);
82 CServiceBroker::GetJobManager()->AddJob(thumbnailwriter, nullptr);
86 void CScreenShot::TakeScreenshot()
88 std::shared_ptr<CSettingPath> screenshotSetting = std::static_pointer_cast<CSettingPath>(CServiceBroker::GetSettingsComponent()->GetSettings()->GetSetting(CSettings::SETTING_DEBUG_SCREENSHOTPATH));
89 if (!screenshotSetting)
90 return;
92 std::string strDir = screenshotSetting->GetValue();
93 if (strDir.empty())
95 if (!CGUIControlButtonSetting::GetPath(screenshotSetting, &g_localizeStrings))
96 return;
98 strDir = screenshotSetting->GetValue();
101 URIUtils::RemoveSlashAtEnd(strDir);
103 if (!strDir.empty())
105 std::string file =
106 CUtil::GetNextFilename(URIUtils::AddFileToFolder(strDir, "screenshot{:05}.png"), 65535);
108 if (!file.empty())
110 TakeScreenshot(file, false);
112 else
114 CLog::Log(LOGWARNING, "Too many screen shots or invalid folder");