Add d-pointer to Server::ShellInterface

This commit is contained in:
Martin Gräßlin 2014-09-18 18:51:35 +02:00
parent c2f89128d5
commit b2f6704560
2 changed files with 67 additions and 37 deletions

View file

@ -30,14 +30,45 @@ namespace Server
static const quint32 s_version = 1; static const quint32 s_version = 1;
const struct wl_shell_interface ShellInterface::s_interface = { class ShellInterface::Private
ShellInterface::createSurfaceCallback {
public:
Private(ShellInterface *q, Display *d);
void create();
Display *display;
wl_global *shell = nullptr;
QList<ShellSurfaceInterface*> surfaces;
private:
static void bind(wl_client *client, void *data, uint32_t version, uint32_t id);
static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface);
void bind(wl_client *client, uint32_t version, uint32_t id);
void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface);
ShellInterface *q;
static const struct wl_shell_interface s_interface;
};
ShellInterface::Private::Private(ShellInterface *q, Display *d)
: display(d)
, q(q)
{
}
void ShellInterface::Private::create()
{
Q_ASSERT(!shell);
shell = wl_global_create(*display, &wl_shell_interface, s_version, this, &bind);
}
const struct wl_shell_interface ShellInterface::Private::s_interface = {
createSurfaceCallback
}; };
ShellInterface::ShellInterface(Display *display, QObject *parent) ShellInterface::ShellInterface(Display *display, QObject *parent)
: QObject(parent) : QObject(parent)
, m_display(display) , d(new Private(this, display))
, m_shell(nullptr)
{ {
} }
@ -48,61 +79,70 @@ ShellInterface::~ShellInterface()
void ShellInterface::create() void ShellInterface::create()
{ {
Q_ASSERT(!m_shell); d->create();
m_shell = wl_global_create(*m_display, &wl_shell_interface, s_version, this, &ShellInterface::bind);
} }
void ShellInterface::destroy() void ShellInterface::destroy()
{ {
if (!m_shell) { if (!d->shell) {
return; return;
} }
wl_global_destroy(m_shell); wl_global_destroy(d->shell);
m_shell = nullptr; d->shell = nullptr;
} }
void ShellInterface::bind(wl_client *client, void *data, uint32_t version, uint32_t id) void ShellInterface::Private::bind(wl_client *client, void *data, uint32_t version, uint32_t id)
{ {
reinterpret_cast<ShellInterface*>(data)->bind(client, version, id); reinterpret_cast<ShellInterface::Private*>(data)->bind(client, version, id);
} }
void ShellInterface::bind(wl_client *client, uint32_t version, uint32_t id) void ShellInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{ {
wl_resource *shell = wl_resource_create(client, &wl_shell_interface, qMin(version, s_version), id); wl_resource *shell = wl_resource_create(client, &wl_shell_interface, qMin(version, s_version), id);
if (!shell) { if (!shell) {
wl_client_post_no_memory(client); wl_client_post_no_memory(client);
return; return;
} }
wl_resource_set_implementation(shell, &ShellInterface::s_interface, this, nullptr); wl_resource_set_implementation(shell, &s_interface, this, nullptr);
} }
void ShellInterface::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface) void ShellInterface::Private::createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface)
{ {
ShellInterface *s = reinterpret_cast<ShellInterface*>(wl_resource_get_user_data(resource)); auto s = reinterpret_cast<ShellInterface::Private*>(wl_resource_get_user_data(resource));
s->createSurface(client, wl_resource_get_version(resource), id, s->createSurface(client, wl_resource_get_version(resource), id,
reinterpret_cast<SurfaceInterface*>(wl_resource_get_user_data(surface))); reinterpret_cast<SurfaceInterface*>(wl_resource_get_user_data(surface)));
} }
void ShellInterface::createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface) void ShellInterface::Private::createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface)
{ {
auto it = std::find_if(m_surfaces.constBegin(), m_surfaces.constEnd(), auto it = std::find_if(surfaces.constBegin(), surfaces.constEnd(),
[surface](ShellSurfaceInterface *s) { [surface](ShellSurfaceInterface *s) {
return surface == s->surface(); return surface == s->surface();
} }
); );
if (it != m_surfaces.constBegin()) { if (it != surfaces.constBegin()) {
wl_resource_post_error(surface->surface(), WL_DISPLAY_ERROR_INVALID_OBJECT, "ShellSurface already created"); wl_resource_post_error(surface->surface(), WL_DISPLAY_ERROR_INVALID_OBJECT, "ShellSurface already created");
return; return;
} }
ShellSurfaceInterface *shellSurface = new ShellSurfaceInterface(this, surface); ShellSurfaceInterface *shellSurface = new ShellSurfaceInterface(q, surface);
m_surfaces << shellSurface; surfaces << shellSurface;
connect(shellSurface, &ShellSurfaceInterface::destroyed, this, QObject::connect(shellSurface, &ShellSurfaceInterface::destroyed, q,
[this, shellSurface] { [this, shellSurface] {
m_surfaces.removeAll(shellSurface); surfaces.removeAll(shellSurface);
} }
); );
shellSurface->create(client, version, id); shellSurface->create(client, version, id);
emit surfaceCreated(shellSurface); emit q->surfaceCreated(shellSurface);
}
bool ShellInterface::isValid() const
{
return d->shell != nullptr;
}
Display *ShellInterface::display() const
{
return d->display;
} }
/********************************* /*********************************

View file

@ -48,13 +48,9 @@ public:
void create(); void create();
void destroy(); void destroy();
bool isValid() const { bool isValid() const;
return m_shell != nullptr;
}
Display *display() const { Display *display() const;
return m_display;
}
Q_SIGNALS: Q_SIGNALS:
void surfaceCreated(KWayland::Server::ShellSurfaceInterface*); void surfaceCreated(KWayland::Server::ShellSurfaceInterface*);
@ -62,14 +58,8 @@ Q_SIGNALS:
private: private:
friend class Display; friend class Display;
explicit ShellInterface(Display *display, QObject *parent); explicit ShellInterface(Display *display, QObject *parent);
static void bind(wl_client *client, void *data, uint32_t version, uint32_t id); class Private;
static void createSurfaceCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface); QScopedPointer<Private> d;
void bind(wl_client *client, uint32_t version, uint32_t id);
void createSurface(wl_client *client, uint32_t version, uint32_t id, SurfaceInterface *surface);
Display *m_display;
wl_global *m_shell;
static const struct wl_shell_interface s_interface;
QList<ShellSurfaceInterface*> m_surfaces;
}; };
class KWAYLANDSERVER_EXPORT ShellSurfaceInterface : public QObject class KWAYLANDSERVER_EXPORT ShellSurfaceInterface : public QObject