File indexing completed on 2025-02-02 04:26:13

0001 /* This file is part of Spectacle, the KDE screenshot utility
0002  * SPDX-FileCopyrightText: 2019 Boudhayan Gupta <bgupta@kde.org>
0003 
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "PlatformLoader.h"
0008 #include "Config.h"
0009 #include "PlasmaVersion.h"
0010 #include "ScreenShotEffect.h"
0011 
0012 #include "ImagePlatformKWin.h"
0013 #include "PlatformNull.h"
0014 #include "VideoPlatformWayland.h"
0015 
0016 #ifdef XCB_FOUND
0017 #include "ImagePlatformXcb.h"
0018 #endif
0019 
0020 #include <KWindowSystem>
0021 
0022 #include <QDebug>
0023 
0024 ImagePlatformPtr getForcedImagePlatform()
0025 {
0026     // This environment variable is only for testing purposes.
0027     auto platformName = qgetenv("SPECTACLE_IMAGE_PLATFORM");
0028     if (platformName.isEmpty()) {
0029         return nullptr;
0030     }
0031 
0032     if (platformName == ImagePlatformKWin::staticMetaObject.className()) {
0033         return std::make_unique<ImagePlatformKWin>();
0034     } else if (platformName == ImagePlatformXcb::staticMetaObject.className()) {
0035         return std::make_unique<ImagePlatformXcb>();
0036     } else if (platformName == ImagePlatformNull::staticMetaObject.className()) {
0037         return std::make_unique<ImagePlatformNull>();
0038     } else if (!platformName.isEmpty()) {
0039         qWarning() << "SPECTACLE_IMAGE_PLATFORM:" << platformName << "is invalid";
0040     }
0041 
0042     return nullptr;
0043 }
0044 
0045 ImagePlatformPtr loadImagePlatform()
0046 {
0047     if (auto platform = getForcedImagePlatform()) {
0048         return platform;
0049     }
0050 
0051     // Check XDG_SESSION_TYPE because Spectacle might be using the XCB platform via XWayland
0052     const bool isReallyX11 = KWindowSystem::isPlatformX11() && qstrcmp(qgetenv("XDG_SESSION_TYPE").constData(), "wayland") != 0;
0053     // Before KWin 5.27.8, there was an infinite loop in KWin on X11 when doing rectangle captures.
0054     // Spectacle uses CaptureScreen DBus calls to KWin for rectangle captures.
0055     if (ScreenShotEffect::isLoaded() && ScreenShotEffect::version() != ScreenShotEffect::NullVersion
0056         && (!isReallyX11 || PlasmaVersion::get() >= PlasmaVersion::check(5, 27, 8))) {
0057         return std::make_unique<ImagePlatformKWin>();
0058     }
0059 #ifdef XCB_FOUND
0060     else if (isReallyX11) {
0061         return std::make_unique<ImagePlatformXcb>();
0062     }
0063 #endif
0064     // If nothing else worked, return the null platform
0065     return std::make_unique<ImagePlatformNull>();
0066 }
0067 
0068 VideoPlatformPtr getForcedVideoPlatform()
0069 {
0070     // This environment variable is only for testing purposes.
0071     auto platformName = qgetenv("SPECTACLE_VIDEO_PLATFORM");
0072     if (platformName.isEmpty()) {
0073         return nullptr;
0074     }
0075 
0076     if (platformName == VideoPlatformWayland::staticMetaObject.className()) {
0077         return std::make_unique<VideoPlatformWayland>();
0078     } else if (platformName == VideoPlatformNull::staticMetaObject.className()) {
0079         return std::make_unique<VideoPlatformNull>();
0080     } else if (!platformName.isEmpty()) {
0081         qWarning() << "SPECTACLE_VIDEO_PLATFORM:" << platformName << "is invalid";
0082     }
0083 
0084     return nullptr;
0085 }
0086 
0087 VideoPlatformPtr loadVideoPlatform()
0088 {
0089     if (auto platform = getForcedVideoPlatform()) {
0090         return platform;
0091     }
0092     if (KWindowSystem::isPlatformWayland()) {
0093         return std::make_unique<VideoPlatformWayland>();
0094     }
0095     return std::make_unique<VideoPlatformNull>();
0096 }