Added auto-test for wayland plugin.

Similar to the compositor auto-test, except this time we mock the
compositor, and test the client code, by forcing the wayland plugin to
be used.

Change-Id: I363019ff7e136db6822993f1881fec48a02a7db4
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Samuel Rødal 2012-03-06 10:29:45 +01:00 committed by Jørgen Lind
parent b3da8baef1
commit 8feb960ff8
10 changed files with 1354 additions and 0 deletions

View File

@ -0,0 +1,34 @@
CONFIG += testcase
TARGET = tst_client
QT += testlib
QT += core-private gui-private
use_pkgconfig {
CONFIG += link_pkgconfig
PKGCONFIG += wayland-server
#set the rpath
!isEmpty(QMAKE_LFLAGS_RPATH) {
WAYLAND_NEEDS_RPATH = $$system(pkg-config --libs-only-L wayland-server)
!isEmpty(WAYLAND_NEEDS_RPATH) {
WAYLAND_LIBDIR = $$system(pkg-config --variable=libdir wayland-server)
!isEmpty(WAYLAND_LIBDIR):QMAKE_LFLAGS += $${QMAKE_LFLAGS_RPATH}$${WAYLAND_LIBDIR}
}
}
} else {
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
!isEmpty(QMAKE_LIBDIR_WAYLAND) {
LIBS += -L$$QMAKE_LIBDIR_WAYLAND
}
LIBS += -lwayland-server -lffi
}
SOURCES += tst_client.cpp \
mockcompositor.cpp \
mockinput.cpp \
mockshell.cpp \
mockshm.cpp \
mocksurface.cpp \
mockoutput.cpp
HEADERS += mockcompositor.h mocksurface.h

View File

