1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include "mockcompositor.h"
43 #include "mocksurface.h"
45 MockCompositor::MockCompositor()
50 pthread_create(&m_thread, 0, run, this);
53 m_waitCondition.wait(&m_mutex);
57 MockCompositor::~MockCompositor()
60 m_waitCondition.wakeOne();
61 pthread_join(m_thread, 0);
64 void MockCompositor::lock()
69 void MockCompositor::unlock()
74 void MockCompositor::applicationInitialized()
79 int MockCompositor::waylandFileDescriptor() const
81 return m_compositor->fileDescriptor();
84 void MockCompositor::processWaylandEvents()
86 m_waitCondition.wakeOne();
89 void MockCompositor::setOutputGeometry(const QRect &rect)
91 Command command = makeCommand(Impl::Compositor::setOutputGeometry, m_compositor);
92 command.parameters << rect;
93 processCommand(command);
96 void MockCompositor::setKeyboardFocus(const QSharedPointer<MockSurface> &surface)
98 Command command = makeCommand(Impl::Compositor::setKeyboardFocus, m_compositor);
99 command.parameters << QVariant::fromValue(surface);
100 processCommand(command);
103 void MockCompositor::sendMousePress(const QSharedPointer<MockSurface> &surface, const QPoint &pos)
105 Command command = makeCommand(Impl::Compositor::sendMousePress, m_compositor);
106 command.parameters << QVariant::fromValue(surface) << pos;
107 processCommand(command);
110 void MockCompositor::sendMouseRelease(const QSharedPointer<MockSurface> &surface)
112 Command command = makeCommand(Impl::Compositor::sendMouseRelease, m_compositor);
113 command.parameters << QVariant::fromValue(surface);
114 processCommand(command);
117 void MockCompositor::sendKeyPress(const QSharedPointer<MockSurface> &surface, uint code)
119 Command command = makeCommand(Impl::Compositor::sendKeyPress, m_compositor);
120 command.parameters << QVariant::fromValue(surface) << code;
121 processCommand(command);
124 void MockCompositor::sendKeyRelease(const QSharedPointer<MockSurface> &surface, uint code)
126 Command command = makeCommand(Impl::Compositor::sendKeyRelease, m_compositor);
127 command.parameters << QVariant::fromValue(surface) << code;
128 processCommand(command);
131 QSharedPointer<MockSurface> MockCompositor::surface()
133 QSharedPointer<MockSurface> result;
135 QVector<Impl::Surface *> surfaces = m_compositor->surfaces();
136 if (!surfaces.isEmpty())
137 result = surfaces.first()->mockSurface();
142 MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target)
145 command.callback = callback;
146 command.target = target;
150 void MockCompositor::processCommand(const Command &command)
153 m_commandQueue << command;
156 m_waitCondition.wakeOne();
159 void MockCompositor::dispatchCommands()
161 foreach (const Command &command, m_commandQueue)
162 command.callback(command.target, command.parameters);
163 m_commandQueue.clear();
166 void *MockCompositor::run(void *data)
168 MockCompositor *controller = static_cast<MockCompositor *>(data);
170 Impl::Compositor compositor;
172 controller->m_compositor = &compositor;
173 controller->m_waitCondition.wakeOne();
175 while (!controller->m_ready) {
176 controller->dispatchCommands();
177 compositor.dispatchEvents(20);
180 while (controller->m_alive) {
181 QMutexLocker locker(&controller->m_mutex);
182 controller->m_waitCondition.wait(&controller->m_mutex);
183 controller->dispatchCommands();
184 compositor.dispatchEvents(20);
192 Compositor::Compositor()
193 : m_display(wl_display_create())
196 wl_list_init(&m_outputResources);
198 wl_display_add_socket(m_display, 0);
200 wl_seat_init(&m_seat);
201 wl_pointer_init(&m_pointer);
202 wl_seat_set_pointer(&m_seat, &m_pointer);
203 wl_keyboard_init(&m_keyboard);
204 wl_seat_set_keyboard(&m_seat, &m_keyboard);
206 wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor);
207 wl_display_add_global(m_display, &wl_seat_interface, this, bindSeat);
208 wl_display_add_global(m_display, &wl_output_interface, this, bindOutput);
209 wl_display_add_global(m_display, &wl_shell_interface, this, bindShell);
211 wl_display_init_shm(m_display);
213 m_loop = wl_display_get_event_loop(m_display);
214 m_fd = wl_event_loop_get_fd(m_loop);
217 Compositor::~Compositor()
219 wl_pointer_release(&m_pointer);
220 wl_keyboard_release(&m_keyboard);
221 wl_display_destroy(m_display);
224 void Compositor::dispatchEvents(int timeout)
226 wl_event_loop_dispatch(m_loop, timeout);
229 static void compositor_create_surface(wl_client *client, wl_resource *compositorResource, uint32_t id)
231 Compositor *compositor = static_cast<Compositor *>(compositorResource->data);
232 compositor->addSurface(new Surface(client, id, compositor));
235 static void compositor_create_region(wl_client *client, wl_resource *compositorResource, uint32_t id)
238 Q_UNUSED(compositorResource);
242 void Compositor::bindCompositor(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
244 static const struct wl_compositor_interface compositorInterface = {
245 compositor_create_surface,
246 compositor_create_region
250 wl_client_add_object(client, &wl_compositor_interface, &compositorInterface, id, compositorData);
253 static void unregisterResourceCallback(wl_listener *listener, void *data)
255 struct wl_resource *resource = reinterpret_cast<struct wl_resource *>(data);
256 wl_list_remove(&resource->link);
260 void registerResource(wl_list *list, wl_resource *resource)
262 wl_list_insert(list, &resource->link);
264 wl_listener *listener = new wl_listener;
265 listener->notify = unregisterResourceCallback;
267 wl_signal_add(&resource->destroy_signal, listener);
270 QVector<Surface *> Compositor::surfaces() const
275 uint32_t Compositor::nextSerial()
277 return wl_display_next_serial(m_display);
280 void Compositor::addSurface(Surface *surface)
282 m_surfaces << surface;
285 void Compositor::removeSurface(Surface *surface)
287 m_surfaces.remove(m_surfaces.indexOf(surface));