| 1 | // Copyright (C) 2023 The Qt Company Ltd. | 
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
| 3 |  | 
| 4 | #include "qwindowcapture.h" | 
| 5 | #include "qplatformmediaintegration_p.h" | 
| 6 | #include "qmediacapturesession.h" | 
| 7 | #include "private/qobject_p.h" | 
| 8 | #include "private/qplatformsurfacecapture_p.h" | 
| 9 |  | 
| 10 | QT_BEGIN_NAMESPACE | 
| 11 |  | 
| 12 | static QWindowCapture::Error toWindowCaptureError(QPlatformSurfaceCapture::Error error) | 
| 13 | { | 
| 14 |     return static_cast<QWindowCapture::Error>(error); | 
| 15 | } | 
| 16 |  | 
| 17 | class QWindowCapturePrivate : public QObjectPrivate | 
| 18 | { | 
| 19 | public: | 
| 20 |     QMediaCaptureSession *captureSession = nullptr; | 
| 21 |     std::unique_ptr<QPlatformSurfaceCapture> platformWindowCapture; | 
| 22 | }; | 
| 23 |  | 
| 24 | /*! | 
| 25 |     \class QWindowCapture | 
| 26 |     \inmodule QtMultimedia | 
| 27 |     \ingroup multimedia | 
| 28 |     \ingroup multimedia_video | 
| 29 |     \since 6.6 | 
| 30 |  | 
| 31 |     \brief This class is used for capturing a window. | 
| 32 |  | 
| 33 |     The class captures a window. It is managed by | 
| 34 |     the QMediaCaptureSession class where the captured window can be displayed | 
| 35 |     in a video preview object or recorded to a file. | 
| 36 |  | 
| 37 |     \include qwindowcapture-limitations.qdocinc {content} {Q} | 
| 38 |  | 
| 39 |     \sa QMediaCaptureSession, QCapturableWindow | 
| 40 | */ | 
| 41 | /*! | 
| 42 |     \qmltype WindowCapture | 
| 43 |     \nativetype QWindowCapture | 
| 44 |     \inqmlmodule QtMultimedia | 
| 45 |     \ingroup multimedia_qml | 
| 46 |     \ingroup multimedia_video_qml | 
| 47 |     \since 6.6 | 
| 48 |  | 
| 49 |     \brief This type is used for capturing a window. | 
| 50 |  | 
| 51 |     WindowCapture captures a window. It is managed by | 
| 52 |     MediaCaptureSession where the captured window can be displayed | 
| 53 |     in a video preview object or recorded to a file. | 
| 54 |  | 
| 55 |     \include qwindowcapture-limitations.qdocinc {content} {} | 
| 56 |  | 
| 57 |     \sa CaptureSession, CapturableWindow | 
| 58 | */ | 
| 59 |  | 
| 60 | /*! | 
| 61 |     \enum QWindowCapture::Error | 
| 62 |  | 
| 63 |     Enumerates error codes that can be signaled by the QWindowCapture class. | 
| 64 |     errorString() provides detailed information about the error cause. | 
| 65 |  | 
| 66 |     \value NoError                      No error | 
| 67 |     \value InternalError                Internal window capturing driver error | 
| 68 |     \value CapturingNotSupported        Window capturing is not supported | 
| 69 |     \value CaptureFailed                Capturing window failed | 
| 70 |     \value NotFound                     Selected window not found | 
| 71 | */ | 
| 72 |  | 
| 73 | /*! | 
| 74 |     Constructs a new QWindowCapture object with \a parent. | 
| 75 | */ | 
| 76 | QWindowCapture::QWindowCapture(QObject *parent) : QObject(*new QWindowCapturePrivate, parent) | 
| 77 | { | 
| 78 |     Q_D(QWindowCapture); | 
| 79 |  | 
| 80 |     qRegisterMetaType<QCapturableWindow>(); | 
| 81 |  | 
| 82 |     auto platformCapture = QPlatformMediaIntegration::instance()->createWindowCapture(this); | 
| 83 |  | 
| 84 |     if (platformCapture) { | 
| 85 |         connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::activeChanged, context: this, | 
| 86 |                 slot: &QWindowCapture::activeChanged); | 
| 87 |         connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::errorChanged, context: this, | 
| 88 |                 slot: &QWindowCapture::errorChanged); | 
| 89 |         connect(sender: platformCapture, signal: &QPlatformSurfaceCapture::errorOccurred, context: this, | 
| 90 |                 slot: [this](QPlatformSurfaceCapture::Error error, QString errorString) { | 
| 91 |                     emit errorOccurred(error: toWindowCaptureError(error), errorString); | 
| 92 |                 }); | 
| 93 |         connect(sender: platformCapture, | 
| 94 |                 signal: qOverload<QCapturableWindow>(&QPlatformSurfaceCapture::sourceChanged), context: this, | 
| 95 |                 slot: &QWindowCapture::windowChanged); | 
| 96 |  | 
| 97 |         d->platformWindowCapture.reset(p: platformCapture); | 
| 98 |     } | 
| 99 | } | 
| 100 |  | 
| 101 | /*! | 
| 102 |     Destroys the object. | 
| 103 |  */ | 
| 104 | QWindowCapture::~QWindowCapture() | 
| 105 | { | 
| 106 |     Q_D(QWindowCapture); | 
| 107 |  | 
| 108 |     d->platformWindowCapture.reset(); | 
| 109 |  | 
| 110 |     if (d->captureSession) | 
| 111 |         d->captureSession->setWindowCapture(nullptr); | 
| 112 | } | 
| 113 |  | 
| 114 | /*! | 
| 115 |     \qmlmethod list<CapturableWindow> QtMultimedia::WindowCapture::capturableWindows() | 
| 116 |  | 
| 117 |     Returns a list of CapturableWindow objects that is available for capturing. | 
| 118 | */ | 
| 119 | /*! | 
| 120 |     \fn QList<QCapturableWindow> QWindowCapture::capturableWindows() | 
| 121 |  | 
| 122 |     Returns a list of QCapturableWindow objects that is available for capturing. | 
| 123 |  */ | 
| 124 | QList<QCapturableWindow> QWindowCapture::capturableWindows() | 
| 125 | { | 
| 126 |     return QPlatformMediaIntegration::instance()->capturableWindowsList(); | 
| 127 | } | 
| 128 |  | 
| 129 | QMediaCaptureSession *QWindowCapture::captureSession() const | 
| 130 | { | 
| 131 |     Q_D(const QWindowCapture); | 
| 132 |  | 
| 133 |     return d->captureSession; | 
| 134 | } | 
| 135 |  | 
| 136 | /*! | 
| 137 |     \qmlproperty Window QtMultimedia::WindowCapture::window | 
| 138 |     Describes the window for capturing. | 
| 139 |  | 
| 140 |     \sa QtMultimedia::WindowCapture::capturableWindows | 
| 141 | */ | 
| 142 |  | 
| 143 | /*! | 
| 144 |     \property QWindowCapture::window | 
| 145 |     \brief the window for capturing. | 
| 146 |  | 
| 147 |     \sa QWindowCapture::capturableWindows | 
| 148 | */ | 
| 149 | QCapturableWindow QWindowCapture::window() const | 
| 150 | { | 
| 151 |     Q_D(const QWindowCapture); | 
| 152 |  | 
| 153 |     return d->platformWindowCapture ? d->platformWindowCapture->source<QCapturableWindow>() | 
| 154 |                                     : QCapturableWindow(); | 
| 155 | } | 
| 156 |  | 
| 157 | void QWindowCapture::setWindow(QCapturableWindow window) | 
| 158 | { | 
| 159 |     Q_D(QWindowCapture); | 
| 160 |  | 
| 161 |     if (d->platformWindowCapture) | 
| 162 |         d->platformWindowCapture->setSource(window); | 
| 163 | } | 
| 164 |  | 
| 165 | /*! | 
| 166 |     \qmlproperty bool QtMultimedia::WindowCapture::active | 
| 167 |     Describes whether the capturing is currently active. | 
| 168 | */ | 
| 169 |  | 
| 170 | /*! | 
| 171 |     \property QWindowCapture::active | 
| 172 |     \brief whether the capturing is currently active. | 
| 173 |  | 
| 174 |     \sa start(), stop() | 
| 175 | */ | 
| 176 | bool QWindowCapture::isActive() const | 
| 177 | { | 
| 178 |     Q_D(const QWindowCapture); | 
| 179 |  | 
| 180 |     return d->platformWindowCapture && d->platformWindowCapture->isActive(); | 
| 181 | } | 
| 182 |  | 
| 183 | void QWindowCapture::setActive(bool active) | 
| 184 | { | 
| 185 |     Q_D(QWindowCapture); | 
| 186 |  | 
| 187 |     if (d->platformWindowCapture) | 
| 188 |         d->platformWindowCapture->setActive(active); | 
| 189 | } | 
| 190 |  | 
| 191 | /*! | 
| 192 |     \qmlmethod QtMultimedia::WindowCapture::start | 
| 193 | */ | 
| 194 |  | 
| 195 | /*! | 
| 196 |     \fn void QWindowCapture::start() | 
| 197 |  | 
| 198 |     Starts capturing the \l window. | 
| 199 |  | 
| 200 |     This is equivalent to setting the \l active property to true. | 
| 201 | */ | 
| 202 |  | 
| 203 | /*! | 
| 204 |     \qmlmethod QtMultimedia::WindowCapture::stop | 
| 205 | */ | 
| 206 |  | 
| 207 | /*! | 
| 208 |     \fn void QWindowCapture::stop() | 
| 209 |  | 
| 210 |     Stops capturing. | 
| 211 |  | 
| 212 |     This is equivalent to setting the \l active property to false. | 
| 213 | */ | 
| 214 |  | 
| 215 |  | 
| 216 | /*! | 
| 217 |     \qmlproperty enumeration QtMultimedia::WindowCapture::error | 
| 218 |     Returns a code of the last error. | 
| 219 | */ | 
| 220 |  | 
| 221 | /*! | 
| 222 |     \property QWindowCapture::error | 
| 223 |     \brief the code of the last error. | 
| 224 | */ | 
| 225 | QWindowCapture::Error QWindowCapture::error() const | 
| 226 | { | 
| 227 |     Q_D(const QWindowCapture); | 
| 228 |  | 
| 229 |     return d->platformWindowCapture ? toWindowCaptureError(error: d->platformWindowCapture->error()) | 
| 230 |                                     : CapturingNotSupported; | 
| 231 | } | 
| 232 |  | 
| 233 | /*! | 
| 234 |     \fn void QWindowCapture::errorOccurred(QWindowCapture::Error error, const QString &errorString) | 
| 235 |  | 
| 236 |     Signals when an \a error occurs, along with the \a errorString. | 
| 237 | */ | 
| 238 | /*! | 
| 239 |     \qmlproperty string QtMultimedia::WindowCapture::errorString | 
| 240 |     Returns a human readable string describing the cause of error. | 
| 241 | */ | 
| 242 |  | 
| 243 | /*! | 
| 244 |     \property QWindowCapture::errorString | 
| 245 |     \brief a human readable string describing the cause of error. | 
| 246 | */ | 
| 247 | QString QWindowCapture::errorString() const | 
| 248 | { | 
| 249 |     Q_D(const QWindowCapture); | 
| 250 |  | 
| 251 |     return d->platformWindowCapture | 
| 252 |             ? d->platformWindowCapture->errorString() | 
| 253 |             : QLatin1StringView("Capturing is not support on this platform" ); | 
| 254 | } | 
| 255 |  | 
| 256 | void QWindowCapture::setCaptureSession(QMediaCaptureSession *captureSession) | 
| 257 | { | 
| 258 |     Q_D(QWindowCapture); | 
| 259 |  | 
| 260 |     d->captureSession = captureSession; | 
| 261 | } | 
| 262 |  | 
| 263 | QPlatformSurfaceCapture *QWindowCapture::platformWindowCapture() const | 
| 264 | { | 
| 265 |     Q_D(const QWindowCapture); | 
| 266 |  | 
| 267 |     return d->platformWindowCapture.get(); | 
| 268 | } | 
| 269 |  | 
| 270 | QT_END_NAMESPACE | 
| 271 |  | 
| 272 | #include "moc_qwindowcapture.cpp" | 
| 273 |  |