@ -0,0 +1,269 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include "mocksurface.h"
MockCompositor::MockCompositor()
: m_alive(true)
, m_ready(false)
, m_compositor(0)
{
pthread_create(&m_thread, 0, run, this);
m_mutex.lock();
m_waitCondition.wait(&m_mutex);
m_mutex.unlock();
}
MockCompositor::~MockCompositor()
{
m_alive = false;
m_waitCondition.wakeOne();
pthread_join(m_thread, 0);
}
void MockCompositor::lock()
{
m_mutex.lock();
}
void MockCompositor::unlock()
{
m_mutex.unlock();
}
void MockCompositor::applicationInitialized()
{
m_ready = true;
}
int MockCompositor::waylandFileDescriptor() const
{
return m_compositor->fileDescriptor();
}
void MockCompositor::processWaylandEvents()
{
m_waitCondition.wakeOne();
}
void MockCompositor::setOutputGeometry(const QRect &rect)
{
Command command = makeCommand(Impl::Compositor::setOutputGeometry, m_compositor);
command.parameters << rect;
processCommand(command);
}
void MockCompositor::setKeyboardFocus(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::setKeyboardFocus, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
void MockCompositor::sendMousePress(const QSharedPointer<MockSurface> &surface, const QPoint &pos)
{
Command command = makeCommand(Impl::Compositor::sendMousePress, m_compositor);
command.parameters << QVariant::fromValue(surface) << pos;
processCommand(command);
}
void MockCompositor::sendMouseRelease(const QSharedPointer<MockSurface> &surface)
{
Command command = makeCommand(Impl::Compositor::sendMouseRelease, m_compositor);
command.parameters << QVariant::fromValue(surface);
processCommand(command);
}
QSharedPointer<MockSurface> MockCompositor::surface()
{
QSharedPointer<MockSurface> result;
lock();
QVector<Impl::Surface *> surfaces = m_compositor->surfaces();
if (!surfaces.isEmpty())
result = surfaces.first()->mockSurface();
unlock();
return result;
}
MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target)
{
Command command;
command.callback = callback;
command.target = target;
return command;
}
void MockCompositor::processCommand(const Command &command)
{
lock();
m_commandQueue << command;
unlock();
m_waitCondition.wakeOne();
}
void MockCompositor::dispatchCommands()
{
foreach (const Command &command, m_commandQueue)
command.callback(command.target, command.parameters);
m_commandQueue.clear();
}
void *MockCompositor::run(void *data)
{
MockCompositor *controller = static_cast<MockCompositor *>(data);
Impl::Compositor compositor;
controller->m_compositor = &compositor;
controller->m_waitCondition.wakeOne();
while (!controller->m_ready) {
controller->dispatchCommands();
compositor.dispatchEvents(20);
}
while (controller->m_alive) {
QMutexLocker locker(&controller->m_mutex);
controller->m_waitCondition.wait(&controller->m_mutex);
controller->dispatchCommands();
compositor.dispatchEvents(20);
}
return 0;
}
namespace Impl {
Compositor::Compositor()
: m_display(wl_display_create())
, m_time(0)
{
wl_list_init(&m_outputResources);
wl_display_add_socket(m_display, 0);
wl_input_device_init(&m_input);
wl_display_add_global(m_display, &wl_compositor_interface, this, bindCompositor);
wl_display_add_global(m_display, &wl_input_device_interface, this, bindInput);
wl_display_add_global(m_display, &wl_output_interface, this, bindOutput);
wl_display_add_global(m_display, &wl_shell_interface, this, bindShell);
initShm();
m_loop = wl_display_get_event_loop(m_display);
m_fd = wl_event_loop_get_fd(m_loop);
}
Compositor::~Compositor()
{
wl_shm_finish(m_shm);
wl_display_destroy(m_display);
}
void Compositor::dispatchEvents(int timeout)
{
wl_event_loop_dispatch(m_loop, timeout);
}
static void compositor_create_surface(wl_client *client, wl_resource *compositorResource, uint32_t id)
{
Compositor *compositor = static_cast<Compositor *>(compositorResource->data);
compositor->addSurface(new Surface(client, id, compositor));
}
static void compositor_create_region(wl_client *client, wl_resource *compositorResource, uint32_t id)
{
Q_UNUSED(client);
Q_UNUSED(compositorResource);
Q_UNUSED(id);
}
void Compositor::bindCompositor(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
static const struct wl_compositor_interface compositorInterface = {
compositor_create_surface,
compositor_create_region
};
Q_UNUSED(version);
wl_client_add_object(client, &wl_compositor_interface, &compositorInterface, id, compositorData);
}
static void unregisterResourceCallback(wl_listener *listener,
wl_resource *resource,
uint32_t time)
{
Q_UNUSED(time);
wl_list_remove(&resource->link);
delete listener;
}
void registerResource(wl_list *list, wl_resource *resource)
{
wl_list_insert(list, &resource->link);
wl_listener *listener = new wl_listener;
listener->func = unregisterResourceCallback;
wl_list_insert(&resource->destroy_listener_list, &listener->link);
}
QVector<Surface *> Compositor::surfaces() const
{
return m_surfaces;
}
void Compositor::addSurface(Surface *surface)
{
m_surfaces << surface;
}
void Compositor::removeSurface(Surface *surface)
{
m_surfaces.remove(m_surfaces.indexOf(surface));
}
}

View File

