2024-08-30 14:53:25 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2025-01-27 07:33:18 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2025 Deskflow Developers
|
2025-01-24 00:11:17 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2024 Symless Ltd.
|
|
|
|
|
* SPDX-FileCopyrightText: (C) 2022 Red Hat, Inc.
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
2024-08-30 14:53:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "mt/Thread.h"
|
|
|
|
|
#include "platform/EiScreen.h"
|
|
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
#include <libportal/inputcapture.h>
|
|
|
|
|
#include <libportal/portal.h>
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
namespace deskflow {
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
class PortalInputCapture
|
|
|
|
|
{
|
2024-08-30 14:53:25 +00:00
|
|
|
public:
|
|
|
|
|
PortalInputCapture(EiScreen *screen, IEventQueue *events);
|
|
|
|
|
~PortalInputCapture();
|
|
|
|
|
void enable();
|
|
|
|
|
void disable();
|
|
|
|
|
void release();
|
|
|
|
|
void release(double x, double y);
|
2025-08-06 23:41:44 +00:00
|
|
|
bool isActive() const
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
return m_isActive;
|
2024-10-17 18:04:35 +00:00
|
|
|
}
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
private:
|
2025-05-23 20:52:46 +00:00
|
|
|
void glibThread(const void *);
|
2025-06-20 00:49:53 +00:00
|
|
|
gboolean timeoutHandler() const;
|
|
|
|
|
gboolean initSession();
|
2026-02-02 01:10:24 +00:00
|
|
|
void setupSession(XdpInputCaptureSession *session);
|
|
|
|
|
void handleStart(GObject *object, GAsyncResult *res);
|
2025-06-20 00:49:53 +00:00
|
|
|
void handleInitSession(GObject *object, GAsyncResult *res);
|
|
|
|
|
void handleSetPointerBarriers(const GObject *object, GAsyncResult *res);
|
|
|
|
|
void handleSessionClosed(XdpSession *session);
|
|
|
|
|
void handleDisabled(const XdpInputCaptureSession *session, const GVariant *option);
|
2025-06-20 15:20:37 +00:00
|
|
|
void handleActivated(const XdpInputCaptureSession *session, const std::uint32_t activationId, GVariant *options);
|
|
|
|
|
void
|
|
|
|
|
handleDeactivated(const XdpInputCaptureSession *session, const std::uint32_t activationId, const GVariant *options);
|
2025-06-20 02:29:34 +00:00
|
|
|
void handleZonesChanged(XdpInputCaptureSession *session, const GVariant *options);
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
/// g_signal_connect callback wrapper
|
2025-06-20 15:20:37 +00:00
|
|
|
static void sessionClosed(XdpSession *session, const gpointer data)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
static_cast<PortalInputCapture *>(data)->handleSessionClosed(session);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
2025-06-20 15:20:37 +00:00
|
|
|
static void disabled(const XdpInputCaptureSession *session, const GVariant *options, const gpointer data)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
static_cast<PortalInputCapture *>(data)->handleDisabled(session, options);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
2025-06-20 15:20:37 +00:00
|
|
|
static void activated(
|
|
|
|
|
const XdpInputCaptureSession *session, const std::uint32_t activationId, GVariant *options, const gpointer data
|
|
|
|
|
)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
static_cast<PortalInputCapture *>(data)->handleActivated(session, activationId, options);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
2025-06-20 15:20:37 +00:00
|
|
|
static void deactivated(
|
|
|
|
|
const XdpInputCaptureSession *session, const std::uint32_t activationId, const GVariant *options,
|
|
|
|
|
const gpointer data
|
|
|
|
|
)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
static_cast<PortalInputCapture *>(data)->handleDeactivated(session, activationId, options);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
2025-06-20 15:20:37 +00:00
|
|
|
static void zonesChanged(XdpInputCaptureSession *session, const GVariant *options, const gpointer data)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-06-20 00:49:53 +00:00
|
|
|
static_cast<PortalInputCapture *>(data)->handleZonesChanged(session, options);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2025-06-20 15:16:55 +00:00
|
|
|
enum class Signal : uint8_t
|
|
|
|
|
{
|
|
|
|
|
SessionClosed,
|
|
|
|
|
Disabled,
|
|
|
|
|
Activated,
|
|
|
|
|
Deactivated,
|
|
|
|
|
ZonesChanged
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-20 00:49:53 +00:00
|
|
|
EiScreen *m_screen = nullptr;
|
|
|
|
|
IEventQueue *m_events = nullptr;
|
2026-02-02 01:10:24 +00:00
|
|
|
int m_portalVersion = 0;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:49:53 +00:00
|
|
|
Thread *m_glibThread;
|
|
|
|
|
GMainLoop *m_glibMainLoop = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:49:53 +00:00
|
|
|
XdpPortal *m_portal = nullptr;
|
|
|
|
|
XdpInputCaptureSession *m_session = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 15:20:37 +00:00
|
|
|
std::map<Signal, gulong> m_signals = {
|
2025-06-20 15:16:55 +00:00
|
|
|
{Signal::SessionClosed, 0},
|
|
|
|
|
{Signal::Disabled, 0},
|
|
|
|
|
{Signal::Activated, 0},
|
|
|
|
|
{Signal::Deactivated, 0},
|
|
|
|
|
{Signal::ZonesChanged, 0}
|
|
|
|
|
};
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:49:53 +00:00
|
|
|
bool m_enabled = false;
|
|
|
|
|
bool m_isActive = false;
|
|
|
|
|
std::uint32_t m_activationId = 0;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:49:53 +00:00
|
|
|
std::vector<XdpInputCapturePointerBarrier *> m_barriers;
|
2024-08-30 14:53:25 +00:00
|
|
|
};
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
} // namespace deskflow
|