mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-12-27 03:49:48 +01:00
remotedesktop: implement remotedesktop portal
This commit is contained in:
parent
7c381c7cab
commit
ebb343a884
11 changed files with 736 additions and 18 deletions
|
@ -84,11 +84,12 @@ else()
|
|||
set(HYPRLAND_PROTOCOLS "${CMAKE_SOURCE_DIR}/subprojects/hyprland-protocols")
|
||||
endif()
|
||||
|
||||
pkg_search_module(UUID REQUIRED uuid)
|
||||
file(GLOB_RECURSE SRCFILES CONFIGURE_DEPENDS "src/*.cpp")
|
||||
add_executable(xdg-desktop-portal-hyprland ${SRCFILES})
|
||||
target_link_libraries(
|
||||
xdg-desktop-portal-hyprland PRIVATE rt PkgConfig::SDBUS Threads::Threads
|
||||
PkgConfig::deps)
|
||||
PkgConfig::deps ${UUID_LIBRARIES})
|
||||
|
||||
# protocols
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||
|
@ -127,6 +128,8 @@ protocolwayland()
|
|||
protocolnew("${CMAKE_SOURCE_DIR}/protocols"
|
||||
"wlr-foreign-toplevel-management-unstable-v1" true)
|
||||
protocolnew("${CMAKE_SOURCE_DIR}/protocols" "wlr-screencopy-unstable-v1" true)
|
||||
protocolnew("${CMAKE_SOURCE_DIR}/protocols" "wlr-virtual-pointer-unstable-v1" true)
|
||||
protocolnew("${CMAKE_SOURCE_DIR}/protocols" "virtual-keyboard-unstable-v1" true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-global-shortcuts-v1"
|
||||
true)
|
||||
protocolnew("${HYPRLAND_PROTOCOLS}/protocols" "hyprland-toplevel-export-v1"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[portal]
|
||||
DBusName=org.freedesktop.impl.portal.desktop.hyprland
|
||||
Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.GlobalShortcuts;org.freedesktop.impl.portal.InputCapture;
|
||||
Interfaces=org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.ScreenCast;org.freedesktop.impl.portal.GlobalShortcuts;org.freedesktop.impl.portal.InputCapture;org.freedesktop.impl.portal.RemoteDesktop;
|
||||
UseIn=wlroots;Hyprland;sway;Wayfire;river;
|
||||
|
|
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
113
protocols/virtual-keyboard-unstable-v1.xml
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="virtual_keyboard_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2008-2011 Kristian Høgsberg
|
||||
Copyright © 2010-2013 Intel Corporation
|
||||
Copyright © 2012-2013 Collabora, Ltd.
|
||||
Copyright © 2018 Purism SPC
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwp_virtual_keyboard_v1" version="1">
|
||||
<description summary="virtual keyboard">
|
||||
The virtual keyboard provides an application with requests which emulate
|
||||
the behaviour of a physical keyboard.
|
||||
|
||||
This interface can be used by clients on its own to provide raw input
|
||||
events, or it can accompany the input method protocol.
|
||||
</description>
|
||||
|
||||
<request name="keymap">
|
||||
<description summary="keyboard mapping">
|
||||
Provide a file descriptor to the compositor which can be
|
||||
memory-mapped to provide a keyboard mapping description.
|
||||
|
||||
Format carries a value from the keymap_format enumeration.
|
||||
</description>
|
||||
<arg name="format" type="uint" summary="keymap format"/>
|
||||
<arg name="fd" type="fd" summary="keymap file descriptor"/>
|
||||
<arg name="size" type="uint" summary="keymap size, in bytes"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="no_keymap" value="0" summary="No keymap was set"/>
|
||||
</enum>
|
||||
|
||||
<request name="key">
|
||||
<description summary="key event">
|
||||
A key was pressed or released.
|
||||
The time argument is a timestamp with millisecond granularity, with an
|
||||
undefined base. All requests regarding a single object must share the
|
||||
same clock.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
|
||||
State carries a value from the key_state enumeration.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="key" type="uint" summary="key that produced the event"/>
|
||||
<arg name="state" type="uint" summary="physical state of the key"/>
|
||||
</request>
|
||||
|
||||
<request name="modifiers">
|
||||
<description summary="modifier and group state">
|
||||
Notifies the compositor that the modifier and/or group state has
|
||||
changed, and it should update state.
|
||||
|
||||
The client should use wl_keyboard.modifiers event to synchronize its
|
||||
internal state with seat state.
|
||||
|
||||
Keymap must be set before issuing this request.
|
||||
</description>
|
||||
<arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
|
||||
<arg name="mods_latched" type="uint" summary="latched modifiers"/>
|
||||
<arg name="mods_locked" type="uint" summary="locked modifiers"/>
|
||||
<arg name="group" type="uint" summary="keyboard layout"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor" since="1">
|
||||
<description summary="destroy the virtual keyboard keyboard object"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_virtual_keyboard_manager_v1" version="1">
|
||||
<description summary="virtual keyboard manager">
|
||||
A virtual keyboard manager allows an application to provide keyboard
|
||||
input events as if they came from a physical keyboard.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
|
||||
</enum>
|
||||
|
||||
<request name="create_virtual_keyboard">
|
||||
<description summary="Create a new virtual keyboard">
|
||||
Creates a new virtual keyboard associated to a seat.
|
||||
|
||||
If the compositor enables a keyboard to perform arbitrary actions, it
|
||||
should present an error when an untrusted client requests a new
|
||||
keyboard.
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat"/>
|
||||
<arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
152
protocols/wlr-virtual-pointer-unstable-v1.xml
Normal file
152
protocols/wlr-virtual-pointer-unstable-v1.xml
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_virtual_pointer_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2019 Josef Gajdusek
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_virtual_pointer_v1" version="2">
|
||||
<description summary="virtual pointer">
|
||||
This protocol allows clients to emulate a physical pointer device. The
|
||||
requests are mostly mirror opposites of those specified in wl_pointer.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_axis" value="0"
|
||||
summary="client sent invalid axis enumeration value" />
|
||||
<entry name="invalid_axis_source" value="1"
|
||||
summary="client sent invalid axis source enumeration value" />
|
||||
</enum>
|
||||
|
||||
<request name="motion">
|
||||
<description summary="pointer relative motion event">
|
||||
The pointer has moved by a relative amount to the previous request.
|
||||
|
||||
Values are in the global compositor space.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="dx" type="fixed" summary="displacement on the x-axis"/>
|
||||
<arg name="dy" type="fixed" summary="displacement on the y-axis"/>
|
||||
</request>
|
||||
|
||||
<request name="motion_absolute">
|
||||
<description summary="pointer absolute motion event">
|
||||
The pointer has moved in an absolute coordinate frame.
|
||||
|
||||
Value of x can range from 0 to x_extent, value of y can range from 0
|
||||
to y_extent.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="x" type="uint" summary="position on the x-axis"/>
|
||||
<arg name="y" type="uint" summary="position on the y-axis"/>
|
||||
<arg name="x_extent" type="uint" summary="extent of the x-axis"/>
|
||||
<arg name="y_extent" type="uint" summary="extent of the y-axis"/>
|
||||
</request>
|
||||
|
||||
<request name="button">
|
||||
<description summary="button event">
|
||||
A button was pressed or released.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="button" type="uint" summary="button that produced the event"/>
|
||||
<arg name="state" type="uint" enum="wl_pointer.button_state" summary="physical state of the button"/>
|
||||
</request>
|
||||
|
||||
<request name="axis">
|
||||
<description summary="axis event">
|
||||
Scroll and other axis requests.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
|
||||
<arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
|
||||
</request>
|
||||
|
||||
<request name="frame">
|
||||
<description summary="end of a pointer event sequence">
|
||||
Indicates the set of events that logically belong together.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="axis_source">
|
||||
<description summary="axis source event">
|
||||
Source information for scroll and other axis.
|
||||
</description>
|
||||
<arg name="axis_source" type="uint" enum="wl_pointer.axis_source" summary="source of the axis event"/>
|
||||
</request>
|
||||
|
||||
<request name="axis_stop">
|
||||
<description summary="axis stop event">
|
||||
Stop notification for scroll and other axes.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="the axis stopped with this event"/>
|
||||
</request>
|
||||
|
||||
<request name="axis_discrete">
|
||||
<description summary="axis click event">
|
||||
Discrete step information for scroll and other axes.
|
||||
|
||||
This event allows the client to extend data normally sent using the axis
|
||||
event with discrete value.
|
||||
</description>
|
||||
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
|
||||
<arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
|
||||
<arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
|
||||
<arg name="discrete" type="int" summary="number of steps"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor" since="1">
|
||||
<description summary="destroy the virtual pointer object"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_virtual_pointer_manager_v1" version="2">
|
||||
<description summary="virtual pointer manager">
|
||||
This object allows clients to create individual virtual pointer objects.
|
||||
</description>
|
||||
|
||||
<request name="create_virtual_pointer">
|
||||
<description summary="Create a new virtual pointer">
|
||||
Creates a new virtual pointer. The optional seat is a suggestion to the
|
||||
compositor.
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
|
||||
<arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor" since="1">
|
||||
<description summary="destroy the virtual pointer manager"/>
|
||||
</request>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
<request name="create_virtual_pointer_with_output" since="2">
|
||||
<description summary="Create a new virtual pointer">
|
||||
Creates a new virtual pointer. The seat and the output arguments are
|
||||
optional. If the seat argument is set, the compositor should assign the
|
||||
input device to the requested seat. If the output argument is set, the
|
||||
compositor should map the input device to the requested output.
|
||||
</description>
|
||||
<arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
<arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
|
@ -31,7 +31,7 @@ SOutput::SOutput(SP<CCWlOutput> output_) : output(output_) {
|
|||
y = y_;
|
||||
});
|
||||
output->setScale([this](CCWlOutput* r, uint32_t factor_) { scale = factor_; });
|
||||
output->setDone([](CCWlOutput* r) { g_pPortalManager->m_sPortals.inputCapture->zonesChanged(); });
|
||||
output->setDone([](CCWlOutput* r) {});
|
||||
}
|
||||
|
||||
CPortalManager::CPortalManager() {
|
||||
|
@ -60,6 +60,7 @@ void CPortalManager::onGlobal(uint32_t name, const char* interface, uint32_t ver
|
|||
|
||||
Debug::log(LOG, " | Got interface: {} (ver {})", INTERFACE, version);
|
||||
|
||||
|
||||
if (INTERFACE == zwlr_screencopy_manager_v1_interface.name && m_sPipewire.loop) {
|
||||
m_sPortals.screencopy = std::make_unique<CScreencopyPortal>(makeShared<CCZwlrScreencopyManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &zwlr_screencopy_manager_v1_interface, version)));
|
||||
|
@ -69,9 +70,23 @@ void CPortalManager::onGlobal(uint32_t name, const char* interface, uint32_t ver
|
|||
m_sPortals.globalShortcuts = std::make_unique<CGlobalShortcutsPortal>(makeShared<CCHyprlandGlobalShortcutsManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &hyprland_global_shortcuts_manager_v1_interface, version)));
|
||||
}
|
||||
|
||||
if (m_sPortals.remoteDesktop == nullptr)
|
||||
m_sPortals.remoteDesktop = std::make_unique<CRemoteDesktopPortal>();
|
||||
|
||||
if (INTERFACE == hyprland_input_capture_manager_v1_interface.name)
|
||||
m_sPortals.inputCapture = std::make_unique<CInputCapturePortal>(makeShared<CCHyprlandInputCaptureManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &hyprland_input_capture_manager_v1_interface, version)));
|
||||
|
||||
if (INTERFACE == zwlr_virtual_pointer_manager_v1_interface.name)
|
||||
m_sPortals.remoteDesktop->registerPointer(makeShared<CCZwlrVirtualPointerManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &zwlr_virtual_pointer_manager_v1_interface, version)));
|
||||
|
||||
if (INTERFACE == zwp_virtual_keyboard_manager_v1_interface.name)
|
||||
m_sPortals.remoteDesktop->registerKeyboard(makeShared<CCZwpVirtualKeyboardManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &zwp_virtual_keyboard_manager_v1_interface, version)));
|
||||
|
||||
|
||||
else if (INTERFACE == hyprland_toplevel_export_manager_v1_interface.name) {
|
||||
m_sWaylandConnection.hyprlandToplevelMgr = makeShared<CCHyprlandToplevelExportManagerV1>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &hyprland_toplevel_export_manager_v1_interface, version));
|
||||
|
@ -85,6 +100,20 @@ void CPortalManager::onGlobal(uint32_t name, const char* interface, uint32_t ver
|
|||
POUTPUT->id = name;
|
||||
}
|
||||
|
||||
else if (INTERFACE == wl_seat_interface.name) {
|
||||
m_sWaylandConnection.seat = makeShared<CCWlSeat>((wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &wl_seat_interface, version));
|
||||
}
|
||||
|
||||
/*
|
||||
else if (INTERFACE == wl_keyboard_interface.name) {
|
||||
const auto PKEYBOARD = m_vKeyboards
|
||||
.emplace_back(std::make_unique<SKeyboard>(makeShared<CCWlKeyboard>(
|
||||
(wl_proxy*)wl_registry_bind((wl_registry*)m_sWaylandConnection.registry->resource(), name, &wl_keyboard_interface, version))))
|
||||
.get();
|
||||
PKEYBOARD->id = name;
|
||||
}
|
||||
*/
|
||||
|
||||
else if (INTERFACE == zwp_linux_dmabuf_v1_interface.name) {
|
||||
if (version < 4) {
|
||||
Debug::log(ERR, "cannot use linux_dmabuf with ver < 4");
|
||||
|
@ -419,8 +448,9 @@ void CPortalManager::startEventLoop() {
|
|||
m_sPortals.globalShortcuts.reset();
|
||||
m_sPortals.screencopy.reset();
|
||||
m_sPortals.screenshot.reset();
|
||||
m_sHelpers.toplevel.reset();
|
||||
m_sPortals.inputCapture.reset();
|
||||
m_sPortals.remoteDesktop.reset();
|
||||
m_sHelpers.toplevel.reset();
|
||||
|
||||
m_pConnection.reset();
|
||||
pw_loop_destroy(m_sPipewire.loop);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../portals/Screenshot.hpp"
|
||||
#include "../portals/GlobalShortcuts.hpp"
|
||||
#include "../portals/InputCapture.hpp"
|
||||
#include "../portals/RemoteDesktop.hpp"
|
||||
#include "../helpers/Timer.hpp"
|
||||
#include "../shared/ToplevelManager.hpp"
|
||||
#include <gbm.h>
|
||||
|
@ -20,6 +21,9 @@
|
|||
#include "linux-dmabuf-v1.hpp"
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.hpp"
|
||||
#include "wlr-screencopy-unstable-v1.hpp"
|
||||
#include "hyprland-input-capture-v1.hpp"
|
||||
#include "wlr-virtual-pointer-unstable-v1.hpp"
|
||||
#include "virtual-keyboard-unstable-v1.hpp"
|
||||
|
||||
#include "../includes.hpp"
|
||||
#include "../dbusDefines.hpp"
|
||||
|
@ -60,6 +64,12 @@ class CPortalManager {
|
|||
SOutput* getOutputFromName(const std::string& name);
|
||||
std::vector<std::unique_ptr<SOutput>> const& getAllOutputs();
|
||||
|
||||
struct {
|
||||
enum wl_keyboard_keymap_format format;
|
||||
int32_t fd;
|
||||
uint32_t size;
|
||||
} m_sKeymap;
|
||||
|
||||
struct {
|
||||
pw_loop* loop = nullptr;
|
||||
} m_sPipewire;
|
||||
|
@ -69,6 +79,7 @@ class CPortalManager {
|
|||
std::unique_ptr<CScreenshotPortal> screenshot;
|
||||
std::unique_ptr<CGlobalShortcutsPortal> globalShortcuts;
|
||||
std::unique_ptr<CInputCapturePortal> inputCapture;
|
||||
std::unique_ptr<CRemoteDesktopPortal> remoteDesktop;
|
||||
} m_sPortals;
|
||||
|
||||
struct {
|
||||
|
@ -77,6 +88,7 @@ class CPortalManager {
|
|||
|
||||
struct {
|
||||
wl_display* display = nullptr;
|
||||
SP<CCWlSeat> seat;
|
||||
SP<CCWlRegistry> registry;
|
||||
SP<CCHyprlandToplevelExportManagerV1> hyprlandToplevelMgr;
|
||||
SP<CCZwpLinuxDmabufV1> linuxDmabuf;
|
||||
|
|
|
@ -25,7 +25,11 @@ CInputCapturePortal::CInputCapturePortal(SP<CCHyprlandInputCaptureManagerV1> mgr
|
|||
});
|
||||
|
||||
mgr->setKeymap([this](CCHyprlandInputCaptureManagerV1* r, hyprlandInputCaptureManagerV1KeymapFormat format, int32_t fd, uint32_t size) {
|
||||
Debug::log(LOG, "[input-capture] got keymap");
|
||||
onKeymap(format == HYPRLAND_INPUT_CAPTURE_MANAGER_V1_KEYMAP_FORMAT_XKB_V1 ? fd : 0, size);
|
||||
g_pPortalManager->m_sKeymap.format = wl_keyboard_keymap_format(format);
|
||||
g_pPortalManager->m_sKeymap.fd = fd;
|
||||
g_pPortalManager->m_sKeymap.size = size;
|
||||
});
|
||||
|
||||
mgr->setModifiers([this](CCHyprlandInputCaptureManagerV1* r, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
|
||||
|
@ -128,7 +132,8 @@ dbUasv CInputCapturePortal::onCreateSession(sdbus::ObjectPath requestHandle, sdb
|
|||
session->request = createDBusRequest(requestHandle);
|
||||
session->request->onDestroy = [session]() { session->request.release(); };
|
||||
|
||||
session->eis = std::make_unique<EmulatedInputServer>("eis-" + sessionId, keymap);
|
||||
session->eis = std::make_unique<EmulatedInputServer>("eis-" + sessionId);
|
||||
session->eis->setKeymap(keymap);
|
||||
|
||||
sessions.emplace(sessionHandle, session);
|
||||
|
||||
|
|
207
src/portals/RemoteDesktop.cpp
Normal file
207
src/portals/RemoteDesktop.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
#include "RemoteDesktop.hpp"
|
||||
#include "../core/PortalManager.hpp"
|
||||
#include "../helpers/Log.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
void CRemoteDesktopPortal::registerPointer(SP<CCZwlrVirtualPointerManagerV1> mgr) {
|
||||
m_sState.pointerMgr = mgr;
|
||||
}
|
||||
|
||||
void CRemoteDesktopPortal::registerKeyboard(SP<CCZwpVirtualKeyboardManagerV1> mgr) {
|
||||
m_sState.keyboardMgr = mgr;
|
||||
}
|
||||
|
||||
CRemoteDesktopPortal::CRemoteDesktopPortal() {
|
||||
Debug::log(LOG, "[remotedesktop] initializing remote desktop portal");
|
||||
m_pObject = sdbus::createObject(*g_pPortalManager->getConnection(), OBJECT_PATH);
|
||||
m_pObject
|
||||
->addVTable(
|
||||
sdbus::registerMethod("CreateSession")
|
||||
.implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onCreateSession(o1, o2, s, m);
|
||||
}),
|
||||
sdbus::registerMethod("SelectDevices")
|
||||
.implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onSelectDevices(o1, o2, s, m);
|
||||
}),
|
||||
sdbus::registerMethod("Start")
|
||||
.implementedAs([this](sdbus::ObjectPath o1, sdbus::ObjectPath o2, std::string s1, std::string s2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onStart(o1, o2, s1, s2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyPointerMotion")
|
||||
.implementedAs([this](sdbus::ObjectPath o, double d1, double d2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyPointerMotion(o, d1, d2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyPointerMotionAbsolute")
|
||||
.implementedAs([this](sdbus::ObjectPath o, unsigned int u, double d1, double d2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyPointerMotionAbsolute(o, u, d1, d2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyPointerButton")
|
||||
.implementedAs([this](sdbus::ObjectPath o, int i, unsigned int u, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyPointerButton(o, i, u, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyPointerAxis")
|
||||
.implementedAs([this](sdbus::ObjectPath o, double d1, double d2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyPointerAxis(o, d1, d2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyPointerAxisDiscrete")
|
||||
.implementedAs([this](sdbus::ObjectPath o, unsigned int u, int i, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyPointerAxisDiscrete(o, u, i, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyKeyboardKeycode")
|
||||
.implementedAs([this](sdbus::ObjectPath o, int i, unsigned int u, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyKeyboardKeycode(o, i, u, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyKeyboardKeysym")
|
||||
.implementedAs([this](sdbus::ObjectPath o, int i, unsigned int u, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyKeyboardKeysym(o, i, u, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyTouchDown")
|
||||
.implementedAs([this](sdbus::ObjectPath o, unsigned int u1, unsigned int u2, double d1, double d2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyTouchDown(o, u1, u2, d1, d2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyTouchMotion")
|
||||
.implementedAs([this](sdbus::ObjectPath o, unsigned int u1, unsigned int u2, double d1, double d2, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyTouchMotion(o, u1, u2, d1, d2, m);
|
||||
}),
|
||||
sdbus::registerMethod("NotifyTouchUp")
|
||||
.implementedAs([this](sdbus::ObjectPath o, unsigned int u, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onNotifyTouchUp(o, u, m);
|
||||
}),
|
||||
sdbus::registerMethod("ConnectToEIS").implementedAs([this](sdbus::ObjectPath o, std::string s, std::unordered_map<std::string, sdbus::Variant> m) {
|
||||
return onConnectToEIS(o, s, m);
|
||||
}),
|
||||
sdbus::registerProperty("AvailableDeviceTypes").withGetter([] { return (uint32_t)(1 | 2); }),
|
||||
sdbus::registerProperty("version").withGetter([] { return (uint32_t)(1); }))
|
||||
.forInterface(INTERFACE_NAME);
|
||||
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
Debug::log(LOG, "[remotedesktop] New session:");
|
||||
Debug::log(LOG, "[remotedesktop] | {}", requestHandle.c_str());
|
||||
Debug::log(LOG, "[remotedesktop] | {}", sessionHandle.c_str());
|
||||
Debug::log(LOG, "[remotedesktop] | appid: {}", appID);
|
||||
|
||||
std::shared_ptr<SSession> PSESSION = std::make_shared<SSession>(appID, requestHandle, sessionHandle);
|
||||
|
||||
// create objects
|
||||
PSESSION->session = createDBusSession(sessionHandle);
|
||||
PSESSION->sessionHandle = sessionHandle;
|
||||
PSESSION->session->onDestroy = [PSESSION, this]() {
|
||||
PSESSION->eis->stopServer();
|
||||
PSESSION->eis.reset();
|
||||
Debug::log(LOG, "[remotedesktop] Session {} destroyed", PSESSION->sessionHandle.c_str());
|
||||
PSESSION->session.release();
|
||||
m_mSessions.erase(PSESSION->sessionHandle);
|
||||
};
|
||||
|
||||
PSESSION->request = createDBusRequest(requestHandle);
|
||||
PSESSION->requestHandle = requestHandle;
|
||||
PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); };
|
||||
|
||||
PSESSION->pointer = makeShared<CCZwlrVirtualPointerV1>(m_sState.pointerMgr->sendCreateVirtualPointer(g_pPortalManager->m_sWaylandConnection.seat->resource()));
|
||||
PSESSION->keyboard = makeShared<CCZwpVirtualKeyboardV1>(m_sState.keyboardMgr->sendCreateVirtualKeyboard(g_pPortalManager->m_sWaylandConnection.seat->resource()));
|
||||
|
||||
const auto& keymap = g_pPortalManager->m_sKeymap;
|
||||
PSESSION->keyboard->sendKeymap(keymap.format, keymap.fd, keymap.size);
|
||||
|
||||
PSESSION->eis = std::make_unique<EmulatedInputServer>("eisr-" + std::to_string(m_uSessionCounter++));
|
||||
PSESSION->eis->setVirtualPointer(PSESSION->pointer);
|
||||
PSESSION->eis->setVirtualKeyboard(PSESSION->keyboard);
|
||||
|
||||
m_mSessions.emplace(sessionHandle, PSESSION);
|
||||
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onSelectDevices(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onStart(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::string parentWindow,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
Debug::log(LOG, "[remotedesktop] start request");
|
||||
|
||||
std::unordered_map<std::string, sdbus::Variant> results;
|
||||
results["devices"] = sdbus::Variant{uint32_t{1 | 2}};
|
||||
results["clipboard_enabled"] = sdbus::Variant{bool(true)};
|
||||
|
||||
std::unordered_map<std::string, sdbus::Variant> restoreData;
|
||||
results["restore_data"] = sdbus::Variant{sdbus::Struct<std::string, uint32_t, sdbus::Variant>{"hyprland", 1, sdbus::Variant{restoreData}}};
|
||||
results["persist_mode"] = sdbus::Variant{uint32_t{2}};
|
||||
|
||||
return {0, results};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyPointerMotion(sdbus::ObjectPath sessionHandle, double dx, double dy, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->pointer->sendMotion(0, dx, dy);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyPointerMotionAbsolute(sdbus::ObjectPath sessionHandle, unsigned int stream, double x, double y, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->pointer->sendMotionAbsolute(0, x, y, 1920, 1080);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyPointerButton(sdbus::ObjectPath sessionHandle, int button, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->pointer->sendButton(0, button, state);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyPointerAxis(sdbus::ObjectPath sessionHandle, double dx, double dy, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->pointer->sendAxis(0, 0, dy);
|
||||
PSESSION->pointer->sendAxis(0, 1, dx);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyPointerAxisDiscrete(sdbus::ObjectPath sessionHandle, unsigned int axis, int steps, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->pointer->sendAxisDiscrete(1, 0, axis, steps);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyKeyboardKeycode(sdbus::ObjectPath sessionHandle, int keycode, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
PSESSION->keyboard->sendKey(1, keycode, state);
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyKeyboardKeysym(sdbus::ObjectPath sessionHandle, int keysym, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyTouchDown(sdbus::ObjectPath sessionHandle, unsigned int stream, unsigned int slot, double x, double y,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyTouchMotion(sdbus::ObjectPath sessionHandle, unsigned int stream, unsigned int slot, double x, double y,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
dbUasv CRemoteDesktopPortal::onNotifyTouchUp(sdbus::ObjectPath sessionHandle, unsigned int slot, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
return {0, {}};
|
||||
}
|
||||
|
||||
sdbus::UnixFd CRemoteDesktopPortal::onConnectToEIS(sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map<std::string, sdbus::Variant> opts) {
|
||||
Debug::log(LOG, "[remotedesktop] New ConnectToEIS request: {}:", sessionHandle.c_str());
|
||||
const auto PSESSION = m_mSessions[sessionHandle];
|
||||
if (!PSESSION) return (sdbus::UnixFd)0;
|
||||
|
||||
int sockfd = PSESSION->eis->getFileDescriptor();
|
||||
|
||||
Debug::log(LOG, "[remotedesktop] Connected to the socket. File descriptor: {}", sockfd);
|
||||
return (sdbus::UnixFd)sockfd;
|
||||
}
|
64
src/portals/RemoteDesktop.hpp
Normal file
64
src/portals/RemoteDesktop.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
#include "wlr-virtual-pointer-unstable-v1.hpp"
|
||||
#include "virtual-keyboard-unstable-v1.hpp"
|
||||
#include "../shared/Session.hpp"
|
||||
#include "../shared/Eis.hpp"
|
||||
#include "../dbusDefines.hpp"
|
||||
#include <libei-1.0/libeis.h>
|
||||
#include <queue>
|
||||
|
||||
class CRemoteDesktopPortal {
|
||||
public:
|
||||
CRemoteDesktopPortal();
|
||||
void registerPointer(SP<CCZwlrVirtualPointerManagerV1> mgr);
|
||||
void registerKeyboard(SP<CCZwpVirtualKeyboardManagerV1> mgr);
|
||||
|
||||
dbUasv onCreateSession(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onSelectDevices(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onStart(sdbus::ObjectPath requestHandle, sdbus::ObjectPath sessionHandle, std::string appID, std::string parentWindow,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyPointerMotion(sdbus::ObjectPath sessionHandle, double dx, double dy, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyPointerMotionAbsolute(sdbus::ObjectPath sessionHandle, unsigned int stream, double x, double y, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyPointerButton(sdbus::ObjectPath sessionHandle, int button, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyPointerAxis(sdbus::ObjectPath sessionHandle, double dx, double dy, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyPointerAxisDiscrete(sdbus::ObjectPath sessionHandle, unsigned int axis, int steps, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyKeyboardKeycode(sdbus::ObjectPath sessionHandle, int keycode, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyKeyboardKeysym(sdbus::ObjectPath sessionHandle, int keysym, unsigned int state, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyTouchDown(sdbus::ObjectPath sessionHandle, unsigned int stream, unsigned int slot, double x, double y,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyTouchMotion(sdbus::ObjectPath sessionHandle, unsigned int stream, unsigned int slot, double x, double y,
|
||||
std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
dbUasv onNotifyTouchUp(sdbus::ObjectPath sessionHandle, unsigned int slot, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
sdbus::UnixFd onConnectToEIS(sdbus::ObjectPath sessionHandle, std::string appID, std::unordered_map<std::string, sdbus::Variant> opts);
|
||||
|
||||
struct SSession {
|
||||
std::string appid;
|
||||
sdbus::ObjectPath requestHandle, sessionHandle;
|
||||
std::unique_ptr<SDBusRequest> request;
|
||||
std::unique_ptr<SDBusSession> session;
|
||||
|
||||
SP<CCZwlrVirtualPointerV1> pointer;
|
||||
SP<CCZwpVirtualKeyboardV1> keyboard;
|
||||
std::unique_ptr<EmulatedInputServer> eis;
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<SSession>> m_mSessions;
|
||||
|
||||
private:
|
||||
std::priority_queue<int, std::vector<int>, std::greater<int>> m_pqFreeIds;
|
||||
|
||||
struct {
|
||||
SP<CCZwlrVirtualPointerManagerV1> pointerMgr;
|
||||
SP<CCZwpVirtualKeyboardManagerV1> keyboardMgr;
|
||||
} m_sState;
|
||||
|
||||
std::unique_ptr<sdbus::IObject> m_pObject;
|
||||
uint m_uSessionCounter = 0;
|
||||
|
||||
const sdbus::InterfaceName INTERFACE_NAME = sdbus::InterfaceName{"org.freedesktop.impl.portal.RemoteDesktop"};
|
||||
const sdbus::ObjectPath OBJECT_PATH = sdbus::ObjectPath{"/org/freedesktop/portal/desktop"};
|
||||
};
|
|
@ -6,12 +6,11 @@
|
|||
#include <libeis.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
EmulatedInputServer::EmulatedInputServer(std::string socketName, Keymap _keymap) {
|
||||
EmulatedInputServer::EmulatedInputServer(std::string socketName) {
|
||||
Debug::log(LOG, "[EIS] Init socket: {}", socketName);
|
||||
|
||||
keymap = _keymap;
|
||||
|
||||
const char* xdg = getenv("XDG_RUNTIME_DIR");
|
||||
if (xdg)
|
||||
socketPath = std::string(xdg) + "/" + socketName;
|
||||
|
@ -61,12 +60,6 @@ int EmulatedInputServer::onEvent(eis_event* e) {
|
|||
eisClient = eis_event_get_client(e);
|
||||
Debug::log(LOG, "[EIS] {} client connected: {}", eis_client_is_sender(eisClient) ? "Sender" : "Receiver", eis_client_get_name(eisClient));
|
||||
|
||||
if (eis_client_is_sender(eisClient)) {
|
||||
Debug::log(WARN, "[EIS] Unexpected sender client {} connected to input capture session", eis_client_get_name(eisClient));
|
||||
eis_client_disconnect(eisClient);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (client.handle) {
|
||||
Debug::log(WARN, "[EIS] Unexpected additional client {} connected to input capture session", eis_client_get_name(eisClient));
|
||||
eis_client_disconnect(eisClient);
|
||||
|
@ -80,6 +73,7 @@ int EmulatedInputServer::onEvent(eis_event* e) {
|
|||
seat = eis_client_new_seat(eisClient, "default");
|
||||
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_BUTTON);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_SCROLL);
|
||||
eis_seat_configure_capability(seat, EIS_DEVICE_CAP_KEYBOARD);
|
||||
|
@ -120,6 +114,121 @@ int EmulatedInputServer::onEvent(eis_event* e) {
|
|||
} else
|
||||
Debug::log(WARN, "[EIS] Unknown device to close");
|
||||
break;
|
||||
case EIS_EVENT_FRAME:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendFrame();
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_START_EMULATING:
|
||||
device = eis_event_get_device(e);
|
||||
Debug::log(LOG, "[EIS] Device {} is ready to send events", eis_device_get_name(device));
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_STOP_EMULATING:
|
||||
device = eis_event_get_device(e);
|
||||
Debug::log(LOG, "[EIS] Device {} will no longer send events", eis_device_get_name(device));
|
||||
break;
|
||||
case EIS_EVENT_POINTER_MOTION:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendMotion(0, eis_event_pointer_get_dx(e), eis_event_pointer_get_dy(e));
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_POINTER_MOTION_ABSOLUTE:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendMotionAbsolute(0, eis_event_pointer_get_absolute_x(e), eis_event_pointer_get_absolute_y(e), screenWidth, screenHeight);
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_BUTTON_BUTTON:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendButton(0, eis_event_button_get_button(e), eis_event_button_get_is_press(e));
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_SCROLL_DELTA:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendAxis(0, 0, eis_event_scroll_get_dy(e));
|
||||
virtualPointer->sendAxis(0, 1, eis_event_scroll_get_dx(e));
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_SCROLL_STOP:
|
||||
if (virtualPointer != nullptr) {
|
||||
if (eis_event_scroll_get_stop_x(e))
|
||||
virtualPointer->sendAxisStop(0, 1);
|
||||
if (eis_event_scroll_get_stop_y(e))
|
||||
virtualPointer->sendAxisStop(0, 0);
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_SCROLL_DISCRETE:
|
||||
if (virtualPointer != nullptr) {
|
||||
virtualPointer->sendAxisDiscrete(1, 0, 1, eis_event_scroll_get_discrete_dy(e));
|
||||
virtualPointer->sendAxisDiscrete(1, 1, 1, eis_event_scroll_get_discrete_dx(e));
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_KEYBOARD_KEY:
|
||||
{
|
||||
if (virtualKeyboard != nullptr) {
|
||||
uint32_t keycode = eis_event_keyboard_get_key(e);
|
||||
bool pressed = eis_event_keyboard_get_key_is_press(e);
|
||||
switch (keycode) {
|
||||
case KEY_LEFTSHIFT:
|
||||
case KEY_RIGHTSHIFT:
|
||||
if (pressed)
|
||||
depressed |= 1;
|
||||
else
|
||||
depressed &= ~(1);
|
||||
break;
|
||||
case KEY_CAPSLOCK:
|
||||
if (pressed) {
|
||||
if (locked & (1 << 1))
|
||||
locked &= ~(1 << 1);
|
||||
else
|
||||
locked |= 1 << 1;
|
||||
}
|
||||
break;
|
||||
case KEY_LEFTCTRL:
|
||||
case KEY_RIGHTCTRL:
|
||||
if (pressed)
|
||||
depressed |= 1 << 2;
|
||||
else
|
||||
depressed &= ~(1 << 2);
|
||||
break;
|
||||
case KEY_LEFTALT:
|
||||
case KEY_RIGHTALT:
|
||||
if (pressed)
|
||||
depressed |= 1 << 3;
|
||||
else
|
||||
depressed &= ~(1 << 3);
|
||||
break;
|
||||
case KEY_NUMLOCK:
|
||||
if (pressed) {
|
||||
if (locked & (1 << 4))
|
||||
locked &= ~(1 << 4);
|
||||
else
|
||||
locked |= 1 << 4;
|
||||
}
|
||||
break;
|
||||
case KEY_LEFTMETA:
|
||||
case KEY_RIGHTMETA:
|
||||
if (pressed)
|
||||
depressed |= 1 << 6;
|
||||
else
|
||||
depressed &= ~(1 << 6);
|
||||
break;
|
||||
case KEY_SCROLLLOCK:
|
||||
if (pressed) {
|
||||
if (locked & (1 << 7))
|
||||
locked &= ~(1 << 7);
|
||||
else
|
||||
locked |= 1 << 7;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
virtualKeyboard->sendModifiers(depressed, latched, locked, 3);
|
||||
virtualKeyboard->sendKey(1, keycode, pressed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: return 0;
|
||||
}
|
||||
return 0;
|
||||
|
@ -132,6 +241,7 @@ void EmulatedInputServer::ensurePointer(eis_event* event) {
|
|||
eis_device* pointer = eis_seat_new_device(client.seat);
|
||||
eis_device_configure_name(pointer, "captured relative pointer");
|
||||
eis_device_configure_capability(pointer, EIS_DEVICE_CAP_POINTER);
|
||||
eis_device_configure_capability(pointer, EIS_DEVICE_CAP_POINTER_ABSOLUTE);
|
||||
eis_device_configure_capability(pointer, EIS_DEVICE_CAP_BUTTON);
|
||||
eis_device_configure_capability(pointer, EIS_DEVICE_CAP_SCROLL);
|
||||
|
||||
|
@ -140,9 +250,15 @@ void EmulatedInputServer::ensurePointer(eis_event* event) {
|
|||
|
||||
eis_region_set_offset(r, o->x, o->y);
|
||||
eis_region_set_size(r, o->width, o->height);
|
||||
Debug::log(LOG, "[EIS] REGION TME {} {}", o->width, o->height);
|
||||
eis_region_set_physical_scale(r, o->scale);
|
||||
eis_region_add(r);
|
||||
eis_region_unref(r);
|
||||
|
||||
//#FIXME: #TODO: this doesn't work if there are multiple outputs in getAllOutPuts()
|
||||
screenWidth = o->width;
|
||||
screenHeight = o->height;
|
||||
|
||||
}
|
||||
|
||||
eis_device_add(pointer);
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <libeis.h>
|
||||
#include <libei-1.0/libeis.h>
|
||||
#include <string>
|
||||
#include "wlr-virtual-pointer-unstable-v1.hpp"
|
||||
#include "virtual-keyboard-unstable-v1.hpp"
|
||||
#include <memory>
|
||||
#include "../includes.hpp"
|
||||
|
||||
struct Keymap {
|
||||
int32_t fd = 0;
|
||||
|
@ -13,7 +17,7 @@ struct Keymap {
|
|||
*/
|
||||
class EmulatedInputServer {
|
||||
public:
|
||||
EmulatedInputServer(std::string socketPath, Keymap keymap);
|
||||
EmulatedInputServer(std::string socketPath);
|
||||
std::string socketPath;
|
||||
|
||||
void startEmulating(int activationId);
|
||||
|
@ -32,6 +36,9 @@ class EmulatedInputServer {
|
|||
|
||||
int getFileDescriptor();
|
||||
|
||||
void setVirtualPointer(SP<CCZwlrVirtualPointerV1> ptr) {virtualPointer = ptr;}
|
||||
void setVirtualKeyboard(SP<CCZwpVirtualKeyboardV1> kb) {virtualKeyboard = kb; }
|
||||
|
||||
void stopServer();
|
||||
|
||||
private:
|
||||
|
@ -46,6 +53,15 @@ class EmulatedInputServer {
|
|||
eis_device* keyboard = nullptr;
|
||||
} client;
|
||||
|
||||
SP<CCZwlrVirtualPointerV1> virtualPointer = nullptr;
|
||||
SP<CCZwpVirtualKeyboardV1> virtualKeyboard = nullptr;
|
||||
uint32_t screenWidth = 0;
|
||||
uint32_t screenHeight = 0;
|
||||
|
||||
uint32_t depressed = 0;
|
||||
uint32_t latched = 0;
|
||||
uint32_t locked = 0;
|
||||
|
||||
Keymap keymap;
|
||||
|
||||
int onEvent(eis_event* e);
|
||||
|
|
Loading…
Reference in a new issue