@ -0,0 +1,179 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MOCKCOMPOSITOR_H
#define MOCKCOMPOSITOR_H
#include <pthread.h>
#include <qglobal.h>
#include <wayland-server.h>
#include <QRect>
#include <QMutex>
#include <QSharedPointer>
#include <QVariant>
#include <QVector>
#include <QWaitCondition>
namespace Impl {
typedef void (**Implementation)(void);
class Surface;
class Compositor
{
public:
Compositor();
~Compositor();
int fileDescriptor() const { return m_fd; }
void dispatchEvents(int timeout = 0);
uint32_t time() { return ++m_time; }
static void setOutputGeometry(void *compositor, const QList<QVariant> &parameters);
QVector<Surface *> surfaces() const;
void addSurface(Surface *surface);
void removeSurface(Surface *surface);
static void setKeyboardFocus(void *data, const QList<QVariant> &parameters);
static void sendMousePress(void *data, const QList<QVariant> &parameters);
static void sendMouseRelease(void *data, const QList<QVariant> &parameters);
private:
static void bindCompositor(wl_client *client, void *data, uint32_t version, uint32_t id);
static void bindInput(wl_client *client, void *data, uint32_t version, uint32_t id);
static void bindOutput(wl_client *client, void *data, uint32_t version, uint32_t id);
static void bindShell(wl_client *client, void *data, uint32_t version, uint32_t id);
static void destroyInputResource(wl_resource *resource);
void initShm();
void sendOutputGeometry(wl_resource *resource);
void sendOutputMode(wl_resource *resource);
QRect m_outputGeometry;
wl_display *m_display;
wl_event_loop *m_loop;
wl_shm *m_shm;
int m_fd;
wl_list m_outputResources;
uint32_t m_time;
wl_input_device m_input;
QVector<Surface *> m_surfaces;
};
void registerResource(wl_list *list, wl_resource *resource);
}
class MockSurface
{
public:
Impl::Surface *handle() const { return m_surface; }
private:
MockSurface(Impl::Surface *surface);
friend class Impl::Compositor;
friend class Impl::Surface;
Impl::Surface *m_surface;
};
Q_DECLARE_METATYPE(QSharedPointer<MockSurface>)
class MockCompositor
{
public:
MockCompositor();
~MockCompositor();
void applicationInitialized();
int waylandFileDescriptor() const;
void processWaylandEvents();
void setOutputGeometry(const QRect &rect);
void setKeyboardFocus(const QSharedPointer<MockSurface> &surface);
void sendMousePress(const QSharedPointer<MockSurface> &surface, const QPoint &pos);
void sendMouseRelease(const QSharedPointer<MockSurface> &surface);
QSharedPointer<MockSurface> surface();
void lock();
void unlock();
private:
struct Command
{
typedef void (*Callback)(void *target, const QList<QVariant> &parameters);
Callback callback;
void *target;
QList<QVariant> parameters;
};
static Command makeCommand(Command::Callback callback, void *target);
void processCommand(const Command &command);
void dispatchCommands();
static void *run(void *data);
bool m_alive;
bool m_ready;
pthread_t m_thread;
QMutex m_mutex;
QWaitCondition m_waitCondition;
Impl::Compositor *m_compositor;
QList<Command> m_commandQueue;
};
#endif

View File

@ -0,0 +1,125 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include "mocksurface.h"
namespace Impl {
void Compositor::destroyInputResource(wl_resource *resource)
{
Compositor *compositor = static_cast<Compositor *>(resource->data);
wl_input_device *input = &compositor->m_input;
if (input->keyboard_focus_resource == resource)
input->keyboard_focus_resource = 0;
if (input->pointer_focus_resource == resource)
input->pointer_focus_resource = 0;
wl_list_remove(&resource->link);
free(resource);
}
void input_device_attach(wl_client *client,
wl_resource *device_resource,
uint32_t time,
wl_resource *buffer_resource, int32_t x, int32_t y)
{
Q_UNUSED(client);
Q_UNUSED(device_resource);
Q_UNUSED(time);
Q_UNUSED(buffer_resource);
Q_UNUSED(QPoint(x, y));
}
void Compositor::bindInput(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
static const struct wl_input_device_interface inputDeviceInterface = {
input_device_attach,
};
Q_UNUSED(version);
wl_resource *resource = wl_client_add_object(client, &wl_input_device_interface, &inputDeviceInterface, id, compositorData);
resource->destroy = destroyInputResource;
Compositor *compositor = static_cast<Compositor *>(compositorData);
wl_list_insert(&compositor->m_input.resource_list, &resource->link);
}
static wl_surface *resolveSurface(const QVariant &v)
{
QSharedPointer<MockSurface> mockSurface = v.value<QSharedPointer<MockSurface> >();
Surface *surface = mockSurface ? mockSurface->handle() : 0;
return surface ? surface->handle() : 0;
}
void Compositor::setKeyboardFocus(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
wl_input_device_set_keyboard_focus(&compositor->m_input, resolveSurface(parameters.first()), compositor->time());
}
void Compositor::sendMousePress(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
wl_surface *surface = resolveSurface(parameters.first());
if (!surface)
return;
QPoint pos = parameters.last().toPoint();
wl_input_device_set_pointer_focus(&compositor->m_input, surface, compositor->time(), pos.x(), pos.y());
wl_input_device_send_motion(compositor->m_input.pointer_focus_resource, compositor->time(), pos.x(), pos.y());
wl_input_device_send_button(compositor->m_input.pointer_focus_resource, compositor->time(), 0x110, 1);
}
void Compositor::sendMouseRelease(void *data, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(data);
wl_surface *surface = resolveSurface(parameters.first());
if (!surface)
return;
wl_input_device_send_button(compositor->m_input.pointer_focus_resource, compositor->time(), 0x110, 0);
}
}

