summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-05-03 01:27:59 +0100
committerVaxry <vaxry@vaxry.net>2024-05-03 01:52:05 +0100
commit27552976705e416ce481ca74d377578bcbc134e0 (patch)
treef878f05a1bffead708cdc7dc480e0b199860f163 /src
parent7d49819b5ecb4cb69d3db405a658ba44c17fc8e6 (diff)
virtual-pointer: move to new impl
Diffstat (limited to 'src')
-rw-r--r--src/Compositor.cpp4
-rw-r--r--src/Compositor.hpp1
-rw-r--r--src/events/Devices.cpp8
-rw-r--r--src/helpers/WLClasses.hpp15
-rw-r--r--src/includes.hpp2
-rw-r--r--src/managers/ProtocolManager.cpp2
-rw-r--r--src/managers/input/InputManager.cpp36
-rw-r--r--src/managers/input/InputManager.hpp5
-rw-r--r--src/protocols/VirtualPointer.cpp165
-rw-r--r--src/protocols/VirtualPointer.hpp57
10 files changed, 274 insertions, 21 deletions
diff --git a/src/Compositor.cpp b/src/Compositor.cpp
index 80e61a25..3f53f6c3 100644
--- a/src/Compositor.cpp
+++ b/src/Compositor.cpp
@@ -245,8 +245,6 @@ void CCompositor::initServer() {
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
- m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
-
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
if (!m_sWRLDRMLeaseMgr) {
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
@@ -305,7 +303,6 @@ void CCompositor::initAllSignals() {
addWLSignal(&m_sWLROutputLayout->events.change, &Events::listen_change, m_sWLROutputLayout, "OutputLayout");
addWLSignal(&m_sWLROutputMgr->events.apply, &Events::listen_outputMgrApply, m_sWLROutputMgr, "OutputMgr");
addWLSignal(&m_sWLROutputMgr->events.test, &Events::listen_outputMgrTest, m_sWLROutputMgr, "OutputMgr");
- addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
if (m_sWRLDRMLeaseMgr)
@@ -346,7 +343,6 @@ void CCompositor::removeAllSignals() {
removeWLSignal(&Events::listen_change);
removeWLSignal(&Events::listen_outputMgrApply);
removeWLSignal(&Events::listen_outputMgrTest);
- removeWLSignal(&Events::listen_newVirtPtr);
removeWLSignal(&Events::listen_RendererDestroy);
if (m_sWRLDRMLeaseMgr)
diff --git a/src/Compositor.hpp b/src/Compositor.hpp
index 175688c7..02fd6311 100644
--- a/src/Compositor.hpp
+++ b/src/Compositor.hpp
@@ -60,7 +60,6 @@ class CCompositor {
wlr_egl* m_sWLREGL;
int m_iDRMFD;
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
- wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
wlr_tablet_manager_v2* m_sWLRTabletManager;
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
wlr_linux_dmabuf_v1* m_sWLRLinuxDMABuf;
diff --git a/src/events/Devices.cpp b/src/events/Devices.cpp
index bf72d89f..ec0b14c4 100644
--- a/src/events/Devices.cpp
+++ b/src/events/Devices.cpp
@@ -93,14 +93,6 @@ void Events::listener_newInput(wl_listener* listener, void* data) {
g_pInputManager->updateCapabilities();
}
-void Events::listener_newVirtPtr(wl_listener* listener, void* data) {
- const auto EV = (wlr_virtual_pointer_v1_new_pointer_event*)data;
- const auto POINTER = EV->new_pointer;
- const auto DEVICE = &POINTER->pointer.base;
-
- g_pInputManager->newMouse(DEVICE, true);
-}
-
void Events::listener_destroyMouse(void* owner, void* data) {
const auto PMOUSE = (SMouse*)owner;
diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp
index 6b155e83..7eaebead 100644
--- a/src/helpers/WLClasses.hpp
+++ b/src/helpers/WLClasses.hpp
@@ -12,6 +12,7 @@
class CMonitor;
class CVirtualKeyboard;
+class CVirtualPointer;
struct SRenderData {
CMonitor* pMonitor;
@@ -104,13 +105,19 @@ struct SKeyboard {
};
struct SMouse {
- wlr_input_device* mouse = nullptr;
+ wlr_input_device* mouse = nullptr;
- std::string name = "";
+ std::string name = "";
+
+ bool virt = false;
+
+ bool connected = false; // means connected to the cursor
- bool virt = false;
+ WP<CVirtualPointer> virtualPointer;
- bool connected = false; // means connected to the cursor
+ struct {
+ CHyprSignalListener destroyMouse;
+ } listeners;
DYNLISTENER(destroyMouse);
diff --git a/src/includes.hpp b/src/includes.hpp
index 052c973e..73611fb2 100644
--- a/src/includes.hpp
+++ b/src/includes.hpp
@@ -67,7 +67,6 @@ extern "C" {
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_damage_ring.h>
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
-#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <wlr/util/edges.h>
@@ -79,6 +78,7 @@ extern "C" {
#include <wlr/render/gles2.h>
#include <wlr/render/wlr_texture.h>
#include <wlr/interfaces/wlr_keyboard.h>
+#include <wlr/interfaces/wlr_pointer.h>
#include <wlr/types/wlr_xdg_foreign_registry.h>
#include <wlr/types/wlr_xdg_foreign_v1.h>
#include <wlr/types/wlr_xdg_foreign_v2.h>
diff --git a/src/managers/ProtocolManager.cpp b/src/managers/ProtocolManager.cpp
index 122e2ff1..8ec2a35f 100644
--- a/src/managers/ProtocolManager.cpp
+++ b/src/managers/ProtocolManager.cpp
@@ -21,6 +21,7 @@
#include "../protocols/SessionLock.hpp"
#include "../protocols/InputMethodV2.hpp"
#include "../protocols/VirtualKeyboard.hpp"
+#include "../protocols/VirtualPointer.hpp"
CProtocolManager::CProtocolManager() {
@@ -45,6 +46,7 @@ CProtocolManager::CProtocolManager() {
PROTO::sessionLock = std::make_unique<CSessionLockProtocol>(&ext_session_lock_manager_v1_interface, 1, "SessionLock");
PROTO::ime = std::make_unique<CInputMethodV2Protocol>(&zwp_input_method_manager_v2_interface, 1, "IMEv2");
PROTO::virtualKeyboard = std::make_unique<CVirtualKeyboardProtocol>(&zwp_virtual_keyboard_manager_v1_interface, 1, "VirtualKeyboard");
+ PROTO::virtualPointer = std::make_unique<CVirtualPointerProtocol>(&zwlr_virtual_pointer_manager_v1_interface, 2, "VirtualPointer");
// Old protocol implementations.
// TODO: rewrite them to use hyprwayland-scanner.
diff --git a/src/managers/input/InputManager.cpp b/src/managers/input/InputManager.cpp
index e3c1b463..58b5caa3 100644
--- a/src/managers/input/InputManager.cpp
+++ b/src/managers/input/InputManager.cpp
@@ -12,6 +12,7 @@
#include "../../protocols/SessionLock.hpp"
#include "../../protocols/InputMethodV2.hpp"
#include "../../protocols/VirtualKeyboard.hpp"
+#include "../../protocols/VirtualPointer.hpp"
CInputManager::CInputManager() {
m_sListeners.setCursorShape = PROTO::cursorShape->events.setShape.registerListener([this](std::any data) {
@@ -40,6 +41,8 @@ CInputManager::CInputManager() {
m_sListeners.newIdleInhibitor = PROTO::idleInhibit->events.newIdleInhibitor.registerListener([this](std::any data) { this->newIdleInhibitor(data); });
m_sListeners.newVirtualKeyboard =
PROTO::virtualKeyboard->events.newKeyboard.registerListener([this](std::any data) { this->newVirtualKeyboard(std::any_cast<SP<CVirtualKeyboard>>(data)); });
+ m_sListeners.newVirtualMouse =
+ PROTO::virtualPointer->events.newPointer.registerListener([this](std::any data) { this->newVirtualMouse(std::any_cast<SP<CVirtualPointer>>(data)); });
}
CInputManager::~CInputManager() {
@@ -968,12 +971,41 @@ void CInputManager::applyConfigToKeyboard(SKeyboard* pKeyboard) {
pKeyboard->keyboard->name);
}
-void CInputManager::newMouse(wlr_input_device* mouse, bool virt) {
+void CInputManager::newVirtualMouse(SP<CVirtualPointer> mouse) {
+ const auto PMOUSE = &m_lMice.emplace_back();
+
+ PMOUSE->mouse = &mouse->wlr()->base;
+ PMOUSE->virtualPointer = mouse;
+ PMOUSE->virt = true;
+ try {
+ PMOUSE->name = getNameForNewDevice(mouse->wlr()->base.name);
+ } catch (std::exception& e) {
+ Debug::log(ERR, "Mouse had no name???"); // logic error
+ }
+
+ wlr_cursor_attach_input_device(g_pCompositor->m_sWLRCursor, &mouse->wlr()->base);
+
+ PMOUSE->connected = true;
+
+ setPointerConfigs();
+
+ PMOUSE->hyprListener_destroyMouse.initCallback(&mouse->wlr()->base.events.destroy, &Events::listener_destroyMouse, PMOUSE, "Mouse");
+
+ // TODO: this pointer pass sucks.
+ PMOUSE->listeners.destroyMouse = mouse->events.destroy.registerListener([this, PMOUSE](std::any data) { destroyMouse(PMOUSE->mouse); });
+
+ g_pCompositor->m_sSeat.mouse = PMOUSE;
+
+ m_tmrLastCursorMovement.reset();
+
+ Debug::log(LOG, "New virtual mouse created, pointer WLR: {:x}", (uintptr_t)mouse->wlr());
+}
+
+void CInputManager::newMouse(wlr_input_device* mouse) {
m_lMice.emplace_back();
const auto PMOUSE = &m_lMice.back();
PMOUSE->mouse = mouse;
- PMOUSE->virt = virt;
try {
PMOUSE->name = getNameForNewDevice(mouse->name);
} catch (std::exception& e) {
diff --git a/src/managers/input/InputManager.hpp b/src/managers/input/InputManager.hpp
index 27551249..6a338088 100644
--- a/src/managers/input/InputManager.hpp
+++ b/src/managers/input/InputManager.hpp
@@ -12,6 +12,7 @@ class CPointerConstraint;
class CWindow;
class CIdleInhibitor;
class CVirtualKeyboard;
+class CVirtualPointer;
enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0,
@@ -79,7 +80,8 @@ class CInputManager {
void newKeyboard(wlr_input_device*);
void newVirtualKeyboard(SP<CVirtualKeyboard>);
- void newMouse(wlr_input_device*, bool virt = false);
+ void newMouse(wlr_input_device*);
+ void newVirtualMouse(SP<CVirtualPointer>);
void newTouchDevice(wlr_input_device*);
void newSwitch(wlr_input_device*);
void destroyTouchDevice(STouchDevice*);
@@ -201,6 +203,7 @@ class CInputManager {
CHyprSignalListener setCursorShape;
CHyprSignalListener newIdleInhibitor;
CHyprSignalListener newVirtualKeyboard;
+ CHyprSignalListener newVirtualMouse;
} m_sListeners;
bool m_bCursorImageOverridden = false;
diff --git a/src/protocols/VirtualPointer.cpp b/src/protocols/VirtualPointer.cpp
new file mode 100644
index 00000000..287e7bad
--- /dev/null
+++ b/src/protocols/VirtualPointer.cpp
@@ -0,0 +1,165 @@
+#include "VirtualPointer.hpp"
+
+#define LOGM PROTO::virtualPointer->protoLog
+
+static const wlr_pointer_impl pointerImpl = {
+ .name = "virtual-pointer-v1",
+};
+
+CVirtualPointer::CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_) : resource(resource_) {
+ if (!good())
+ return;
+
+ resource->setDestroy([this](CZwlrVirtualPointerV1* r) {
+ events.destroy.emit();
+ PROTO::virtualPointer->destroyResource(this);
+ });
+ resource->setOnDestroy([this](CZwlrVirtualPointerV1* r) {
+ events.destroy.emit();
+ PROTO::virtualPointer->destroyResource(this);
+ });
+
+ wlr_pointer_init(&pointer, &pointerImpl, "CVirtualPointer");
+
+ resource->setMotion([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, wl_fixed_t dx, wl_fixed_t dy) {
+ wlr_pointer_motion_event event = {
+ .pointer = &pointer,
+ .time_msec = timeMs,
+ .delta_x = wl_fixed_to_double(dx),
+ .delta_y = wl_fixed_to_double(dy),
+ .unaccel_dx = wl_fixed_to_double(dx),
+ .unaccel_dy = wl_fixed_to_double(dy),
+ };
+ wl_signal_emit_mutable(&pointer.events.motion, &event);
+ });
+
+ resource->setMotionAbsolute([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t x, uint32_t y, uint32_t xExtent, uint32_t yExtent) {
+ if (!xExtent || !yExtent)
+ return;
+
+ wlr_pointer_motion_absolute_event event = {
+ .pointer = &pointer,
+ .time_msec = timeMs,
+ .x = (double)x / xExtent,
+ .y = (double)y / yExtent,
+ };
+ wl_signal_emit_mutable(&pointer.events.motion_absolute, &event);
+ });
+
+ resource->setButton([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t button, uint32_t state) {
+ struct wlr_pointer_button_event event = {
+ .pointer = &pointer,
+ .time_msec = timeMs,
+ .button = button,
+ .state = (wl_pointer_button_state)state,
+ };
+ wl_signal_emit_mutable(&pointer.events.button, &event);
+ });
+
+ resource->setAxis([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value) {
+ if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
+ r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
+ return;
+ }
+
+ axis = axis_;
+ axisEvents[axis] = wlr_pointer_axis_event{.pointer = &pointer, .time_msec = timeMs, .orientation = (wl_pointer_axis)axis, .delta = wl_fixed_to_double(value)};
+ });
+
+ resource->setFrame([this](CZwlrVirtualPointerV1* r) {
+ for (auto& e : axisEvents) {
+ if (!e.pointer)
+ continue;
+ wl_signal_emit_mutable(&pointer.events.axis, &e);
+ e.pointer = nullptr;
+ }
+
+ wl_signal_emit_mutable(&pointer.events.frame, &pointer);
+ });
+
+ resource->setAxisSource([this](CZwlrVirtualPointerV1* r, uint32_t source) { axisEvents[axis].source = (wl_pointer_axis_source)source; });
+
+ resource->setAxisStop([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_) {
+ if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
+ r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
+ return;
+ }
+
+ axis = axis_;
+ axisEvents[axis].pointer = &pointer;
+ axisEvents[axis].time_msec = timeMs;
+ axisEvents[axis].orientation = (wl_pointer_axis)axis;
+ axisEvents[axis].delta = 0;
+ axisEvents[axis].delta_discrete = 0;
+ });
+
+ resource->setAxisDiscrete([this](CZwlrVirtualPointerV1* r, uint32_t timeMs, uint32_t axis_, wl_fixed_t value, int32_t discrete) {
+ if (axis > WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
+ r->error(ZWLR_VIRTUAL_POINTER_V1_ERROR_INVALID_AXIS, "Invalid axis");
+ return;
+ }
+
+ axis = axis_;
+ axisEvents[axis].pointer = &pointer;
+ axisEvents[axis].time_msec = timeMs;
+ axisEvents[axis].orientation = (wl_pointer_axis)axis;
+ axisEvents[axis].delta = wl_fixed_to_double(value);
+ axisEvents[axis].delta_discrete = discrete * 120;
+ });
+}
+
+CVirtualPointer::~CVirtualPointer() {
+ wlr_pointer_finish(&pointer);
+ events.destroy.emit();
+}
+
+bool CVirtualPointer::good() {
+ return resource->resource();
+}
+
+wlr_pointer* CVirtualPointer::wlr() {
+ return &pointer;
+}
+
+wl_client* CVirtualPointer::client() {
+ return resource->client();
+}
+
+CVirtualPointerProtocol::CVirtualPointerProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
+ ;
+}
+
+void CVirtualPointerProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
+ const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CZwlrVirtualPointerManagerV1>(client, ver, id)).get();
+ RESOURCE->setOnDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
+ RESOURCE->setDestroy([this](CZwlrVirtualPointerManagerV1* p) { this->onManagerResourceDestroy(p->resource()); });
+
+ RESOURCE->setCreateVirtualPointer([this](CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) { this->onCreatePointer(pMgr, seat, id); });
+ RESOURCE->setCreateVirtualPointerWithOutput([this](CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, wl_resource* output, uint32_t id) {
+ LOGM(WARN, "TODO: CreateWithOutput is not supported yet. Ignoring for now.");
+ this->onCreatePointer(pMgr, seat, id);
+ });
+}
+
+void CVirtualPointerProtocol::onManagerResourceDestroy(wl_resource* res) {
+ std::erase_if(m_vManagers, [&](const auto& other) { return other->resource() == res; });
+}
+
+void CVirtualPointerProtocol::destroyResource(CVirtualPointer* pointer) {
+ std::erase_if(m_vPointers, [&](const auto& other) { return other.get() == pointer; });
+}
+
+void CVirtualPointerProtocol::onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id) {
+
+ const auto RESOURCE = m_vPointers.emplace_back(std::make_shared<CVirtualPointer>(std::make_shared<CZwlrVirtualPointerV1>(pMgr->client(), pMgr->version(), id)));
+
+ if (!RESOURCE->good()) {
+ pMgr->noMemory();
+ m_vPointers.pop_back();
+ return;
+ }
+
+ LOGM(LOG, "New VPointer at id {}", id);
+
+ events.newPointer.emit(RESOURCE);
+} \ No newline at end of file
diff --git a/src/protocols/VirtualPointer.hpp b/src/protocols/VirtualPointer.hpp
new file mode 100644
index 00000000..4528b491
--- /dev/null
+++ b/src/protocols/VirtualPointer.hpp
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <memory>
+#include <vector>
+#include <cstdint>
+#include <array>
+#include "WaylandProtocol.hpp"
+#include "wlr-virtual-pointer-unstable-v1.hpp"
+#include "../helpers/signal/Signal.hpp"
+
+class CVirtualPointer {
+ public:
+ CVirtualPointer(SP<CZwlrVirtualPointerV1> resource_);
+ ~CVirtualPointer();
+
+ struct {
+ CSignal destroy;
+ } events;
+
+ bool good();
+ wlr_pointer* wlr();
+ wl_client* client();
+
+ private:
+ SP<CZwlrVirtualPointerV1> resource;
+ wlr_pointer pointer;
+
+ uint32_t axis = 0;
+
+ std::array<wlr_pointer_axis_event, 2> axisEvents;
+};
+
+class CVirtualPointerProtocol : public IWaylandProtocol {
+ public:
+ CVirtualPointerProtocol(const wl_interface* iface, const int& ver, const std::string& name);
+
+ virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
+
+ struct {
+ CSignal newPointer; // SP<CVirtualPointer>
+ } events;
+
+ private:
+ void onManagerResourceDestroy(wl_resource* res);
+ void destroyResource(CVirtualPointer* pointer);
+ void onCreatePointer(CZwlrVirtualPointerManagerV1* pMgr, wl_resource* seat, uint32_t id);
+
+ //
+ std::vector<UP<CZwlrVirtualPointerManagerV1>> m_vManagers;
+ std::vector<SP<CVirtualPointer>> m_vPointers;
+
+ friend class CVirtualPointer;
+};
+
+namespace PROTO {
+ inline UP<CVirtualPointerProtocol> virtualPointer;
+};