tablets and shit

This commit is contained in:
Vaxry 2024-07-03 19:14:23 +02:00
parent 24e4768753
commit 7754368ade
13 changed files with 379 additions and 444 deletions

84
patch.txt Normal file
View file

@ -0,0 +1,84 @@
diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp
index 8b4ba0ee..e34aa54b 100644
--- a/src/managers/PointerManager.cpp
+++ b/src/managers/PointerManager.cpp
@@ -4,6 +4,7 @@
#include "../protocols/PointerGestures.hpp"
#include "../protocols/FractionalScale.hpp"
#include "../protocols/core/Compositor.hpp"
+#include "eventLoop/EventLoopManager.hpp"
#include "SeatManager.hpp"
#include <wlr/interfaces/wlr_output.h>
#include <wlr/render/interface.h>
@@ -139,8 +140,8 @@ CPointerManager::CPointerManager() {
onMonitorLayoutChange();
- PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { onMonitorLayoutChange(); }, nullptr);
- PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { onMonitorLayoutChange(); }, nullptr);
+ PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr);
+ PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr);
PMONITOR->events.destroy.registerStaticListener(
[this](void* owner, std::any data) {
if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown)
diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp
index 1193ffb8..e2d72f22 100644
--- a/src/managers/eventLoop/EventLoopManager.cpp
+++ b/src/managers/eventLoop/EventLoopManager.cpp
@@ -86,4 +86,25 @@ void CEventLoopManager::nudgeTimers() {
itimerspec ts = {.it_value = now};
timerfd_settime(m_sTimers.timerfd, TFD_TIMER_ABSTIME, &ts, nullptr);
-}
\ No newline at end of file
+}
+
+void CEventLoopManager::doLater(const std::function<void()>& fn) {
+ m_sIdle.fns.emplace_back(fn);
+
+ if (m_sIdle.eventSource)
+ return;
+
+ m_sIdle.eventSource = wl_event_loop_add_idle(
+ m_sWayland.loop,
+ [](void* data) {
+ auto IDLE = (CEventLoopManager::SIdleData*)data;
+ auto cpy = IDLE->fns;
+ IDLE->fns.clear();
+ IDLE->eventSource = nullptr;
+ for (auto& c : cpy) {
+ if (c)
+ c();
+ }
+ },
+ &m_sIdle);
+}
diff --git a/src/managers/eventLoop/EventLoopManager.hpp b/src/managers/eventLoop/EventLoopManager.hpp
index 7a4fa19e..77e57513 100644
--- a/src/managers/eventLoop/EventLoopManager.hpp
+++ b/src/managers/eventLoop/EventLoopManager.hpp
@@ -23,6 +23,14 @@ class CEventLoopManager {
// recalculates timers
void nudgeTimers();
+ // schedules a function to run later, aka in a wayland idle event.
+ void doLater(const std::function<void()>& fn);
+
+ struct SIdleData {
+ wl_event_source* eventSource = nullptr;
+ std::vector<std::function<void()>> fns;
+ };
+
private:
struct {
wl_event_loop* loop = nullptr;
@@ -34,6 +42,8 @@ class CEventLoopManager {
std::vector<SP<CEventLoopTimer>> timers;
int timerfd = -1;
} m_sTimers;
+
+ SIdleData m_sIdle;
};
inline std::unique_ptr<CEventLoopManager> g_pEventLoopManager;
\ No newline at end of file

View file

@ -318,6 +318,50 @@ void CCompositor::initAllSignals() {
g_pInputManager->newSwitch(dev); g_pInputManager->newSwitch(dev);
}, },
nullptr); nullptr);
m_pAqBackend->events.newTablet.registerStaticListener(
[](void* data, std::any d) {
auto dev = std::any_cast<SP<Aquamarine::ITablet>>(d);
Debug::log(LOG, "New aquamarine tablet with name {}", dev->getName());
g_pInputManager->newTablet(dev);
},
nullptr);
m_pAqBackend->events.newTabletPad.registerStaticListener(
[](void* data, std::any d) {
auto dev = std::any_cast<SP<Aquamarine::ITabletPad>>(d);
Debug::log(LOG, "New aquamarine tablet pad with name {}", dev->getName());
g_pInputManager->newTabletPad(dev);
},
nullptr);
if (m_pAqBackend->hasSession()) {
m_pAqBackend->session->events.changeActive.registerStaticListener(
[this](void*, std::any) {
if (m_pAqBackend->session->active) {
Debug::log(LOG, "Session got activated!");
m_bSessionActive = true;
for (auto& m : m_vMonitors) {
scheduleFrameForMonitor(m.get());
g_pHyprRenderer->applyMonitorRule(m.get(), &m->activeMonitorRule, true);
}
g_pConfigManager->m_bWantsMonitorReload = true;
} else {
Debug::log(LOG, "Session got deactivated!");
m_bSessionActive = false;
for (auto& m : m_vMonitors) {
m->noFrameSchedule = true;
m->framesToSkip = 1;
}
}
},
nullptr);
}
} }
void CCompositor::removeAllSignals() { void CCompositor::removeAllSignals() {
@ -2293,9 +2337,8 @@ void CCompositor::updateWorkspaceSpecialRenderData(const int& id) {
} }
void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor) { void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor) {
// FIXME: if ((m_pAqBackend->hasSession() && !m_pAqBackend->session->active) || !m_bSessionActive)
// if ((m_sWLRSession && !m_sWLRSession->active) || !m_bSessionActive) return;
// return;
if (!pMonitor->m_bEnabled) if (!pMonitor->m_bEnabled)
return; return;
@ -2858,7 +2901,7 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>()); auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>());
if (std::string("HEADLESS-1") == output->name) { if (std::string("HEADLESS-1") == output->name) {
g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get(); g_pCompositor->m_pUnsafeOutput = PNEWMONITOR.get();
output->name = "FALLBACK"; // we are allowed to do this :) output->name = "FALLBACK"; // we are allowed to do this :)
} }
Debug::log(LOG, "New output with name {}", output->name); Debug::log(LOG, "New output with name {}", output->name);

View file