View File

@ -0,0 +1,81 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
namespace Impl {
void Compositor::bindOutput(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
Q_UNUSED(version);
wl_resource *resource = wl_client_add_object(client, &wl_output_interface, 0, id, compositorData);
Compositor *compositor = static_cast<Compositor *>(compositorData);
registerResource(&compositor->m_outputResources, resource);
compositor->sendOutputGeometry(resource);
compositor->sendOutputMode(resource);
}
void Compositor::sendOutputGeometry(wl_resource *resource)
{
const QRect &r = m_outputGeometry;
wl_output_send_geometry(resource, r.x(), r.y(), r.width(), r.height(), 0, "", "");
}
void Compositor::sendOutputMode(wl_resource *resource)
{
wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, 640, 480, 60);
}
void Compositor::setOutputGeometry(void *c, const QList<QVariant> &parameters)
{
Compositor *compositor = static_cast<Compositor *>(c);
compositor->m_outputGeometry = parameters.first().toRect();
wl_resource *resource;
wl_list_for_each(resource, &compositor->m_outputResources, link)
compositor->sendOutputGeometry(resource);
}
}

View File

@ -0,0 +1,159 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
namespace Impl {
void shell_surface_move(wl_client *client,
wl_resource *surface_resource,
wl_resource *input_device_resource,
uint32_t time)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
Q_UNUSED(input_device_resource);
Q_UNUSED(time);
}
void shell_surface_resize(wl_client *client,
wl_resource *surface_resource,
wl_resource *input_device_resource,
uint32_t time,
uint32_t edges)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
Q_UNUSED(input_device_resource);
Q_UNUSED(time);
Q_UNUSED(edges);
}
void shell_surface_set_toplevel(wl_client *client,
wl_resource *surface_resource)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
}
void shell_surface_set_transient(wl_client *client,
wl_resource *surface_resource,
wl_resource *parent_surface_resource,
int x,
int y,
uint32_t flags)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
Q_UNUSED(parent_surface_resource);
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(flags);
}
void shell_surface_set_fullscreen(wl_client *client,
wl_resource *surface_resource,
uint32_t method,
uint32_t framerate,
wl_resource *output)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
Q_UNUSED(method);
Q_UNUSED(framerate);
Q_UNUSED(output);
}
void shell_surface_set_popup(wl_client *client, wl_resource *resource,
wl_resource *input_device, uint32_t time,
wl_resource *parent,
int32_t x, int32_t y,
uint32_t flags)
{
Q_UNUSED(client);
Q_UNUSED(resource);
Q_UNUSED(input_device);
Q_UNUSED(time);
Q_UNUSED(parent);
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(flags);
}
void shell_surface_set_maximized(wl_client *client,
wl_resource *surface_resource,
wl_resource *output)
{
Q_UNUSED(client);
Q_UNUSED(surface_resource);
Q_UNUSED(output);
}
static void get_shell_surface(wl_client *client, wl_resource *compositorResource, uint32_t id, wl_resource *surfaceResource)
{
const struct wl_shell_surface_interface shellSurfaceInterface = {
shell_surface_move,
shell_surface_resize,
shell_surface_set_toplevel,
shell_surface_set_transient,
shell_surface_set_fullscreen,
shell_surface_set_popup,
shell_surface_set_maximized
};
Q_UNUSED(compositorResource);
wl_client_add_object(client, &wl_shell_surface_interface, &shellSurfaceInterface, id, surfaceResource->data);
}
void Compositor::bindShell(wl_client *client, void *compositorData, uint32_t version, uint32_t id)
{
static const struct wl_shell_interface shellInterface = {
get_shell_surface
};
Q_UNUSED(version);
wl_client_add_object(client, &wl_shell_interface, &shellInterface, id, compositorData);
}
}

View File

