1 /********************************************************************
2 Copyright © 2020 Roman Gilg <subdiff@gmail.com>
3 
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #include "../../src/client/connection_thread.h"
21 #include "../../src/client/event_queue.h"
22 #include "../../src/client/output.h"
23 #include "../../src/client/registry.h"
24 #include "../../src/client/wlr_output_configuration_v1.h"
25 #include "../../src/client/wlr_output_manager_v1.h"
26 
27 #include "../../server/compositor.h"
28 #include "../../server/display.h"
29 #include "../../server/output.h"
30 #include "../../server/output_configuration_v1.h"
31 #include "../../server/output_management_v1.h"
32 
33 #include <QtTest>
34 
35 #include <wayland-client-protocol.h>
36 
37 namespace Clt = Wrapland::Client;
38 namespace Srv = Wrapland::Server;
39 
40 class TestWlrOutputManagement : public QObject
41 {
42     Q_OBJECT
43 public:
44     explicit TestWlrOutputManagement(QObject* parent = nullptr);
45 private Q_SLOTS:
46     void init();
47     void cleanup();
48 
49 private:
50     Srv::Display* m_display;
51     Srv::OutputManagementV1* m_outputManagementInterface;
52     QList<Srv::Output*> m_serverOutputs;
53 
54     Clt::Registry* m_registry = nullptr;
55     Clt::WlrOutputHeadV1* m_outputHead = nullptr;
56     Clt::WlrOutputManagerV1* m_outputManager = nullptr;
57     Clt::WlrOutputConfigurationV1* m_outputConfiguration = nullptr;
58     QList<Clt::WlrOutputHeadV1*> m_clientOutputs;
59     QList<Srv::Output::Mode> m_modes;
60 
61     Clt::ConnectionThread* m_connection = nullptr;
62     Clt::EventQueue* m_queue = nullptr;
63     QThread* m_thread;
64 
65     QSignalSpy* m_announcedSpy;
66     QSignalSpy* m_omSpy;
67     QSignalSpy* m_configSpy;
68 };
69 
70 static const QString s_socketName = QStringLiteral("wrapland-test-output-0");
71 
TestWlrOutputManagement(QObject * parent)72 TestWlrOutputManagement::TestWlrOutputManagement(QObject* parent)
73     : QObject(parent)
74     , m_display(nullptr)
75     , m_outputManagementInterface(nullptr)
76     , m_connection(nullptr)
77     , m_queue(nullptr)
78     , m_thread(nullptr)
79     , m_announcedSpy(nullptr)
80 {
81     qRegisterMetaType<Srv::OutputConfigurationV1*>();
82 }
83 
init()84 void TestWlrOutputManagement::init()
85 {
86     m_display = new Srv::Display(this);
87     m_display->setSocketName(s_socketName);
88     m_display->createCompositor(this);
89 
90     auto server_output = new Srv::Output(m_display, this);
91 
92     Srv::Output::Mode m0;
93     m0.id = 0;
94     m0.size = QSize(800, 600);
95     m0.preferred = true;
96     server_output->add_mode(m0);
97 
98     Srv::Output::Mode m1;
99     m1.id = 1;
100     m1.size = QSize(1024, 768);
101     server_output->add_mode(m1);
102 
103     Srv::Output::Mode m2;
104     m2.id = 2;
105     m2.size = QSize(1280, 1024);
106     m2.refresh_rate = 90000;
107     server_output->add_mode(m2);
108 
109     Srv::Output::Mode m3;
110     m3.id = 3;
111     m3.size = QSize(1920, 1080);
112     m3.refresh_rate = 100000;
113     server_output->add_mode(m3);
114 
115     m_modes << m0 << m1 << m2 << m3;
116 
117     server_output->set_mode(1);
118     server_output->set_geometry(QRectF(QPointF(0, 1920), QSizeF(1024, 768)));
119     m_serverOutputs << server_output;
120 
121     m_outputManagementInterface = m_display->createOutputManagementV1(this);
122 
123     // setup connection
124     m_connection = new Clt::ConnectionThread;
125     QSignalSpy connectedSpy(m_connection, &Clt::ConnectionThread::establishedChanged);
126     m_connection->setSocketName(s_socketName);
127 
128     m_thread = new QThread(this);
129     m_connection->moveToThread(m_thread);
130     m_thread->start();
131 
132     m_connection->establishConnection();
133     QVERIFY(connectedSpy.count() || connectedSpy.wait());
134     QCOMPARE(connectedSpy.count(), 1);
135 
136     m_queue = new Clt::EventQueue(this);
137     QVERIFY(!m_queue->isValid());
138     m_queue->setup(m_connection);
139     QVERIFY(m_queue->isValid());
140 
141     m_registry = new Clt::Registry();
142 
143     m_announcedSpy = new QSignalSpy(m_registry, &Clt::Registry::wlrOutputManagerV1Announced);
144     m_omSpy = new QSignalSpy(m_registry, &Clt::Registry::outputDeviceV1Announced);
145 
146     QVERIFY(m_announcedSpy->isValid());
147     QVERIFY(m_omSpy->isValid());
148 
149     m_registry->create(m_connection->display());
150     QVERIFY(m_registry->isValid());
151     m_registry->setEventQueue(m_queue);
152     m_registry->setup();
153     wl_display_flush(m_connection->display());
154 
155     // We currently don't have a server implementation for the wlr_output_management_unstable_v1
156     // protocol.
157     QVERIFY(!m_announcedSpy->wait(500));
158     QCOMPARE(m_announcedSpy->count(), 0);
159 }
160 
cleanup()161 void TestWlrOutputManagement::cleanup()
162 {
163     if (m_outputConfiguration) {
164         delete m_outputConfiguration;
165         m_outputConfiguration = nullptr;
166     }
167     delete m_outputHead;
168     m_clientOutputs.clear();
169     if (m_outputManager) {
170         delete m_outputManager;
171         m_outputManager = nullptr;
172     }
173 
174     delete m_announcedSpy;
175     delete m_omSpy;
176 
177     if (m_registry) {
178         delete m_registry;
179         m_registry = nullptr;
180     }
181     if (m_queue) {
182         delete m_queue;
183         m_queue = nullptr;
184     }
185     if (m_connection) {
186         m_connection->deleteLater();
187         m_connection = nullptr;
188     }
189     if (m_thread) {
190         m_thread->quit();
191         m_thread->wait();
192         delete m_thread;
193         m_thread = nullptr;
194     }
195 
196     if (m_outputManagementInterface) {
197         delete m_outputManagementInterface;
198         m_outputManagementInterface = nullptr;
199     }
200     delete m_display;
201     m_display = nullptr;
202     m_serverOutputs.clear();
203 }
204 
205 QTEST_GUILESS_MAIN(TestWlrOutputManagement)
206 #include "wlr_output_management.moc"
207