@ -597,9 +597,8 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
R"#( {{ R"#( {{
"address": "0x{:x}", "address": "0x{:x}",
"type": "tabletTool", "type": "tabletTool",
"belongsTo": "0x{:x}"
}},)#", }},)#",
(uintptr_t)d.get(), d->wlr() ? (uintptr_t)d->wlr()->data : 0); (uintptr_t)d.get());
} }
trimTrailingComma(result); trimTrailingComma(result);
@ -659,11 +658,11 @@ std::string devicesRequest(eHyprCtlOutputFormat format, std::string request) {
} }
for (auto& d : g_pInputManager->m_vTablets) { for (auto& d : g_pInputManager->m_vTablets) {
result += std::format("\tTablet at {:x}:\n\t\t{}\n\t\t\tsize: {}x{}mm\n", (uintptr_t)d.get(), d->hlName, d->wlr()->width_mm, d->wlr()->height_mm); result += std::format("\tTablet at {:x}:\n\t\t{}\n\t\t\tsize: {}x{}mm\n", (uintptr_t)d.get(), d->hlName, d->aq()->physicalSize.x, d->aq()->physicalSize.y);
} }
for (auto& d : g_pInputManager->m_vTabletTools) { for (auto& d : g_pInputManager->m_vTabletTools) {
result += std::format("\tTablet Tool at {:x} (belongs to {:x})\n", (uintptr_t)d.get(), d->wlr() ? (uintptr_t)d->wlr()->data : 0); result += std::format("\tTablet Tool at {:x}\n", (uintptr_t)d.get());
} }
result += "\n\nTouch:\n"; result += "\n\nTouch:\n";
@ -1385,7 +1384,7 @@ std::string dispatchOutput(eHyprCtlOutputFormat format, std::string request) {
const auto MODE = vars[1]; const auto MODE = vars[1];
bool added = false; bool added = false;
if (!vars[3].empty()) { if (!vars[3].empty()) {
for (auto& m : g_pCompositor->m_vRealMonitors) { for (auto& m : g_pCompositor->m_vRealMonitors) {

View file

@ -2,8 +2,9 @@
#include "../defines.hpp" #include "../defines.hpp"
#include "../protocols/Tablet.hpp" #include "../protocols/Tablet.hpp"
#include "../protocols/core/Compositor.hpp" #include "../protocols/core/Compositor.hpp"
#include <aquamarine/input/Input.hpp>
SP<CTablet> CTablet::create(wlr_tablet* tablet) { SP<CTablet> CTablet::create(SP<Aquamarine::ITablet> tablet) {
SP<CTablet> pTab = SP<CTablet>(new CTablet(tablet)); SP<CTablet> pTab = SP<CTablet>(new CTablet(tablet));
pTab->self = pTab; pTab->self = pTab;
@ -13,7 +14,7 @@ SP<CTablet> CTablet::create(wlr_tablet* tablet) {
return pTab; return pTab;
} }
SP<CTabletTool> CTabletTool::create(wlr_tablet_tool* tablet) { SP<CTabletTool> CTabletTool::create(SP<Aquamarine::ITabletTool> tablet) {
SP<CTabletTool> pTab = SP<CTabletTool>(new CTabletTool(tablet)); SP<CTabletTool> pTab = SP<CTabletTool>(new CTabletTool(tablet));
pTab->self = pTab; pTab->self = pTab;
@ -23,7 +24,7 @@ SP<CTabletTool> CTabletTool::create(wlr_tablet_tool* tablet) {
return pTab; return pTab;
} }
SP<CTabletPad> CTabletPad::create(wlr_tablet_pad* tablet) { SP<CTabletPad> CTabletPad::create(SP<Aquamarine::ITabletPad> tablet) {
SP<CTabletPad> pTab = SP<CTabletPad>(new CTabletPad(tablet)); SP<CTabletPad> pTab = SP<CTabletPad>(new CTabletPad(tablet));
pTab->self = pTab; pTab->self = pTab;
@ -33,33 +34,25 @@ SP<CTabletPad> CTabletPad::create(wlr_tablet_pad* tablet) {
return pTab; return pTab;
} }
SP<CTabletTool> CTabletTool::fromWlr(wlr_tablet_tool* tool) { static uint32_t aqUpdateToHl(uint32_t aq) {
return ((CTabletTool*)tool->data)->self.lock();
}
SP<CTablet> CTablet::fromWlr(wlr_tablet* tablet) {
return ((CTablet*)tablet->data)->self.lock();
}
static uint32_t wlrUpdateToHl(uint32_t wlr) {
uint32_t result = 0; uint32_t result = 0;
if (wlr & WLR_TABLET_TOOL_AXIS_X) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_X)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_X; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_X;
if (wlr & WLR_TABLET_TOOL_AXIS_Y) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_Y)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_Y; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_Y;
if (wlr & WLR_TABLET_TOOL_AXIS_DISTANCE) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_DISTANCE)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_DISTANCE; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_DISTANCE;
if (wlr & WLR_TABLET_TOOL_AXIS_PRESSURE) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_PRESSURE)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_PRESSURE; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_PRESSURE;
if (wlr & WLR_TABLET_TOOL_AXIS_TILT_X) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_TILT_X)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_X;
if (wlr & WLR_TABLET_TOOL_AXIS_TILT_Y) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_TILT_Y)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_TILT_Y;
if (wlr & WLR_TABLET_TOOL_AXIS_ROTATION) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_ROTATION)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_ROTATION; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_ROTATION;
if (wlr & WLR_TABLET_TOOL_AXIS_SLIDER) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_SLIDER)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_SLIDER; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_SLIDER;
if (wlr & WLR_TABLET_TOOL_AXIS_WHEEL) if (aq & Aquamarine::AQ_TABLET_TOOL_AXIS_WHEEL)
result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_WHEEL; result |= CTablet::eTabletToolAxes::HID_TABLET_TOOL_AXIS_WHEEL;
return result; return result;
} }
@ -68,97 +61,81 @@ uint32_t CTablet::getCapabilities() {
return HID_INPUT_CAPABILITY_POINTER | HID_INPUT_CAPABILITY_TABLET; return HID_INPUT_CAPABILITY_POINTER | HID_INPUT_CAPABILITY_TABLET;
} }
wlr_tablet* CTablet::wlr() { SP<Aquamarine::ITablet> CTablet::aq() {
return tablet; return tablet.lock();
} }
CTablet::CTablet(wlr_tablet* tablet_) : tablet(tablet_) { CTablet::CTablet(SP<Aquamarine::ITablet> tablet_) : tablet(tablet_) {
if (!tablet) if (!tablet)
return; return;
tablet->data = this; listeners.destroy = tablet->events.destroy.registerListener([this](std::any d) {
tablet.reset();
// clang-format off
hyprListener_destroy.initCallback(&tablet->base.events.destroy, [this] (void* owner, void* data) {
tablet = nullptr;
disconnectCallbacks();
events.destroy.emit(); events.destroy.emit();
}, this, "CTablet"); });
hyprListener_axis.initCallback(&tablet->events.axis, [this] (void* owner, void* data) { listeners.axis = tablet->events.axis.registerListener([this](std::any d) {
auto E = (wlr_tablet_tool_axis_event*)data; auto E = std::any_cast<Aquamarine::ITablet::SAxisEvent>(d);
tabletEvents.axis.emit(SAxisEvent{ tabletEvents.axis.emit(SAxisEvent{
.tool = E->tool, .tool = E.tool,
.tablet = self.lock(), .tablet = self.lock(),
.timeMs = E->time_msec, .timeMs = E.timeMs,
.updatedAxes = wlrUpdateToHl(E->updated_axes), .updatedAxes = aqUpdateToHl(E.updatedAxes),
.axis = {E->x, E->y}, .axis = E.absolute,
.axisDelta = {E->dx, E->dy}, .axisDelta = E.delta,
.tilt = {E->tilt_x, E->tilt_y}, .tilt = E.tilt,
.pressure = E->pressure, .pressure = E.pressure,
.distance = E->distance, .distance = E.distance,
.rotation = E->rotation, .rotation = E.rotation,
.slider = E->slider, .slider = E.slider,
.wheelDelta = E->wheel_delta, .wheelDelta = E.wheelDelta,
}); });
}, this, "CTablet"); });
hyprListener_proximity.initCallback(&tablet->events.proximity, [this] (void* owner, void* data) { listeners.proximity = tablet->events.proximity.registerListener([this](std::any d) {
auto E = (wlr_tablet_tool_proximity_event*)data; auto E = std::any_cast<Aquamarine::ITablet::SProximityEvent>(d);
tabletEvents.proximity.emit(SProximityEvent{ tabletEvents.proximity.emit(SProximityEvent{
.tool = E->tool, .tool = E.tool,
.tablet = self.lock(), .tablet = self.lock(),
.timeMs = E->time_msec, .timeMs = E.timeMs,
.proximity = {E->x, E->y}, .proximity = E.absolute,
.in = E->state == WLR_TABLET_TOOL_PROXIMITY_IN, .in = E.in,
}); });
}, this, "CTablet"); });
hyprListener_tip.initCallback(&tablet->events.tip, [this] (void* owner, void* data) { listeners.tip = tablet->events.tip.registerListener([this](std::any d) {
auto E = (wlr_tablet_tool_tip_event*)data; auto E = std::any_cast<Aquamarine::ITablet::STipEvent>(d);
tabletEvents.tip.emit(STipEvent{ tabletEvents.tip.emit(STipEvent{
.tool = E->tool, .tool = E.tool,
.tablet = self.lock(), .tablet = self.lock(),
.timeMs = E->time_msec, .timeMs = E.timeMs,
.tip = {E->x, E->y}, .tip = E.absolute,
.in = E->state == WLR_TABLET_TOOL_TIP_DOWN, .in = E.down,
}); });
}, this, "CTablet"); });
hyprListener_button.initCallback(&tablet->events.button, [this] (void* owner, void* data) { listeners.button = tablet->events.button.registerListener([this](std::any d) {
auto E = (wlr_tablet_tool_button_event*)data; auto E = std::any_cast<Aquamarine::ITablet::SButtonEvent>(d);
tabletEvents.button.emit(SButtonEvent{ tabletEvents.button.emit(SButtonEvent{
.tool = E->tool, .tool = E.tool,
.tablet = self.lock(), .tablet = self.lock(),
.timeMs = E->time_msec, .timeMs = E.timeMs,
.button = E->button, .button = E.button,
.down = E->state == WLR_BUTTON_PRESSED, .down = E.down,
}); });
}, this, "CTablet"); });
// clang-format on
deviceName = tablet->base.name ? tablet->base.name : "UNKNOWN"; deviceName = tablet->getName();
} }
CTablet::~CTablet() { CTablet::~CTablet() {
if (tablet)
tablet->data = nullptr;
PROTO::tablet->recheckRegisteredDevices(); PROTO::tablet->recheckRegisteredDevices();
} }
void CTablet::disconnectCallbacks() {
hyprListener_axis.removeCallback();
hyprListener_button.removeCallback();
hyprListener_destroy.removeCallback();
hyprListener_proximity.removeCallback();
hyprListener_tip.removeCallback();
}
eHIDType CTablet::getType() { eHIDType CTablet::getType() {
return HID_TYPE_TABLET; return HID_TYPE_TABLET;
} }
@ -167,138 +144,111 @@ uint32_t CTabletPad::getCapabilities() {
return HID_INPUT_CAPABILITY_TABLET; return HID_INPUT_CAPABILITY_TABLET;
} }
wlr_tablet_pad* CTabletPad::wlr() { SP<Aquamarine::ITabletPad> CTabletPad::aq() {
return pad; return pad.lock();
} }
eHIDType CTabletPad::getType() { eHIDType CTabletPad::getType() {
return HID_TYPE_TABLET_PAD; return HID_TYPE_TABLET_PAD;
} }
CTabletPad::CTabletPad(wlr_tablet_pad* pad_) : pad(pad_) { CTabletPad::CTabletPad(SP<Aquamarine::ITabletPad> pad_) : pad(pad_) {
if (!pad) if (!pad)
return; return;
// clang-format off listeners.destroy = pad->events.destroy.registerListener([this](std::any d) {
hyprListener_destroy.initCallback(&pad->base.events.destroy, [this] (void* owner, void* data) { pad.reset();
pad = nullptr;
disconnectCallbacks();
events.destroy.emit(); events.destroy.emit();
}, this, "CTabletPad"); });
hyprListener_button.initCallback(&pad->events.button, [this] (void* owner, void* data) { listeners.button = pad->events.button.registerListener([this](std::any d) {
auto E = (wlr_tablet_pad_button_event*)data; auto E = std::any_cast<Aquamarine::ITabletPad::SButtonEvent>(d);
padEvents.button.emit(SButtonEvent{ padEvents.button.emit(SButtonEvent{
.timeMs = E->time_msec, .timeMs = E.timeMs,
.button = E->button, .button = E.button,
.down = E->state == WLR_BUTTON_PRESSED, .down = E.down,
.mode = E->mode, .mode = E.mode,
.group = E->group, .group = E.group,
}); });
}, this, "CTabletPad"); });
hyprListener_ring.initCallback(&pad->events.ring, [this] (void* owner, void* data) { listeners.ring = pad->events.ring.registerListener([this](std::any d) {
auto E = (wlr_tablet_pad_ring_event*)data; auto E = std::any_cast<Aquamarine::ITabletPad::SRingEvent>(d);
padEvents.ring.emit(SRingEvent{ padEvents.ring.emit(SRingEvent{
.timeMs = E->time_msec, .timeMs = E.timeMs,
.finger = E->source == WLR_TABLET_PAD_RING_SOURCE_FINGER, .finger = E.source == Aquamarine::ITabletPad::AQ_TABLET_PAD_RING_SOURCE_FINGER,
.ring = E->ring, .ring = E.ring,
.position = E->position, .position = E.pos,
.mode = E->mode, .mode = E.mode,
}); });
}, this, "CTabletPad"); });
hyprListener_strip.initCallback(&pad->events.strip, [this] (void* owner, void* data) { listeners.strip = pad->events.strip.registerListener([this](std::any d) {
auto E = (wlr_tablet_pad_strip_event*)data; auto E = std::any_cast<Aquamarine::ITabletPad::SStripEvent>(d);
padEvents.strip.emit(SStripEvent{ padEvents.strip.emit(SStripEvent{
.timeMs = E->time_msec, .timeMs = E.timeMs,
.finger = E->source == WLR_TABLET_PAD_STRIP_SOURCE_FINGER, .finger = E.source == Aquamarine::ITabletPad::AQ_TABLET_PAD_STRIP_SOURCE_FINGER,
.strip = E->strip, .strip = E.strip,
.position = E->position, .position = E.pos,
.mode = E->mode, .mode = E.mode,
}); });
}, this, "CTabletPad"); });
hyprListener_attach.initCallback(&pad->events.attach_tablet, [this] (void* owner, void* data) { listeners.attach = pad->events.attach.registerListener([this](std::any d) {
if (!data) ; // TODO: this doesn't do anything in aq atm
return; });
padEvents.attach.emit(CTabletTool::fromWlr((wlr_tablet_tool*)data));
}, this, "CTabletPad");
// clang-format on
deviceName = pad->base.name ? pad->base.name : "UNKNOWN"; deviceName = pad->getName();
} }
CTabletPad::~CTabletPad() { CTabletPad::~CTabletPad() {
PROTO::tablet->recheckRegisteredDevices(); PROTO::tablet->recheckRegisteredDevices();
} }
void CTabletPad::disconnectCallbacks() {
hyprListener_ring.removeCallback();
hyprListener_button.removeCallback();
hyprListener_destroy.removeCallback();
hyprListener_strip.removeCallback();
hyprListener_attach.removeCallback();
}
uint32_t CTabletTool::getCapabilities() { uint32_t CTabletTool::getCapabilities() {
return HID_INPUT_CAPABILITY_POINTER | HID_INPUT_CAPABILITY_TABLET; return HID_INPUT_CAPABILITY_POINTER | HID_INPUT_CAPABILITY_TABLET;
} }
wlr_tablet_tool* CTabletTool::wlr() { SP<Aquamarine::ITabletTool> CTabletTool::aq() {
return tool; return tool.lock();
} }
eHIDType CTabletTool::getType() { eHIDType CTabletTool::getType() {
return HID_TYPE_TABLET_TOOL; return HID_TYPE_TABLET_TOOL;
} }
CTabletTool::CTabletTool(wlr_tablet_tool* tool_) : tool(tool_) { CTabletTool::CTabletTool(SP<Aquamarine::ITabletTool> tool_) : tool(tool_) {
if (!tool) if (!tool)
return; return;
// clang-format off listeners.destroyTool = tool->events.destroy.registerListener([this] (std::any d) {
hyprListener_destroy.initCallback(&tool->events.destroy, [this] (void* owner, void* data) { tool.reset();
tool = nullptr;
disconnectCallbacks();
events.destroy.emit(); events.destroy.emit();
}, this, "CTabletTool"); });
// clang-format on
if (tool->tilt) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_TILT)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_TILT; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_TILT;
if (tool->pressure) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_PRESSURE)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_PRESSURE; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_PRESSURE;
if (tool->distance) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_DISTANCE)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_DISTANCE; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_DISTANCE;
if (tool->rotation) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_ROTATION)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_ROTATION; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_ROTATION;
if (tool->slider) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_SLIDER)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_SLIDER; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_SLIDER;
if (tool->wheel) if (tool->capabilities & Aquamarine::ITabletTool::AQ_TABLET_TOOL_CAPABILITY_WHEEL)
toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_WHEEL; toolCapabilities |= HID_TABLET_TOOL_CAPABILITY_WHEEL;
tool->data = this; deviceName = std::format("{:x}-{:x}", tool->serial, tool->id);
deviceName = std::to_string(tool->hardware_serial) + std::to_string(tool->hardware_wacom);
} }
CTabletTool::~CTabletTool() { CTabletTool::~CTabletTool() {
if (tool)
tool->data = nullptr;
PROTO::tablet->recheckRegisteredDevices(); PROTO::tablet->recheckRegisteredDevices();
} }
void CTabletTool::disconnectCallbacks() {
hyprListener_destroy.removeCallback();
listeners.destroySurface.reset();
}
SP<CWLSurfaceResource> CTabletTool::getSurface() { SP<CWLSurfaceResource> CTabletTool::getSurface() {
return pSurface.lock(); return pSurface.lock();
} }