@ -0,0 +1,100 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include <QImage>
namespace Impl {
class ShmBuffer
{
public:
ShmBuffer(wl_buffer *buffer)
: m_buffer(buffer)
{
refresh();
}
void refresh()
{
m_image = QImage(static_cast<uint8_t *>(wl_shm_buffer_get_data(m_buffer)),
m_buffer->width, m_buffer->height,
wl_shm_buffer_get_stride(m_buffer),
QImage::Format_ARGB32_Premultiplied);
}
private:
wl_buffer *m_buffer;
QImage m_image;
};
static void shm_buffer_created(wl_buffer *buffer)
{
buffer->user_data = new ShmBuffer(buffer);
}
static void shm_buffer_damaged(wl_buffer *buffer,
int32_t x, int32_t y,
int32_t width, int32_t height)
{
Q_UNUSED(QRect(x, y, width, height));
static_cast<ShmBuffer *>(buffer->user_data)->refresh();
}
static void shm_buffer_destroyed(wl_buffer *buffer)
{
delete static_cast<ShmBuffer *>(buffer->user_data);
}
void Compositor::initShm()
{
static struct wl_shm_callbacks shmCallbacks = {
shm_buffer_created,
shm_buffer_damaged,
shm_buffer_destroyed
};
m_shm = wl_shm_init(m_display, &shmCallbacks);
}
}

View File

@ -0,0 +1,145 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mocksurface.h"
#include "mockcompositor.h"
namespace Impl {
void destroy_surface(wl_resource *resource)
{
Surface *surface = static_cast<Surface *>(resource->data);
surface->compositor()->removeSurface(surface);
delete surface;
}
static void surface_destroy(wl_client *, wl_resource *surfaceResource)
{
Surface *surface = static_cast<Surface *>(surfaceResource->data);
wl_resource_destroy(surfaceResource, surface->compositor()->time());
}
void surface_attach(wl_client *client, wl_resource *surface,
wl_resource *buffer, int x, int y)
{
Q_UNUSED(client);
Q_UNUSED(surface);
Q_UNUSED(buffer);
Q_UNUSED(x);
Q_UNUSED(y);
//resolve<Surface>(surface)->attach(buffer ? reinterpret_cast<wl_buffer *>(buffer->data) : 0);
}
void surface_damage(wl_client *client, wl_resource *surface,
int32_t x, int32_t y, int32_t width, int32_t height)
{
Q_UNUSED(client);
Q_UNUSED(surface);
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(width);
Q_UNUSED(height);
//resolve<Surface>(surface)->damage(QRect(x, y, width, height));
}
void surface_frame(wl_client *client,
wl_resource *surface,
uint32_t callback)
{
Q_UNUSED(client);
Q_UNUSED(surface);
Q_UNUSED(callback);
// Surface *surface = resolve<Surface>(resource);
// wl_resource *frame_callback = wl_client_add_object(client, &wl_callback_interface, 0, callback, surface);
// wl_list_insert(&surface->m_frame_callback_list, &frame_callback->link);
}
void surface_set_opaque_region(wl_client *client, wl_resource *surfaceResource,
wl_resource *region)
{
Q_UNUSED(client);
Q_UNUSED(surfaceResource);
Q_UNUSED(region);
}
void surface_set_input_region(wl_client *client, wl_resource *surfaceResource,
wl_resource *region)
{
Q_UNUSED(client);
Q_UNUSED(surfaceResource);
Q_UNUSED(region);
}
Surface::Surface(wl_client *client, uint32_t id, Compositor *compositor)
: m_surface(wl_surface())
, m_compositor(compositor)
, m_mockSurface(new MockSurface(this))
{
static const struct wl_surface_interface surfaceInterface = {
surface_destroy,
surface_attach,
surface_damage,
surface_frame,
surface_set_opaque_region,
surface_set_input_region
};
m_surface.resource.object.id = id;
m_surface.resource.object.interface = &wl_surface_interface;
m_surface.resource.object.implementation = (Implementation)&surfaceInterface;
m_surface.resource.data = this;
m_surface.resource.destroy = destroy_surface;
wl_client_add_resource(client, &m_surface.resource);
}
Surface::~Surface()
{
m_mockSurface->m_surface = 0;
}
}
MockSurface::MockSurface(Impl::Surface *surface)
: m_surface(surface)
{
}

View File

