mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 14:09:48 +01:00
virtual-pointer: move to new impl
This commit is contained in:
parent
7d49819b5e
commit
2755297670
13 changed files with 428 additions and 21 deletions
|
@ -262,6 +262,7 @@ protocolNew("protocols/wlr-gamma-control-unstable-v1.xml" "wlr-gamma-control-uns
|
|||
protocolNew("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||
protocolNew("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
||||
protocolNew("protocols/virtual-keyboard-unstable-v1.xml" "virtual-keyboard-unstable-v1" true)
|
||||
protocolNew("protocols/wlr-virtual-pointer-unstable-v1.xml" "wlr-virtual-pointer-unstable-v1" true)
|
||||
protocolNew("protocols/input-method-unstable-v2.xml" "input-method-unstable-v2" true)
|
||||
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
|
||||
protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||
|
|
|
@ -40,6 +40,7 @@ new_protocols = [
|
|||
['wlr-output-power-management-unstable-v1.xml'],
|
||||
['input-method-unstable-v2.xml'],
|
||||
['virtual-keyboard-unstable-v1.xml'],
|
||||
['wlr-virtual-pointer-unstable-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||
|
|
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>
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 virt = false;
|
||||
|
||||
bool connected = false; // means connected to the cursor
|
||||
bool connected = false; // means connected to the cursor
|
||||
|
||||
WP<CVirtualPointer> virtualPointer;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener destroyMouse;
|
||||
} listeners;
|
||||
|
||||
DYNLISTENER(destroyMouse);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
165
src/protocols/VirtualPointer.cpp
Normal file
165
src/protocols/VirtualPointer.cpp
Normal file
|
@ -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);
|
||||
}
|
57
src/protocols/VirtualPointer.hpp
Normal file
57
src/protocols/VirtualPointer.hpp
Normal file
|
@ -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;
|
||||
};
|
Loading…
Reference in a new issue