View file

@ -6,9 +6,9 @@
#include "../helpers/math/Math.hpp" #include "../helpers/math/Math.hpp"
#include "../helpers/math/Math.hpp" #include "../helpers/math/Math.hpp"
struct wlr_tablet; AQUAMARINE_FORWARD(ITablet);
struct wlr_tablet_tool; AQUAMARINE_FORWARD(ITabletTool);
struct wlr_tablet_pad; AQUAMARINE_FORWARD(ITabletPad);
class CTabletTool; class CTabletTool;
class CTabletPad; class CTabletPad;
@ -21,13 +21,12 @@ class CWLSurfaceResource;
*/ */
class CTablet : public IHID { class CTablet : public IHID {
public: public:
static SP<CTablet> create(wlr_tablet* tablet); static SP<CTablet> create(SP<Aquamarine::ITablet> tablet);
static SP<CTablet> fromWlr(wlr_tablet* tablet);
~CTablet(); ~CTablet();
virtual uint32_t getCapabilities(); virtual uint32_t getCapabilities();
virtual eHIDType getType(); virtual eHIDType getType();
wlr_tablet* wlr(); SP<Aquamarine::ITablet> aq();
enum eTabletToolAxes { enum eTabletToolAxes {
HID_TABLET_TOOL_AXIS_X = (1 << 0), HID_TABLET_TOOL_AXIS_X = (1 << 0),
@ -42,46 +41,46 @@ class CTablet : public IHID {
}; };
struct SAxisEvent { struct SAxisEvent {
wlr_tablet_tool* tool; SP<Aquamarine::ITabletTool> tool;
SP<CTablet> tablet; SP<CTablet> tablet;
uint32_t timeMs = 0; uint32_t timeMs = 0;
uint32_t updatedAxes = 0; // eTabletToolAxes uint32_t updatedAxes = 0; // eTabletToolAxes
Vector2D axis; Vector2D axis;
Vector2D axisDelta; Vector2D axisDelta;
Vector2D tilt; Vector2D tilt;
double pressure = 0; double pressure = 0;
double distance = 0; double distance = 0;
double rotation = 0; double rotation = 0;
double slider = 0; double slider = 0;
double wheelDelta = 0; double wheelDelta = 0;
}; };
struct SProximityEvent { struct SProximityEvent {
wlr_tablet_tool* tool; SP<Aquamarine::ITabletTool> tool;
SP<CTablet> tablet; SP<CTablet> tablet;
uint32_t timeMs = 0; uint32_t timeMs = 0;
Vector2D proximity; Vector2D proximity;
bool in = false; bool in = false;
}; };
struct STipEvent { struct STipEvent {
wlr_tablet_tool* tool; SP<Aquamarine::ITabletTool> tool;
SP<CTablet> tablet; SP<CTablet> tablet;
uint32_t timeMs = 0; uint32_t timeMs = 0;
Vector2D tip; Vector2D tip;
bool in = false; bool in = false;
}; };
struct SButtonEvent { struct SButtonEvent {
wlr_tablet_tool* tool; SP<Aquamarine::ITabletTool> tool;
SP<CTablet> tablet; SP<CTablet> tablet;
uint32_t timeMs = 0; uint32_t timeMs = 0;
uint32_t button; uint32_t button;
bool down = false; bool down = false;
}; };
struct { struct {
@ -100,27 +99,27 @@ class CTablet : public IHID {
CBox boundBox; // output-local CBox boundBox; // output-local
private: private:
CTablet(wlr_tablet* tablet); CTablet(SP<Aquamarine::ITablet> tablet);
void disconnectCallbacks(); WP<Aquamarine::ITablet> tablet;
wlr_tablet* tablet = nullptr; struct {
CHyprSignalListener destroy;
DYNLISTENER(destroy); CHyprSignalListener axis;
DYNLISTENER(axis); CHyprSignalListener proximity;
DYNLISTENER(proximity); CHyprSignalListener tip;
DYNLISTENER(tip); CHyprSignalListener button;
DYNLISTENER(button); } listeners;
}; };
class CTabletPad : public IHID { class CTabletPad : public IHID {
public: public:
static SP<CTabletPad> create(wlr_tablet_pad* pad); static SP<CTabletPad> create(SP<Aquamarine::ITabletPad> pad);
~CTabletPad(); ~CTabletPad();
virtual uint32_t getCapabilities(); virtual uint32_t getCapabilities();
virtual eHIDType getType(); virtual eHIDType getType();
wlr_tablet_pad* wlr(); SP<Aquamarine::ITabletPad> aq();
struct SButtonEvent { struct SButtonEvent {
uint32_t timeMs = 0; uint32_t timeMs = 0;
@ -159,23 +158,22 @@ class CTabletPad : public IHID {
std::string hlName; std::string hlName;
private: private:
CTabletPad(wlr_tablet_pad* pad); CTabletPad(SP<Aquamarine::ITabletPad> pad);
void disconnectCallbacks(); WP<Aquamarine::ITabletPad> pad;
wlr_tablet_pad* pad = nullptr; struct {
CHyprSignalListener destroy;
DYNLISTENER(destroy); CHyprSignalListener ring;
DYNLISTENER(ring); CHyprSignalListener strip;
DYNLISTENER(strip); CHyprSignalListener button;
DYNLISTENER(button); CHyprSignalListener attach;
DYNLISTENER(attach); } listeners;
}; };
class CTabletTool : public IHID { class CTabletTool : public IHID {
public: public:
static SP<CTabletTool> create(wlr_tablet_tool* tool); static SP<CTabletTool> create(SP<Aquamarine::ITabletTool> tool);
static SP<CTabletTool> fromWlr(wlr_tablet_tool* tool);
~CTabletTool(); ~CTabletTool();
enum eTabletToolType { enum eTabletToolType {
@ -198,35 +196,31 @@ class CTabletTool : public IHID {
HID_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5), HID_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5),
}; };
virtual uint32_t getCapabilities(); virtual uint32_t getCapabilities();
wlr_tablet_tool* wlr(); SP<Aquamarine::ITabletTool> aq();
virtual eHIDType getType(); virtual eHIDType getType();
SP<CWLSurfaceResource> getSurface(); SP<CWLSurfaceResource> getSurface();
void setSurface(SP<CWLSurfaceResource>); void setSurface(SP<CWLSurfaceResource>);
WP<CTabletTool> self; WP<CTabletTool> self;
Vector2D tilt; Vector2D tilt;
bool active = false; // true if in proximity bool active = false; // true if in proximity
uint32_t toolCapabilities = 0; uint32_t toolCapabilities = 0;
bool isDown = false; bool isDown = false;
std::vector<uint32_t> buttonsDown; std::vector<uint32_t> buttonsDown;
Vector2D absolutePos; // last known absolute position. Vector2D absolutePos; // last known absolute position.
std::string hlName; std::string hlName;
private: private:
CTabletTool(wlr_tablet_tool* tool); CTabletTool(SP<Aquamarine::ITabletTool> tool);
void disconnectCallbacks(); WP<CWLSurfaceResource> pSurface;
WP<Aquamarine::ITabletTool> tool;
WP<CWLSurfaceResource> pSurface;
wlr_tablet_tool* tool = nullptr;
DYNLISTENER(destroy);
struct { struct {
CHyprSignalListener destroySurface; CHyprSignalListener destroySurface;
CHyprSignalListener destroyTool;
} listeners; } listeners;
}; };

View file

@ -1,50 +0,0 @@
#include "Events.hpp"
#include "../Compositor.hpp"
#include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp"
#include "../render/Renderer.hpp"
// ---------------------------------------------------- //
// _____ ________ _______ _____ ______ _____ //
// | __ \| ____\ \ / /_ _/ ____| ____|/ ____| //
// | | | | |__ \ \ / / | || | | |__ | (___ //
// | | | | __| \ \/ / | || | | __| \___ \ //
// | |__| | |____ \ / _| || |____| |____ ____) | //
// |_____/|______| \/ |_____\_____|______|_____/ //
// //
// ---------------------------------------------------- //
void Events::listener_newInput(wl_listener* listener, void* data) {
const auto DEVICE = (wlr_input_device*)data;
switch (DEVICE->type) {
case WLR_INPUT_DEVICE_KEYBOARD:
Debug::log(LOG, "Attached a keyboard with name {}", DEVICE->name);
//g_pInputManager->newKeyboard(DEVICE);
break;
case WLR_INPUT_DEVICE_POINTER:
Debug::log(LOG, "Attached a mouse with name {}", DEVICE->name);
//g_pInputManager->newMouse(DEVICE);
break;
case WLR_INPUT_DEVICE_TOUCH:
Debug::log(LOG, "Attached a touch device with name {}", DEVICE->name);
// g_pInputManager->newTouchDevice(DEVICE);
break;
case WLR_INPUT_DEVICE_TABLET:
Debug::log(LOG, "Attached a tablet with name {}", DEVICE->name);
g_pInputManager->newTablet(DEVICE);
break;
case WLR_INPUT_DEVICE_TABLET_PAD:
Debug::log(LOG, "Attached a tablet pad with name {}", DEVICE->name);
g_pInputManager->newTabletPad(DEVICE);
break;
case WLR_INPUT_DEVICE_SWITCH:
Debug::log(LOG, "Attached a switch device with name {}", DEVICE->name);
// g_pInputManager->newSwitch(DEVICE);
break;
default: Debug::log(WARN, "Unrecognized input device plugged in: {}", DEVICE->name); break;
}
g_pInputManager->updateCapabilities();
}

View file

@ -8,16 +8,6 @@
// //
namespace Events { namespace Events {
// Monitor events
LISTENER(change);
LISTENER(newOutput);
// DRM events
LISTENER(leaseRequest);
// Layer events
LISTENER(newLayerSurface);
// Window events // Window events
DYNLISTENFUNC(commitWindow); DYNLISTENFUNC(commitWindow);
DYNLISTENFUNC(mapWindow); DYNLISTENFUNC(mapWindow);
@ -35,15 +25,6 @@ namespace Events {
DYNLISTENFUNC(setOverrideRedirect); DYNLISTENFUNC(setOverrideRedirect);
DYNLISTENFUNC(ackConfigure); DYNLISTENFUNC(ackConfigure);
LISTENER(newInput);
// Virt Ptr
LISTENER(newVirtPtr);
// Various
LISTENER(requestSetSel);
LISTENER(requestSetPrimarySel);
// Monitor part 2 the sequel // Monitor part 2 the sequel
DYNLISTENFUNC(monitorFrame); DYNLISTENFUNC(monitorFrame);
DYNLISTENFUNC(monitorDestroy); DYNLISTENFUNC(monitorDestroy);
@ -52,16 +33,4 @@ namespace Events {
DYNLISTENFUNC(monitorNeedsFrame); DYNLISTENFUNC(monitorNeedsFrame);
DYNLISTENFUNC(monitorCommit); DYNLISTENFUNC(monitorCommit);
DYNLISTENFUNC(monitorBind); DYNLISTENFUNC(monitorBind);
// XWayland
LISTENER(surfaceXWayland);
// Renderer destroy
LISTENER(RendererDestroy);
// session
LISTENER(sessionActive);
// Session Lock
LISTENER(newSessionLock);
}; };

View file

@ -1,54 +0,0 @@
#include "Events.hpp"
#include "../Compositor.hpp"
#include "../helpers/WLClasses.hpp"
#include "../managers/input/InputManager.hpp"
#include "../render/Renderer.hpp"
#include "../managers/CursorManager.hpp"
// ------------------------------ //
// __ __ _____ _____ _____ //
// | \/ |_ _|/ ____|/ ____| //
// | \ / | | | | (___ | | //
// | |\/| | | | \___ \| | //
// | | | |_| |_ ____) | |____ //
// |_| |_|_____|_____/ \_____| //
// //
// ------------------------------ //
void Events::listener_leaseRequest(wl_listener* listener, void* data) {
const auto REQUEST = (wlr_drm_lease_request_v1*)data;
struct wlr_drm_lease_v1* lease = wlr_drm_lease_request_v1_grant(REQUEST);
if (!lease) {
Debug::log(ERR, "Failed to grant lease request!");
wlr_drm_lease_request_v1_reject(REQUEST);
}
}
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
Debug::log(LOG, "!!Renderer destroyed!!");
}
void Events::listener_sessionActive(wl_listener* listener, void* data) {
if (g_pCompositor->m_pAqBackend->session->active) {
Debug::log(LOG, "Session got activated!");
g_pCompositor->m_bSessionActive = true;
for (auto& m : g_pCompositor->m_vMonitors) {
g_pCompositor->scheduleFrameForMonitor(m.get());
g_pHyprRenderer->applyMonitorRule(m.get(), &m->activeMonitorRule, true);
}
g_pConfigManager->m_bWantsMonitorReload = true;
} else {
Debug::log(LOG, "Session got inactivated!");
g_pCompositor->m_bSessionActive = false;
for (auto& m : g_pCompositor->m_vMonitors) {
m->noFrameSchedule = true;
m->framesToSkip = 1;
}
}
}

View file

@ -1495,9 +1495,9 @@ void CInputManager::setTouchDeviceConfigs(SP<ITouch> dev) {
void CInputManager::setTabletConfigs() { void CInputManager::setTabletConfigs() {
for (auto& t : m_vTablets) { for (auto& t : m_vTablets) {
if (wlr_input_device_is_libinput(&t->wlr()->base)) { if (t->aq()->getLibinputHandle()) {
const auto NAME = t->hlName; const auto NAME = t->hlName;
const auto LIBINPUTDEV = (libinput_device*)wlr_libinput_get_device_handle(&t->wlr()->base); const auto LIBINPUTDEV = t->aq()->getLibinputHandle();
const auto RELINPUT = g_pConfigManager->getDeviceInt(NAME, "relative_input", "input:tablet:relative_input"); const auto RELINPUT = g_pConfigManager->getDeviceInt(NAME, "relative_input", "input:tablet:relative_input");
t->relativeInput = RELINPUT; t->relativeInput = RELINPUT;
@ -1525,8 +1525,8 @@ void CInputManager::setTabletConfigs() {
const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(NAME, "active_area_size", "input:tablet:active_area_size"); const auto ACTIVE_AREA_SIZE = g_pConfigManager->getDeviceVec(NAME, "active_area_size", "input:tablet:active_area_size");
const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(NAME, "active_area_position", "input:tablet:active_area_position"); const auto ACTIVE_AREA_POS = g_pConfigManager->getDeviceVec(NAME, "active_area_position", "input:tablet:active_area_position");
if (ACTIVE_AREA_SIZE.x != 0 || ACTIVE_AREA_SIZE.y != 0) { if (ACTIVE_AREA_SIZE.x != 0 || ACTIVE_AREA_SIZE.y != 0) {
t->activeArea = CBox{ACTIVE_AREA_POS.x / t->wlr()->width_mm, ACTIVE_AREA_POS.y / t->wlr()->height_mm, (ACTIVE_AREA_POS.x + ACTIVE_AREA_SIZE.x) / t->wlr()->width_mm, t->activeArea = CBox{ACTIVE_AREA_POS.x / t->aq()->physicalSize.x, ACTIVE_AREA_POS.y / t->aq()->physicalSize.y,
(ACTIVE_AREA_POS.y + ACTIVE_AREA_SIZE.y) / t->wlr()->height_mm}; (ACTIVE_AREA_POS.x + ACTIVE_AREA_SIZE.x) / t->aq()->physicalSize.x, (ACTIVE_AREA_POS.y + ACTIVE_AREA_SIZE.y) / t->aq()->physicalSize.y};
} }
} }
} }

View file

@ -22,6 +22,9 @@ AQUAMARINE_FORWARD(IPointer);
AQUAMARINE_FORWARD(IKeyboard); AQUAMARINE_FORWARD(IKeyboard);
AQUAMARINE_FORWARD(ITouch); AQUAMARINE_FORWARD(ITouch);
AQUAMARINE_FORWARD(ISwitch); AQUAMARINE_FORWARD(ISwitch);
AQUAMARINE_FORWARD(ITablet);
AQUAMARINE_FORWARD(ITabletTool);
AQUAMARINE_FORWARD(ITabletPad);
enum eClickBehaviorMode { enum eClickBehaviorMode {
CLICKMODE_DEFAULT = 0, CLICKMODE_DEFAULT = 0,
@ -93,9 +96,8 @@ class CInputManager {
void newVirtualMouse(SP<CVirtualPointerV1Resource>); void newVirtualMouse(SP<CVirtualPointerV1Resource>);
void newTouchDevice(SP<Aquamarine::ITouch>); void newTouchDevice(SP<Aquamarine::ITouch>);
void newSwitch(SP<Aquamarine::ISwitch>); void newSwitch(SP<Aquamarine::ISwitch>);
void newTabletTool(wlr_tablet_tool*); void newTabletPad(SP<Aquamarine::ITabletPad>);
void newTabletPad(wlr_input_device*); void newTablet(SP<Aquamarine::ITablet>);
void newTablet(wlr_input_device*);
void destroyTouchDevice(SP<ITouch>); void destroyTouchDevice(SP<ITouch>);
void destroyKeyboard(SP<IKeyboard>); void destroyKeyboard(SP<IKeyboard>);
void destroyPointer(SP<IPointer>); void destroyPointer(SP<IPointer>);
@ -237,7 +239,7 @@ class CInputManager {
void mouseMoveUnified(uint32_t, bool refocus = false); void mouseMoveUnified(uint32_t, bool refocus = false);
SP<CTabletTool> ensureTabletToolPresent(wlr_tablet_tool*); SP<CTabletTool> ensureTabletToolPresent(SP<Aquamarine::ITabletTool>);
void applyConfigToKeyboard(SP<IKeyboard>); void applyConfigToKeyboard(SP<IKeyboard>);

View file

@ -62,7 +62,7 @@ static void refocusTablet(SP<CTablet> tab, SP<CTabletTool> tool, bool motion = f
if (!motion) if (!motion)
return; return;
if (LASTHLSURFACE->constraint() && tool->wlr()->type != WLR_TABLET_TOOL_TYPE_MOUSE) { if (LASTHLSURFACE->constraint() && tool->aq()->type != Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_MOUSE) {
// cursor logic will completely break here as the cursor will be locked. // cursor logic will completely break here as the cursor will be locked.
// let's just "map" the desired position to the constraint area. // let's just "map" the desired position to the constraint area.
@ -102,7 +102,7 @@ void CInputManager::onTabletAxis(CTablet::SAxisEvent e) {
Vector2D delta = {std::isnan(dx) ? 0.0 : dx, std::isnan(dy) ? 0.0 : dy}; Vector2D delta = {std::isnan(dx) ? 0.0 : dx, std::isnan(dy) ? 0.0 : dy};
switch (e.tool->type) { switch (e.tool->type) {
case WLR_TABLET_TOOL_TYPE_MOUSE: { case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_MOUSE: {
g_pPointerManager->move(delta); g_pPointerManager->move(delta);
break; break;
} }
@ -205,12 +205,12 @@ void CInputManager::onTabletProximity(CTablet::SProximityEvent e) {
PROTO::idle->onActivity(); PROTO::idle->onActivity();
} }
void CInputManager::newTablet(wlr_input_device* pDevice) { void CInputManager::newTablet(SP<Aquamarine::ITablet> pDevice) {
const auto PNEWTABLET = m_vTablets.emplace_back(CTablet::create(wlr_tablet_from_input_device(pDevice))); const auto PNEWTABLET = m_vTablets.emplace_back(CTablet::create(pDevice));
m_vHIDs.push_back(PNEWTABLET); m_vHIDs.push_back(PNEWTABLET);
try { try {
PNEWTABLET->hlName = deviceNameToInternalString(pDevice->name); PNEWTABLET->hlName = deviceNameToInternalString(pDevice->getName());
} catch (std::exception& e) { } catch (std::exception& e) {
Debug::log(ERR, "Tablet had no name???"); // logic error Debug::log(ERR, "Tablet had no name???"); // logic error
} }
@ -227,28 +227,32 @@ void CInputManager::newTablet(wlr_input_device* pDevice) {
setTabletConfigs(); setTabletConfigs();
} }
SP<CTabletTool> CInputManager::ensureTabletToolPresent(wlr_tablet_tool* pTool) { SP<CTabletTool> CInputManager::ensureTabletToolPresent(SP<Aquamarine::ITabletTool> pTool) {
if (pTool->data == nullptr) {
const auto PTOOL = m_vTabletTools.emplace_back(CTabletTool::create(pTool));
m_vHIDs.push_back(PTOOL);
PTOOL->events.destroy.registerStaticListener( for (auto& t : m_vTabletTools) {
[this](void* owner, std::any d) { if (t->aq() == pTool)
auto TOOL = ((CTabletTool*)owner)->self; return t;
destroyTabletTool(TOOL.lock());
},
PTOOL.get());
} }
return CTabletTool::fromWlr(pTool); const auto PTOOL = m_vTabletTools.emplace_back(CTabletTool::create(pTool));
m_vHIDs.push_back(PTOOL);
PTOOL->events.destroy.registerStaticListener(
[this](void* owner, std::any d) {
auto TOOL = ((CTabletTool*)owner)->self;
destroyTabletTool(TOOL.lock());
},
PTOOL.get());
return PTOOL;
} }
void CInputManager::newTabletPad(wlr_input_device* pDevice) { void CInputManager::newTabletPad(SP<Aquamarine::ITabletPad> pDevice) {
const auto PNEWPAD = m_vTabletPads.emplace_back(CTabletPad::create(wlr_tablet_pad_from_input_device(pDevice))); const auto PNEWPAD = m_vTabletPads.emplace_back(CTabletPad::create(pDevice));
m_vHIDs.push_back(PNEWPAD); m_vHIDs.push_back(PNEWPAD);
try { try {
PNEWPAD->hlName = deviceNameToInternalString(pDevice->name); PNEWPAD->hlName = deviceNameToInternalString(pDevice->getName());
} catch (std::exception& e) { } catch (std::exception& e) {
Debug::log(ERR, "Pad had no name???"); // logic error Debug::log(ERR, "Pad had no name???"); // logic error
} }
@ -259,7 +263,7 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
destroyTabletPad(PAD.lock()); destroyTabletPad(PAD.lock());
}, PNEWPAD.get()); }, PNEWPAD.get());
PNEWPAD->padEvents.button.registerStaticListener([this](void* owner, std::any e) { PNEWPAD->padEvents.button.registerStaticListener([](void* owner, std::any e) {
const auto E = std::any_cast<CTabletPad::SButtonEvent>(e); const auto E = std::any_cast<CTabletPad::SButtonEvent>(e);
const auto PPAD = ((CTabletPad*)owner)->self.lock(); const auto PPAD = ((CTabletPad*)owner)->self.lock();
@ -267,26 +271,25 @@ void CInputManager::newTabletPad(wlr_input_device* pDevice) {
PROTO::tablet->buttonPad(PPAD, E.button, E.timeMs, E.down); PROTO::tablet->buttonPad(PPAD, E.button, E.timeMs, E.down);
}, PNEWPAD.get()); }, PNEWPAD.get());
PNEWPAD->padEvents.strip.registerStaticListener([this](void* owner, std::any e) { PNEWPAD->padEvents.strip.registerStaticListener([](void* owner, std::any e) {
const auto E = std::any_cast<CTabletPad::SStripEvent>(e); const auto E = std::any_cast<CTabletPad::SStripEvent>(e);
const auto PPAD = ((CTabletPad*)owner)->self.lock(); const auto PPAD = ((CTabletPad*)owner)->self.lock();
PROTO::tablet->strip(PPAD, E.strip, E.position, E.finger, E.timeMs); PROTO::tablet->strip(PPAD, E.strip, E.position, E.finger, E.timeMs);
}, PNEWPAD.get()); }, PNEWPAD.get());
PNEWPAD->padEvents.ring.registerStaticListener([this](void* owner, std::any e) { PNEWPAD->padEvents.ring.registerStaticListener([](void* owner, std::any e) {
const auto E = std::any_cast<CTabletPad::SRingEvent>(e); const auto E = std::any_cast<CTabletPad::SRingEvent>(e);
const auto PPAD = ((CTabletPad*)owner)->self.lock(); const auto PPAD = ((CTabletPad*)owner)->self.lock();
PROTO::tablet->ring(PPAD, E.ring, E.position, E.finger, E.timeMs); PROTO::tablet->ring(PPAD, E.ring, E.position, E.finger, E.timeMs);
}, PNEWPAD.get()); }, PNEWPAD.get());
PNEWPAD->padEvents.attach.registerStaticListener([this](void* owner, std::any e) { PNEWPAD->padEvents.attach.registerStaticListener([](void* owner, std::any e) {
const auto PPAD = ((CTabletPad*)owner)->self.lock(); const auto PPAD = ((CTabletPad*)owner)->self.lock();
const auto TOOL = std::any_cast<SP<CTabletTool>>(e); const auto TOOL = std::any_cast<SP<CTabletTool>>(e);
PPAD->parent = TOOL; PPAD->parent = TOOL;
}, PNEWPAD.get()); }, PNEWPAD.get());
// clang-format on // clang-format on
} }

View file

@ -44,17 +44,17 @@ bool CTabletPadGroupV2Resource::good() {
return resource->resource(); return resource->resource();
} }
void CTabletPadGroupV2Resource::sendData(SP<CTabletPad> pad, wlr_tablet_pad_group* group) { void CTabletPadGroupV2Resource::sendData(SP<CTabletPad> pad, SP<Aquamarine::ITabletPad::STabletPadGroup> group) {
resource->sendModes(group->mode_count); resource->sendModes(group->modes);
wl_array buttonArr; wl_array buttonArr;
wl_array_init(&buttonArr); wl_array_init(&buttonArr);
wl_array_add(&buttonArr, group->button_count * sizeof(int)); wl_array_add(&buttonArr, group->buttons.size() * sizeof(int));
memcpy(buttonArr.data, group->buttons, group->button_count * sizeof(int)); memcpy(buttonArr.data, group->buttons.data(), group->buttons.size() * sizeof(int));
resource->sendButtons(&buttonArr); resource->sendButtons(&buttonArr);
wl_array_release(&buttonArr); wl_array_release(&buttonArr);
for (size_t i = 0; i < group->strip_count; ++i) { for (size_t i = 0; i < group->strips.size(); ++i) {
const auto RESOURCE = const auto RESOURCE =
PROTO::tablet->m_vStrips.emplace_back(makeShared<CTabletPadStripV2Resource>(makeShared<CZwpTabletPadStripV2>(resource->client(), resource->version(), 0), i)); PROTO::tablet->m_vStrips.emplace_back(makeShared<CTabletPadStripV2Resource>(makeShared<CZwpTabletPadStripV2>(resource->client(), resource->version(), 0), i));
@ -67,7 +67,7 @@ void CTabletPadGroupV2Resource::sendData(SP<CTabletPad> pad, wlr_tablet_pad_grou
resource->sendStrip(RESOURCE->resource.get()); resource->sendStrip(RESOURCE->resource.get());
} }
for (size_t i = 0; i < group->ring_count; ++i) { for (size_t i = 0; i < group->rings.size(); ++i) {
const auto RESOURCE = const auto RESOURCE =
PROTO::tablet->m_vRings.emplace_back(makeShared<CTabletPadRingV2Resource>(makeShared<CZwpTabletPadRingV2>(resource->client(), resource->version(), 0), i)); PROTO::tablet->m_vRings.emplace_back(makeShared<CTabletPadRingV2Resource>(makeShared<CZwpTabletPadRingV2>(resource->client(), resource->version(), 0), i));
@ -97,23 +97,20 @@ bool CTabletPadV2Resource::good() {
void CTabletPadV2Resource::sendData() { void CTabletPadV2Resource::sendData() {
// this is dodgy as fuck. I hate wl_array. it's expanded wl_array_for_each because C++ would complain about the implicit casts // this is dodgy as fuck. I hate wl_array. it's expanded wl_array_for_each because C++ would complain about the implicit casts
const char** path_ptr; for (auto& p : pad->aq()->paths) {
for (path_ptr = (const char**)(&pad->wlr()->paths)->data; (const char*)path_ptr < ((const char*)(&pad->wlr()->paths)->data + (&pad->wlr()->paths)->size); (path_ptr)++) { resource->sendPath(p.c_str());
resource->sendPath(*path_ptr);
} }
resource->sendButtons(pad->wlr()->button_count); resource->sendButtons(pad->aq()->buttons);
wlr_tablet_pad_group* group; for (size_t i = 0; i < pad->aq()->groups.size(); ++i) {
size_t i = 0; createGroup(pad->aq()->groups.at(i), i);
wl_list_for_each(group, &pad->wlr()->groups, link) {
createGroup(group, i++);
} }
resource->sendDone(); resource->sendDone();
} }
void CTabletPadV2Resource::createGroup(wlr_tablet_pad_group* group, size_t idx) { void CTabletPadV2Resource::createGroup(SP<Aquamarine::ITabletPad::STabletPadGroup> group, size_t idx) {
const auto RESOURCE = const auto RESOURCE =
PROTO::tablet->m_vGroups.emplace_back(makeShared<CTabletPadGroupV2Resource>(makeShared<CZwpTabletPadGroupV2>(resource->client(), resource->version(), 0), idx)); PROTO::tablet->m_vGroups.emplace_back(makeShared<CTabletPadGroupV2Resource>(makeShared<CZwpTabletPadGroupV2>(resource->client(), resource->version(), 0), idx));
@ -142,13 +139,10 @@ bool CTabletV2Resource::good() {
void CTabletV2Resource::sendData() { void CTabletV2Resource::sendData() {
resource->sendName(tablet->deviceName.c_str()); resource->sendName(tablet->deviceName.c_str());
resource->sendId(tablet->wlr()->usb_vendor_id, tablet->wlr()->usb_product_id); resource->sendId(tablet->aq()->usbVendorID, tablet->aq()->usbProductID);
// this is dodgy as fuck. I hate wl_array. it's expanded wl_array_for_each because C++ would complain about the implicit casts for (auto& p : tablet->aq()->paths) {
const char** path_ptr; resource->sendPath(p.c_str());
for (path_ptr = (const char**)(&tablet->wlr()->paths)->data; (const char*)path_ptr < ((const char*)(&tablet->wlr()->paths)->data + (&tablet->wlr()->paths)->size);
(path_ptr)++) {
resource->sendPath(*path_ptr);
} }
resource->sendDone(); resource->sendDone();
@ -179,23 +173,23 @@ bool CTabletToolV2Resource::good() {
} }
void CTabletToolV2Resource::sendData() { void CTabletToolV2Resource::sendData() {
static auto WLR_TYPE_TO_PROTO = [](uint32_t wlr) -> zwpTabletToolV2Type { static auto AQ_TYPE_TO_PROTO = [](uint32_t aq) -> zwpTabletToolV2Type {
switch (wlr) { switch (aq) {
case WLR_TABLET_TOOL_TYPE_PEN: return ZWP_TABLET_TOOL_V2_TYPE_PEN; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_PEN: return ZWP_TABLET_TOOL_V2_TYPE_PEN;
case WLR_TABLET_TOOL_TYPE_ERASER: return ZWP_TABLET_TOOL_V2_TYPE_ERASER; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_ERASER: return ZWP_TABLET_TOOL_V2_TYPE_ERASER;
case WLR_TABLET_TOOL_TYPE_BRUSH: return ZWP_TABLET_TOOL_V2_TYPE_BRUSH; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_BRUSH: return ZWP_TABLET_TOOL_V2_TYPE_BRUSH;
case WLR_TABLET_TOOL_TYPE_PENCIL: return ZWP_TABLET_TOOL_V2_TYPE_PENCIL; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_PENCIL: return ZWP_TABLET_TOOL_V2_TYPE_PENCIL;
case WLR_TABLET_TOOL_TYPE_AIRBRUSH: return ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_AIRBRUSH: return ZWP_TABLET_TOOL_V2_TYPE_AIRBRUSH;
case WLR_TABLET_TOOL_TYPE_MOUSE: return ZWP_TABLET_TOOL_V2_TYPE_MOUSE; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_MOUSE: return ZWP_TABLET_TOOL_V2_TYPE_MOUSE;
case WLR_TABLET_TOOL_TYPE_LENS: return ZWP_TABLET_TOOL_V2_TYPE_LENS; case Aquamarine::ITabletTool::AQ_TABLET_TOOL_TYPE_LENS: return ZWP_TABLET_TOOL_V2_TYPE_LENS;
default: ASSERT(false); default: ASSERT(false);
} }
UNREACHABLE(); UNREACHABLE();
}; };
resource->sendType(WLR_TYPE_TO_PROTO(tool->wlr()->type)); resource->sendType(AQ_TYPE_TO_PROTO(tool->aq()->type));
resource->sendHardwareSerial(tool->wlr()->hardware_serial >> 32, tool->wlr()->hardware_serial & 0xFFFFFFFF); resource->sendHardwareSerial(tool->aq()->serial >> 32, tool->aq()->serial & 0xFFFFFFFF);
resource->sendHardwareIdWacom(tool->wlr()->hardware_wacom >> 32, tool->wlr()->hardware_wacom & 0xFFFFFFFF); resource->sendHardwareIdWacom(tool->aq()->id >> 32, tool->aq()->id & 0xFFFFFFFF);
if (tool->toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_DISTANCE) if (tool->toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_DISTANCE)
resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE); resource->sendCapability(zwpTabletToolV2Capability::ZWP_TABLET_TOOL_V2_CAPABILITY_DISTANCE);
if (tool->toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_PRESSURE) if (tool->toolCapabilities & CTabletTool::eTabletToolCapabilities::HID_TABLET_TOOL_CAPABILITY_PRESSURE)

View file

@ -6,6 +6,7 @@
#include "WaylandProtocol.hpp" #include "WaylandProtocol.hpp"
#include "tablet-v2.hpp" #include "tablet-v2.hpp"
#include "../helpers/math/Math.hpp" #include "../helpers/math/Math.hpp"
#include <aquamarine/input/Input.hpp>
class CTablet; class CTablet;
class CTabletTool; class CTabletTool;
@ -51,7 +52,7 @@ class CTabletPadGroupV2Resource {
CTabletPadGroupV2Resource(SP<CZwpTabletPadGroupV2> resource_, size_t idx); CTabletPadGroupV2Resource(SP<CZwpTabletPadGroupV2> resource_, size_t idx);
bool good(); bool good();
void sendData(SP<CTabletPad> pad, wlr_tablet_pad_group* group); void sendData(SP<CTabletPad> pad, SP<Aquamarine::ITabletPad::STabletPadGroup> group);
std::vector<WP<CTabletPadRingV2Resource>> rings; std::vector<WP<CTabletPadRingV2Resource>> rings;
std::vector<WP<CTabletPadStripV2Resource>> strips; std::vector<WP<CTabletPadStripV2Resource>> strips;
@ -83,7 +84,7 @@ class CTabletPadV2Resource {
private: private:
SP<CZwpTabletPadV2> resource; SP<CZwpTabletPadV2> resource;
void createGroup(wlr_tablet_pad_group* group, size_t idx); void createGroup(SP<Aquamarine::ITabletPad::STabletPadGroup> group, size_t idx);
friend class CTabletSeat; friend class CTabletSeat;
friend class CTabletV2Protocol; friend class CTabletV2Protocol;