@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qglobal.h>
#include <wayland-server.h>
#include "mockcompositor.h"
namespace Impl {
class Surface
{
public:
Surface(wl_client *client, uint32_t id, Compositor *compositor);
~Surface();
Compositor *compositor() const { return m_compositor; }
wl_surface *handle() { return &m_surface; }
QSharedPointer<MockSurface> mockSurface() const { return m_mockSurface; }
private:
wl_surface m_surface;
Compositor *m_compositor;
QSharedPointer<MockSurface> m_mockSurface;
};
}

View File

@ -0,0 +1,195 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "mockcompositor.h"
#include <QtTest/QtTest>
static const QSize screenSize(1600, 1200);
class TestWindow : public QWindow
{
public:
TestWindow()
: focusInEventCount(0)
, focusOutEventCount(0)
, keyPressEventCount(0)
, keyReleaseEventCount(0)
, mousePressEventCount(0)
, mouseReleaseEventCount(0)
{
setSurfaceType(QSurface::RasterSurface);
setGeometry(0, 0, 32, 32);
create();
}
void focusInEvent(QFocusEvent *)
{
++focusInEventCount;
}
void focusOutEvent(QFocusEvent *)
{
++focusOutEventCount;
}
void keyPressEvent(QKeyEvent *)
{
++keyPressEventCount;
}
void keyReleaseEvent(QKeyEvent *)
{
++keyReleaseEventCount;
}
void mousePressEvent(QMouseEvent *event)
{
++mousePressEventCount;
mousePressPos = event->pos();
}
void mouseReleaseEvent(QMouseEvent *)
{
++mouseReleaseEventCount;
}
int focusInEventCount;
int focusOutEventCount;
int keyPressEventCount;
int keyReleaseEventCount;
int mousePressEventCount;
int mouseReleaseEventCount;
QPoint mousePressPos;
};
class tst_WaylandClient : public QObject
{
Q_OBJECT
public:
tst_WaylandClient(MockCompositor *c)
: compositor(c)
{
QSocketNotifier *notifier = new QSocketNotifier(compositor->waylandFileDescriptor(), QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), this, SLOT(processWaylandEvents()));
}
public slots:
void processWaylandEvents()
{
compositor->processWaylandEvents();
}
private slots:
void screen();
void createDestroyWindow();
void events();
private:
MockCompositor *compositor;
};
void tst_WaylandClient::screen()
{
QTRY_COMPARE(QGuiApplication::primaryScreen()->size(), screenSize);
}
void tst_WaylandClient::createDestroyWindow()
{
TestWindow window;
window.show();
QTRY_VERIFY(compositor->surface());
window.destroy();
QTRY_VERIFY(!compositor->surface());
}
void tst_WaylandClient::events()
{
TestWindow window;
window.show();
QSharedPointer<MockSurface> surface;
QTRY_VERIFY(surface = compositor->surface());
QCOMPARE(window.focusInEventCount, 0);
compositor->setKeyboardFocus(surface);
QTRY_COMPARE(window.focusInEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QCOMPARE(window.focusOutEventCount, 0);
compositor->setKeyboardFocus(QSharedPointer<MockSurface>(0));
QTRY_COMPARE(window.focusOutEventCount, 1);
QTRY_COMPARE(QGuiApplication::focusWindow(), static_cast<QWindow *>(0));
compositor->setKeyboardFocus(surface);
QTRY_COMPARE(window.focusInEventCount, 2);
QTRY_COMPARE(QGuiApplication::focusWindow(), &window);
QPoint mousePressPos(16, 16);
QCOMPARE(window.mousePressEventCount, 0);
compositor->sendMousePress(surface, mousePressPos);
QTRY_COMPARE(window.mousePressEventCount, 1);
QTRY_COMPARE(window.mousePressPos, mousePressPos);
QCOMPARE(window.mouseReleaseEventCount, 0);
compositor->sendMouseRelease(surface);
QTRY_COMPARE(window.mouseReleaseEventCount, 1);
}
int main(int argc, char **argv)
{
setenv("XDG_RUNTIME_DIR", ".", 1);
setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin
MockCompositor compositor;
compositor.setOutputGeometry(QRect(QPoint(), screenSize));
QGuiApplication app(argc, argv);
compositor.applicationInitialized();
tst_WaylandClient tc(&compositor);
return QTest::qExec(&tc, argc, argv);
}
#include <tst_client.moc>