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 "qx11capturablewindows_p.h"
5#include "private/qcapturablewindow_p.h"
6#include <qdebug.h>
7
8#include <X11/Xlib.h>
9
10QT_BEGIN_NAMESPACE
11
12QX11CapturableWindows::~QX11CapturableWindows()
13{
14 if (m_display)
15 XCloseDisplay(m_display);
16}
17
18QList<QCapturableWindow> QX11CapturableWindows::windows() const
19{
20 auto display = this->display();
21
22 if (!display)
23 return {};
24
25 Atom atom = XInternAtom(display, "_NET_CLIENT_LIST", true);
26 Atom actualType = 0;
27 int format = 0;
28 unsigned long windowsCount = 0;
29 unsigned long bytesAfter = 0;
30 unsigned char *data = nullptr;
31 const int status = XGetWindowProperty(display, XDefaultRootWindow(display), atom, 0L, (~0L),
32 false, AnyPropertyType, &actualType, &format,
33 &windowsCount, &bytesAfter, &data);
34
35 if (status < Success || !data)
36 return {};
37
38 QList<QCapturableWindow> result;
39
40 auto freeDataGuard = qScopeGuard(f: [data]() { XFree(data); });
41 auto windows = reinterpret_cast<XID *>(data);
42 for (unsigned long i = 0; i < windowsCount; i++) {
43 auto windowData = std::make_unique<QCapturableWindowPrivate>();
44 windowData->id = static_cast<QCapturableWindowPrivate::Id>(windows[i]);
45
46 char *windowTitle = nullptr;
47 if (XFetchName(display, windows[i], &windowTitle) && windowTitle) {
48 windowData->description = QString::fromUtf8(utf8: windowTitle);
49 XFree(windowTitle);
50 }
51
52 if (isWindowValid(window: *windowData))
53 result.push_back(t: windowData.release()->create());
54 }
55
56 return result;
57}
58
59bool QX11CapturableWindows::isWindowValid(const QCapturableWindowPrivate &window) const
60{
61 auto display = this->display();
62 XWindowAttributes windowAttributes = {};
63 return display
64 && XGetWindowAttributes(display, static_cast<Window>(window.id), &windowAttributes) != 0
65 && windowAttributes.depth > 0;
66}
67
68Display *QX11CapturableWindows::display() const
69{
70 std::call_once(once&: m_displayOnceFlag, f: [this]() { m_display = XOpenDisplay(nullptr); });
71 return m_display;
72}
73
74QT_END_NAMESPACE
75

source code of qtmultimedia/src/plugins/multimedia/ffmpeg/qx11capturablewindows.cpp