Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/modules/ddm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
find_package(TreelandProtocols REQUIRED)

ws_generate_local(server ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml treeland-ddm-v1-protocol)
local_qtwayland_server_protocol_treeland(libtreeland
PROTOCOL ${TREELAND_PROTOCOLS_DATA_DIR}/treeland-ddm-v1.xml
BASENAME treeland-ddm-v1
)

impl_treeland(
NAME
module_ddm
SOURCE
${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev1.h
${CMAKE_SOURCE_DIR}/src/modules/ddm/ddminterfacev1.cpp
${WAYLAND_PROTOCOLS_OUTPUTDIR}/treeland-ddm-v1-protocol.c
${CMAKE_BINARY_DIR}/src/modules/ddm/wayland-treeland-ddm-v1-server-protocol.c
INCLUDE
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
)
179 changes: 92 additions & 87 deletions src/modules/ddm/ddminterfacev1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,145 +2,150 @@
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "ddminterfacev1.h"
#include "treeland-ddm-v1-protocol.h"
#include "common/treelandlogging.h"

Check warning on line 5 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "common/treelandlogging.h" not found.
#include "helper.h"

Check warning on line 6 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "helper.h" not found.
#include "usermodel.h"

Check warning on line 7 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "usermodel.h" not found.
#include "qwayland-server-treeland-ddm-v1.h"

Check warning on line 8 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "qwayland-server-treeland-ddm-v1.h" not found.

#include <wayland-server-core.h>

Check warning on line 10 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wayland-server-core.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <wayland-server.h>

Check warning on line 11 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wayland-server.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <wayland-util.h>

#include <qwdisplay.h>

#include <QDebug>

Check warning on line 16 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QDebug> not found. Please note: Cppcheck does not need standard library headers to get proper results.

struct treeland_ddm {
wl_resource *resource;
class DDMInterfaceV1Private : public QtWaylandServer::treeland_ddm_v1
{
public:
explicit DDMInterfaceV1Private(DDMInterfaceV1 *_q);
wl_global *global() const;

DDMInterfaceV1 *q = nullptr;
protected:
void destroy(Resource *resource) override;
void bind_resource(Resource *resource) override;
void switch_to_greeter(Resource *resource) override;
void switch_to_user(Resource *resource, const QString &username) override;
void activate_session(Resource *resource) override;
void deactivate_session(Resource *resource) override;
void enable_render(Resource *resource) override;
void disable_render(Resource *resource, uint32_t callback) override;
};

// request implementation
DDMInterfaceV1Private::DDMInterfaceV1Private(DDMInterfaceV1 *_q)
: QtWaylandServer::treeland_ddm_v1()
, q(_q)
{
}

wl_global *DDMInterfaceV1Private::global() const
{
return m_global;
}

void DDMInterfaceV1Private::destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}

void DDMInterfaceV1Private::bind_resource(Resource *resource)

Check warning on line 52 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'bind_resource' is never used.
{
send_acquire_vt(resource->handle, 0);
}

static void switchToGreeter([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) {
void DDMInterfaceV1Private::switch_to_greeter([[maybe_unused]] Resource *resource)

Check warning on line 57 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'switch_to_greeter' is never used.
{
Helper::instance()->showLockScreen(false);
}

static void switchToUser([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource, const char *username) {
auto user = QString::fromLocal8Bit(username);
void DDMInterfaceV1Private::switch_to_user([[maybe_unused]] Resource *resource, const QString &username)

Check warning on line 62 in src/modules/ddm/ddminterfacev1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'switch_to_user' is never used.
{
auto helper = Helper::instance();
if (user == "ddm") {
if (username == "ddm") {
helper->showLockScreen(false);
} else if (user != helper->userModel()->currentUserName()) {
helper->userModel()->setCurrentUserName(QString(username));
} else if (username != helper->userModel()->currentUserName()) {
helper->userModel()->setCurrentUserName(username);
helper->showLockScreen(false);
}
}

static void activateSession([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) {
void DDMInterfaceV1Private::activate_session([[maybe_unused]] Resource *resource)
{
Helper::instance()->activateSession();
}

static void deactivateSession([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) {
void DDMInterfaceV1Private::deactivate_session([[maybe_unused]] Resource *resource)
{
Helper::instance()->deactivateSession();
}

static void enableRender([[maybe_unused]] struct wl_client *client, [[maybe_unused]] struct wl_resource *resource) {
void DDMInterfaceV1Private::enable_render([[maybe_unused]] Resource *resource)
{
Helper::instance()->enableRender();
}

static void disableRender(struct wl_client *client, [[maybe_unused]] struct wl_resource *resource, uint32_t id) {
void DDMInterfaceV1Private::disable_render(Resource *resource, uint32_t id)
{
Helper::instance()->disableRender();
auto callback = wl_resource_create(client, &wl_callback_interface, 1, id);
auto serial = wl_display_get_serial(wl_client_get_display(client));
auto callback = wl_resource_create(resource->client(), &wl_callback_interface, 1, id);
auto serial = wl_display_get_serial(wl_client_get_display(resource->client()));
wl_callback_send_done(callback, serial);
wl_resource_destroy(callback);
}

static void destroy([[maybe_unused]] struct wl_client *client,
struct wl_resource *resource)
DDMInterfaceV1::DDMInterfaceV1(QObject *parent)
: QObject(parent)
, WServerInterface()
, d(new DDMInterfaceV1Private(this))
{
wl_resource_destroy(resource);
}

static const struct treeland_ddm_v1_interface treeland_ddm_impl {
.switch_to_greeter = switchToGreeter,
.switch_to_user = switchToUser,
.activate_session = activateSession,
.deactivate_session = deactivateSession,
.enable_render = enableRender,
.disable_render = disableRender,
.destroy = destroy,
};

// wayland object binding

static void handleResourceDestroy(struct wl_resource *resource) {
qCWarning(treelandCore) << "DDM connection lost";
auto ddm = static_cast<struct treeland_ddm *>(wl_resource_get_user_data(resource));
ddm->resource = nullptr;
}

void handleBindingGlobal(struct wl_client *client, void *data, uint32_t version, uint32_t id) {
auto ddm = static_cast<struct treeland_ddm *>(data);
auto *resource = wl_resource_create(client, &treeland_ddm_v1_interface, version, id);
wl_resource_set_implementation(resource, &treeland_ddm_impl, ddm, handleResourceDestroy);
ddm->resource = resource;
qCDebug(treelandCore) << "DDM connection established";
DDMInterfaceV1::~DDMInterfaceV1() = default;

treeland_ddm_v1_send_acquire_vt(resource, 0);
}

// DDMInterfaceV1

DDMInterfaceV1::DDMInterfaceV1() {

}

DDMInterfaceV1::~DDMInterfaceV1() {
}

QByteArrayView DDMInterfaceV1::interfaceName() const {
static const QByteArray arr(treeland_ddm_v1_interface.name);
return QByteArrayView(arr);
QByteArrayView DDMInterfaceV1::interfaceName() const
{
return d->interfaceName();
}

bool DDMInterfaceV1::isConnected() const {
auto ddm = static_cast<struct treeland_ddm *>(m_handle);
return ddm && ddm->resource;
bool DDMInterfaceV1::isConnected() const
{
return !d->resourceMap().isEmpty();
}

void DDMInterfaceV1::create(WServer *server) {
auto ddm = new treeland_ddm { .resource = nullptr };
m_handle = ddm;
m_global = wl_global_create(server->handle()->handle(), &treeland_ddm_v1_interface,
treeland_ddm_v1_interface.version, ddm, handleBindingGlobal);
void DDMInterfaceV1::switchToVt(const int vtnr)
{
if (isConnected()) {
for (const auto &resource : d->resourceMap()) {
d->send_switch_to_vt(resource->handle, vtnr);
}
} else {
qCWarning(treelandCore) << "DDM is not connected when trying to call switchToVt";
}
}

void DDMInterfaceV1::destroy([[maybe_unused]] WServer *server) {
wl_global_destroy(m_global);
auto ddm = static_cast<struct treeland_ddm *>(m_handle);
delete ddm;
m_handle = nullptr;
void DDMInterfaceV1::acquireVt(const int vtnr)
{
if (isConnected()) {
for (const auto &resource : d->resourceMap()) {
d->send_acquire_vt(resource->handle, vtnr);
}
} else {
qCWarning(treelandCore) << "DDM is not connected when trying to call acquireVt";
}
}

wl_global *DDMInterfaceV1::global() const {
return m_global;
void DDMInterfaceV1::create(WServer *server)
{
d->init(server->handle()->handle(), InterfaceVersion);
}

// Event wrapper

void DDMInterfaceV1::switchToVt(const int vtnr) {
auto ddm = static_cast<struct treeland_ddm *>(m_handle);
if (isConnected())
treeland_ddm_v1_send_switch_to_vt(ddm->resource, vtnr);
else
qCWarning(treelandCore) << "DDM is not connected when trying to call switchToVt";
void DDMInterfaceV1::destroy([[maybe_unused]] WServer *server)
{
d->globalRemove();
}

void DDMInterfaceV1::acquireVt(const int vtnr) {
auto ddm = static_cast<struct treeland_ddm *>(m_handle);
if (isConnected())
treeland_ddm_v1_send_acquire_vt(ddm->resource, vtnr);
else
qCWarning(treelandCore) << "DDM is not connected when trying to call acquireVt";
wl_global *DDMInterfaceV1::global() const
{
return d->global();
}
28 changes: 18 additions & 10 deletions src/modules/ddm/ddminterfacev1.h
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
// Copyright (C) 2025 April Lu <apr3vau@outlook.com>.
// Copyright (C) 2025-2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "wserver.h"

/**
* The server-side wrapper for treeland private protocol.
*/
class DDMInterfaceV1 : public Waylib::Server::WServerInterface {
WAYLIB_SERVER_USE_NAMESPACE
QW_USE_NAMESPACE

class DDMInterfaceV1Private;
class DDMInterfaceV1 : public QObject , public WServerInterface
{
Q_OBJECT
public:
DDMInterfaceV1();
explicit DDMInterfaceV1(QObject *parent = nullptr);
~DDMInterfaceV1() override;
QByteArrayView interfaceName() const override;

bool isConnected() const;
void switchToVt(const int vtnr);
void acquireVt(const int vtnr);

QByteArrayView interfaceName() const override;
static constexpr int InterfaceVersion = 1;

protected:
void create(Waylib::Server::WServer *server) override;
void destroy(Waylib::Server::WServer *server) override;
void create(WServer *server) override;
void destroy(WServer *server) override;
wl_global *global() const override;

private:
struct wl_global *m_global { nullptr };
std::unique_ptr<DDMInterfaceV1Private> d;
};
Loading