/* * Deskflow -- mouse and keyboard sharing utility * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers * SPDX-FileCopyrightText: (C) 2024 Symless Ltd. * SPDX-FileCopyrightText: (C) 2022 Red Hat, Inc. * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ #pragma once #include "mt/Thread.h" #include "platform/EiScreen.h" #include #include #include #include namespace deskflow { class PortalInputCapture { public: PortalInputCapture(EiScreen *screen, IEventQueue *events); ~PortalInputCapture(); void enable(); void disable(); void release(); void release(double x, double y); bool is_active() const { return m_isActive; } private: void glibThread(void *); gboolean timeoutHandler() const; gboolean initSession(); 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); void handleActivated(const XdpInputCaptureSession *session, std::uint32_t activationId, GVariant *options); void handleDeactivated(const XdpInputCaptureSession *session, std::uint32_t activationId, const GVariant *options); void handleZonesChanged(XdpInputCaptureSession *session, const GVariant *options); /// g_signal_connect callback wrapper static void sessionClosed(XdpSession *session, gpointer data) { static_cast(data)->handleSessionClosed(session); } static void disabled(XdpInputCaptureSession *session, GVariant *options, gpointer data) { static_cast(data)->handleDisabled(session, options); } static void activated(const XdpInputCaptureSession *session, std::uint32_t activationId, GVariant *options, gpointer data) { static_cast(data)->handleActivated(session, activationId, options); } static void deactivated(const XdpInputCaptureSession *session, std::uint32_t activationId, const GVariant *options, gpointer data) { static_cast(data)->handleDeactivated(session, activationId, options); } static void zonesChanged(XdpInputCaptureSession *session, GVariant *options, gpointer data) { static_cast(data)->handleZonesChanged(session, options); } int fakeEisFd() const; private: EiScreen *m_screen = nullptr; IEventQueue *m_events = nullptr; Thread *m_glibThread; GMainLoop *m_glibMainLoop = nullptr; XdpPortal *m_portal = nullptr; XdpInputCaptureSession *m_session = nullptr; std::vector m_signals; bool m_enabled = false; bool m_isActive = false; std::uint32_t m_activationId = 0; std::vector m_barriers; }; } // namespace deskflow