mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-12-22 20:39:49 +01:00
session: Tablet support
woo
This commit is contained in:
parent
a0cfad9ec0
commit
f48653cf0e
9 changed files with 564 additions and 34 deletions
|
@ -11,13 +11,13 @@
|
|||
#include "Session.hpp"
|
||||
|
||||
namespace Aquamarine {
|
||||
enum eBackendType {
|
||||
enum eBackendType : uint32_t {
|
||||
AQ_BACKEND_WAYLAND = 0,
|
||||
AQ_BACKEND_DRM,
|
||||
AQ_BACKEND_HEADLESS,
|
||||
};
|
||||
|
||||
enum eBackendRequestMode {
|
||||
enum eBackendRequestMode : uint32_t {
|
||||
/*
|
||||
Require the provided backend, will error out if it's not available.
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@ namespace Aquamarine {
|
|||
AQ_BACKEND_REQUEST_FALLBACK,
|
||||
};
|
||||
|
||||
enum eBackendLogLevel {
|
||||
enum eBackendLogLevel : uint32_t {
|
||||
AQ_LOG_TRACE = 0,
|
||||
AQ_LOG_DEBUG,
|
||||
AQ_LOG_WARNING,
|
||||
|
|
|
@ -13,6 +13,7 @@ struct libseat;
|
|||
struct libinput;
|
||||
struct libinput_event;
|
||||
struct libinput_device;
|
||||
struct libinput_tablet_tool;
|
||||
|
||||
namespace Aquamarine {
|
||||
class CBackend;
|
||||
|
@ -34,7 +35,7 @@ namespace Aquamarine {
|
|||
dev_t dev;
|
||||
std::string path;
|
||||
|
||||
enum eChangeEventType {
|
||||
enum eChangeEventType : uint32_t {
|
||||
AQ_SESSION_EVENT_CHANGE_HOTPLUG = 0,
|
||||
AQ_SESSION_EVENT_CHANGE_LEASE,
|
||||
};
|
||||
|
@ -69,6 +70,8 @@ namespace Aquamarine {
|
|||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputMouse : public IPointer {
|
||||
|
@ -83,6 +86,8 @@ namespace Aquamarine {
|
|||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputTouch : public ITouch {
|
||||
|
@ -97,6 +102,8 @@ namespace Aquamarine {
|
|||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputSwitch : public ISwitch {
|
||||
|
@ -114,6 +121,55 @@ namespace Aquamarine {
|
|||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputTablet : public ITablet {
|
||||
public:
|
||||
CLibinputTablet(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev);
|
||||
virtual ~CLibinputTablet() {
|
||||
;
|
||||
}
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName();
|
||||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputTabletTool : public ITabletTool {
|
||||
public:
|
||||
CLibinputTabletTool(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev, libinput_tablet_tool* tool);
|
||||
virtual ~CLibinputTabletTool();
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName();
|
||||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
libinput_tablet_tool* libinputTool = nullptr;
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputTabletPad : public ITabletPad {
|
||||
public:
|
||||
CLibinputTabletPad(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev);
|
||||
virtual ~CLibinputTabletPad();
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName();
|
||||
|
||||
private:
|
||||
Hyprutils::Memory::CWeakPointer<CLibinputDevice> device;
|
||||
|
||||
Hyprutils::Memory::CSharedPointer<ITabletPad::STabletPadGroup> createGroupFromID(int id);
|
||||
|
||||
friend class CLibinputDevice;
|
||||
};
|
||||
|
||||
class CLibinputDevice {
|
||||
|
@ -132,6 +188,11 @@ namespace Aquamarine {
|
|||
Hyprutils::Memory::CSharedPointer<CLibinputMouse> mouse;
|
||||
Hyprutils::Memory::CSharedPointer<CLibinputTouch> touch;
|
||||
Hyprutils::Memory::CSharedPointer<CLibinputSwitch> switchy; // :)
|
||||
Hyprutils::Memory::CSharedPointer<CLibinputTablet> tablet;
|
||||
Hyprutils::Memory::CSharedPointer<CLibinputTabletPad> tabletPad;
|
||||
std::vector<Hyprutils::Memory::CSharedPointer<CLibinputTabletTool>> tabletTools;
|
||||
|
||||
Hyprutils::Memory::CSharedPointer<CLibinputTabletTool> toolFrom(libinput_tablet_tool* tool);
|
||||
};
|
||||
|
||||
class CSession {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
#include "../misc/Attachment.hpp"
|
||||
|
||||
namespace Aquamarine {
|
||||
enum eBufferCapability {
|
||||
enum eBufferCapability : uint32_t {
|
||||
BUFFER_CAPABILITY_DATAPTR = (1 << 0),
|
||||
};
|
||||
|
||||
enum eBufferType {
|
||||
enum eBufferType : uint32_t {
|
||||
BUFFER_TYPE_DMABUF = 0,
|
||||
BUFFER_TYPE_SHM,
|
||||
BUFFER_TYPE_MISC,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
struct libinput_device;
|
||||
|
||||
namespace Aquamarine {
|
||||
class ITabletTool;
|
||||
|
||||
class IKeyboard {
|
||||
public:
|
||||
virtual ~IKeyboard() {
|
||||
|
@ -41,19 +43,19 @@ namespace Aquamarine {
|
|||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName() = 0;
|
||||
|
||||
enum ePointerAxis {
|
||||
enum ePointerAxis : uint32_t {
|
||||
AQ_POINTER_AXIS_VERTICAL = 0,
|
||||
AQ_POINTER_AXIS_HORIZONTAL,
|
||||
};
|
||||
|
||||
enum ePointerAxisSource {
|
||||
enum ePointerAxisSource : uint32_t {
|
||||
AQ_POINTER_AXIS_SOURCE_WHEEL = 0,
|
||||
AQ_POINTER_AXIS_SOURCE_FINGER,
|
||||
AQ_POINTER_AXIS_SOURCE_CONTINUOUS,
|
||||
AQ_POINTER_AXIS_SOURCE_TILT,
|
||||
};
|
||||
|
||||
enum ePointerAxisRelativeDirection {
|
||||
enum ePointerAxisRelativeDirection : uint32_t {
|
||||
AQ_POINTER_AXIS_RELATIVE_IDENTICAL = 0,
|
||||
AQ_POINTER_AXIS_RELATIVE_INVERTED,
|
||||
};
|
||||
|
@ -198,7 +200,7 @@ namespace Aquamarine {
|
|||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName() = 0;
|
||||
|
||||
enum eSwitchType {
|
||||
enum eSwitchType : uint32_t {
|
||||
AQ_SWITCH_TYPE_UNKNOWN = 0,
|
||||
AQ_SWITCH_TYPE_LID,
|
||||
AQ_SWITCH_TYPE_TABLET_MODE,
|
||||
|
@ -216,18 +218,107 @@ namespace Aquamarine {
|
|||
} events;
|
||||
};
|
||||
|
||||
enum eTabletToolAxes : uint32_t {
|
||||
AQ_TABLET_TOOL_AXIS_X = (1 << 0),
|
||||
AQ_TABLET_TOOL_AXIS_Y = (1 << 1),
|
||||
AQ_TABLET_TOOL_AXIS_DISTANCE = (1 << 2),
|
||||
AQ_TABLET_TOOL_AXIS_PRESSURE = (1 << 3),
|
||||
AQ_TABLET_TOOL_AXIS_TILT_X = (1 << 4),
|
||||
AQ_TABLET_TOOL_AXIS_TILT_Y = (1 << 5),
|
||||
AQ_TABLET_TOOL_AXIS_ROTATION = (1 << 6),
|
||||
AQ_TABLET_TOOL_AXIS_SLIDER = (1 << 7),
|
||||
AQ_TABLET_TOOL_AXIS_WHEEL = (1 << 8),
|
||||
};
|
||||
|
||||
class ITablet {
|
||||
public:
|
||||
// FIXME:
|
||||
virtual ~ITablet() {
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName() = 0;
|
||||
|
||||
uint16_t usbVendorID = 0, usbProductID = 0;
|
||||
Hyprutils::Math::Vector2D physicalSize; // mm
|
||||
std::vector<std::string> paths;
|
||||
|
||||
struct SAxisEvent {
|
||||
Hyprutils::Memory::CSharedPointer<ITabletTool> tool;
|
||||
|
||||
uint32_t timeMs = 0, updatedAxes = 0;
|
||||
Hyprutils::Math::Vector2D absolute;
|
||||
Hyprutils::Math::Vector2D delta;
|
||||
Hyprutils::Math::Vector2D tilt;
|
||||
double pressure = 0.0, distance = 0.0, rotation = 0.0, slider = 0.0, wheelDelta = 0.0;
|
||||
};
|
||||
|
||||
struct SProximityEvent {
|
||||
Hyprutils::Memory::CSharedPointer<ITabletTool> tool;
|
||||
|
||||
uint32_t timeMs = 0;
|
||||
Hyprutils::Math::Vector2D absolute;
|
||||
bool in = false;
|
||||
};
|
||||
|
||||
struct STipEvent {
|
||||
Hyprutils::Memory::CSharedPointer<ITabletTool> tool;
|
||||
|
||||
uint32_t timeMs = 0;
|
||||
Hyprutils::Math::Vector2D absolute;
|
||||
bool down = false;
|
||||
};
|
||||
|
||||
struct SButtonEvent {
|
||||
Hyprutils::Memory::CSharedPointer<ITabletTool> tool;
|
||||
|
||||
uint32_t timeMs = 0, button = 0;
|
||||
bool down = false;
|
||||
};
|
||||
|
||||
struct {
|
||||
Hyprutils::Signal::CSignal axis;
|
||||
Hyprutils::Signal::CSignal proximity;
|
||||
Hyprutils::Signal::CSignal tip;
|
||||
Hyprutils::Signal::CSignal button;
|
||||
Hyprutils::Signal::CSignal destroy;
|
||||
} events;
|
||||
};
|
||||
|
||||
class ITabletTool {
|
||||
public:
|
||||
// FIXME:
|
||||
virtual ~ITabletTool() {
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName() = 0;
|
||||
|
||||
enum eTabletToolType : uint32_t {
|
||||
AQ_TABLET_TOOL_TYPE_INVALID = 0,
|
||||
AQ_TABLET_TOOL_TYPE_PEN,
|
||||
AQ_TABLET_TOOL_TYPE_ERASER,
|
||||
AQ_TABLET_TOOL_TYPE_BRUSH,
|
||||
AQ_TABLET_TOOL_TYPE_PENCIL,
|
||||
AQ_TABLET_TOOL_TYPE_AIRBRUSH,
|
||||
AQ_TABLET_TOOL_TYPE_MOUSE,
|
||||
AQ_TABLET_TOOL_TYPE_LENS,
|
||||
AQ_TABLET_TOOL_TYPE_TOTEM,
|
||||
};
|
||||
|
||||
eTabletToolType type = AQ_TABLET_TOOL_TYPE_INVALID;
|
||||
uint64_t serial = 0, id = 0;
|
||||
|
||||
enum eTabletToolCapabilities : uint32_t {
|
||||
AQ_TABLET_TOOL_CAPABILITY_TILT = (1 << 0),
|
||||
AQ_TABLET_TOOL_CAPABILITY_PRESSURE = (1 << 1),
|
||||
AQ_TABLET_TOOL_CAPABILITY_DISTANCE = (1 << 2),
|
||||
AQ_TABLET_TOOL_CAPABILITY_ROTATION = (1 << 3),
|
||||
AQ_TABLET_TOOL_CAPABILITY_SLIDER = (1 << 4),
|
||||
AQ_TABLET_TOOL_CAPABILITY_WHEEL = (1 << 5),
|
||||
};
|
||||
|
||||
uint32_t capabilities = 0; // enum eTabletToolCapabilities
|
||||
|
||||
struct {
|
||||
Hyprutils::Signal::CSignal destroy;
|
||||
|
@ -236,10 +327,63 @@ namespace Aquamarine {
|
|||
|
||||
class ITabletPad {
|
||||
public:
|
||||
// FIXME:
|
||||
virtual ~ITabletPad() {
|
||||
events.destroy.emit();
|
||||
}
|
||||
|
||||
struct STabletPadGroup {
|
||||
std::vector<uint32_t> buttons, strips, rings;
|
||||
uint16_t modes = 0;
|
||||
};
|
||||
|
||||
virtual libinput_device* getLibinputHandle();
|
||||
virtual const std::string& getName() = 0;
|
||||
|
||||
uint16_t buttons = 0, rings = 0, strips = 0;
|
||||
|
||||
std::vector<std::string> paths;
|
||||
std::vector<Hyprutils::Memory::CSharedPointer<STabletPadGroup>> groups;
|
||||
|
||||
//
|
||||
|
||||
struct SButtonEvent {
|
||||
uint32_t timeMs = 0, button = 0;
|
||||
bool down = false;
|
||||
uint16_t mode = 0, group = 0;
|
||||
};
|
||||
|
||||
enum eTabletPadRingSource : uint16_t {
|
||||
AQ_TABLET_PAD_RING_SOURCE_UNKNOWN = 0,
|
||||
AQ_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
};
|
||||
|
||||
enum eTabletPadStripSource : uint16_t {
|
||||
AQ_TABLET_PAD_STRIP_SOURCE_UNKNOWN = 0,
|
||||
AQ_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
};
|
||||
|
||||
struct SRingEvent {
|
||||
uint32_t timeMs = 0;
|
||||
eTabletPadRingSource source = AQ_TABLET_PAD_RING_SOURCE_UNKNOWN;
|
||||
uint16_t ring = 0;
|
||||
double pos = 0.0;
|
||||
uint16_t mode = 0;
|
||||
};
|
||||
|
||||
struct SStripEvent {
|
||||
uint32_t timeMs = 0;
|
||||
eTabletPadStripSource source = AQ_TABLET_PAD_STRIP_SOURCE_UNKNOWN;
|
||||
uint16_t strip = 0;
|
||||
double pos = 0.0;
|
||||
uint16_t mode = 0;
|
||||
};
|
||||
|
||||
struct {
|
||||
Hyprutils::Signal::CSignal destroy;
|
||||
Hyprutils::Signal::CSignal button;
|
||||
Hyprutils::Signal::CSignal ring;
|
||||
Hyprutils::Signal::CSignal strip;
|
||||
Hyprutils::Signal::CSignal attach;
|
||||
} events;
|
||||
};
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#include <hyprutils/memory/SharedPtr.hpp>
|
||||
|
||||
namespace Aquamarine {
|
||||
enum eAttachmentType {
|
||||
enum eAttachmentType : uint32_t {
|
||||
AQ_ATTACHMENT_DRM_BUFFER = 0,
|
||||
AQ_ATTACHMENT_DRM_KMS_UNIMPORTABLE,
|
||||
};
|
||||
|
|
|
@ -21,12 +21,12 @@ namespace Aquamarine {
|
|||
std::optional<drmModeModeInfo> modeInfo; // if this is a drm mode, this will be populated.
|
||||
};
|
||||
|
||||
enum eOutputPresentationMode {
|
||||
enum eOutputPresentationMode : uint32_t {
|
||||
AQ_OUTPUT_PRESENTATION_VSYNC = 0,
|
||||
AQ_OUTPUT_PRESENTATION_IMMEDIATE, // likely tearing
|
||||
};
|
||||
|
||||
enum eSubpixelMode {
|
||||
enum eSubpixelMode : uint32_t {
|
||||
AQ_SUBPIXEL_UNKNOWN = 0,
|
||||
AQ_SUBPIXEL_NONE,
|
||||
AQ_SUBPIXEL_HORIZONTAL_RGB,
|
||||
|
|
|
@ -8,6 +8,7 @@ extern "C" {
|
|||
#include <xf86drm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <linux/input.h>
|
||||
}
|
||||
|
||||
using namespace Aquamarine;
|
||||
|
@ -270,8 +271,14 @@ void Aquamarine::CSession::onReady() {
|
|||
backend->events.newTouch.emit(SP<ITouch>(d->touch));
|
||||
if (d->switchy)
|
||||
backend->events.newSwitch.emit(SP<ITouch>(d->touch));
|
||||
if (d->tablet)
|
||||
backend->events.newTablet.emit(SP<ITablet>(d->tablet));
|
||||
if (d->tabletPad)
|
||||
backend->events.newTabletPad.emit(SP<ITabletPad>(d->tabletPad));
|
||||
|
||||
// FIXME: other devices.
|
||||
for (auto& t : d->tabletTools) {
|
||||
backend->events.newTabletTool.emit(SP<ITabletTool>(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,6 +408,7 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
|
|||
}
|
||||
|
||||
auto hlDevice = ((CLibinputDevice*)data)->self.lock();
|
||||
bool destroyTool = false;
|
||||
|
||||
switch (eventType) {
|
||||
case LIBINPUT_EVENT_DEVICE_ADDED:
|
||||
|
@ -640,7 +648,145 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
|
|||
|
||||
// --------- tbalet
|
||||
|
||||
// FIXME: other events
|
||||
case LIBINPUT_EVENT_TABLET_PAD_BUTTON: {
|
||||
auto tpe = libinput_event_get_tablet_pad_event(e);
|
||||
|
||||
hlDevice->tabletPad->events.button.emit(ITabletPad::SButtonEvent{
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_pad_get_time_usec(tpe) / 1000),
|
||||
.button = libinput_event_tablet_pad_get_button_number(tpe),
|
||||
.down = libinput_event_tablet_pad_get_button_state(tpe) == LIBINPUT_BUTTON_STATE_PRESSED,
|
||||
.mode = (uint16_t)libinput_event_tablet_pad_get_mode(tpe),
|
||||
.group = (uint16_t)libinput_tablet_pad_mode_group_get_index(libinput_event_tablet_pad_get_mode_group(tpe)),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_RING: {
|
||||
auto tpe = libinput_event_get_tablet_pad_event(e);
|
||||
|
||||
hlDevice->tabletPad->events.ring.emit(ITabletPad::SRingEvent{
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_pad_get_time_usec(tpe) / 1000),
|
||||
.source = libinput_event_tablet_pad_get_ring_source(tpe) == LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN ? ITabletPad::AQ_TABLET_PAD_RING_SOURCE_UNKNOWN :
|
||||
ITabletPad::AQ_TABLET_PAD_RING_SOURCE_FINGER,
|
||||
.ring = (uint16_t)libinput_event_tablet_pad_get_ring_number(tpe),
|
||||
.pos = libinput_event_tablet_pad_get_ring_position(tpe),
|
||||
.mode = (uint16_t)libinput_event_tablet_pad_get_mode(tpe),
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_STRIP: {
|
||||
auto tpe = libinput_event_get_tablet_pad_event(e);
|
||||
|
||||
hlDevice->tabletPad->events.strip.emit(ITabletPad::SStripEvent{
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_pad_get_time_usec(tpe) / 1000),
|
||||
.source = libinput_event_tablet_pad_get_strip_source(tpe) == LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN ? ITabletPad::AQ_TABLET_PAD_STRIP_SOURCE_UNKNOWN :
|
||||
ITabletPad::AQ_TABLET_PAD_STRIP_SOURCE_FINGER,
|
||||
.strip = (uint16_t)libinput_event_tablet_pad_get_strip_number(tpe),
|
||||
.pos = libinput_event_tablet_pad_get_strip_position(tpe),
|
||||
.mode = (uint16_t)libinput_event_tablet_pad_get_mode(tpe),
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: {
|
||||
auto tte = libinput_event_get_tablet_tool_event(e);
|
||||
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
|
||||
|
||||
hlDevice->tablet->events.proximity.emit(ITablet::SProximityEvent{
|
||||
.tool = tool,
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
|
||||
.absolute = {libinput_event_tablet_tool_get_x_transformed(tte, 1), libinput_event_tablet_tool_get_y_transformed(tte, 1)},
|
||||
.in = libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
|
||||
});
|
||||
|
||||
destroyTool = !libinput_tablet_tool_is_unique(libinput_event_tablet_tool_get_tool(tte)) &&
|
||||
libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT;
|
||||
|
||||
if (libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) {
|
||||
std::erase(hlDevice->tabletTools, tool);
|
||||
break;
|
||||
}
|
||||
|
||||
// fallthrough. If this is proximity in, also process axis.
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_AXIS: {
|
||||
auto tte = libinput_event_get_tablet_tool_event(e);
|
||||
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
|
||||
|
||||
ITablet::SAxisEvent event = {
|
||||
.tool = tool,
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
|
||||
};
|
||||
|
||||
if (libinput_event_tablet_tool_x_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_X;
|
||||
event.absolute.x = libinput_event_tablet_tool_get_x_transformed(tte, 1);
|
||||
event.delta.x = libinput_event_tablet_tool_get_dx(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_y_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_Y;
|
||||
event.absolute.y = libinput_event_tablet_tool_get_y_transformed(tte, 1);
|
||||
event.delta.y = libinput_event_tablet_tool_get_dy(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_pressure_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_PRESSURE;
|
||||
event.pressure = libinput_event_tablet_tool_get_pressure(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_distance_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_DISTANCE;
|
||||
event.distance = libinput_event_tablet_tool_get_distance(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_tilt_x_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_TILT_X;
|
||||
event.tilt.x = libinput_event_tablet_tool_get_tilt_x(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_tilt_y_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_TILT_Y;
|
||||
event.tilt.y = libinput_event_tablet_tool_get_tilt_y(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_rotation_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_ROTATION;
|
||||
event.rotation = libinput_event_tablet_tool_get_rotation(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_slider_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_SLIDER;
|
||||
event.slider = libinput_event_tablet_tool_get_slider_position(tte);
|
||||
}
|
||||
if (libinput_event_tablet_tool_wheel_has_changed(tte)) {
|
||||
event.updatedAxes |= AQ_TABLET_TOOL_AXIS_WHEEL;
|
||||
event.wheelDelta = libinput_event_tablet_tool_get_wheel_delta(tte);
|
||||
}
|
||||
|
||||
hlDevice->tablet->events.axis.emit(event);
|
||||
|
||||
if (destroyTool)
|
||||
std::erase(hlDevice->tabletTools, tool);
|
||||
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
|
||||
auto tte = libinput_event_get_tablet_tool_event(e);
|
||||
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
|
||||
|
||||
hlDevice->tablet->events.tip.emit(ITablet::STipEvent{
|
||||
.tool = tool,
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
|
||||
.absolute = {libinput_event_tablet_tool_get_x_transformed(tte, 1), libinput_event_tablet_tool_get_y_transformed(tte, 1)},
|
||||
.down = libinput_event_tablet_tool_get_tip_state(tte) == LIBINPUT_TABLET_TOOL_TIP_DOWN,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
|
||||
auto tte = libinput_event_get_tablet_tool_event(e);
|
||||
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
|
||||
|
||||
hlDevice->tablet->events.button.emit(ITablet::SButtonEvent{
|
||||
.tool = tool,
|
||||
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
|
||||
.button = libinput_event_tablet_tool_get_button(tte),
|
||||
.down = libinput_event_tablet_tool_get_button_state(tte) == LIBINPUT_BUTTON_STATE_PRESSED,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
@ -686,13 +832,50 @@ void Aquamarine::CLibinputDevice::init() {
|
|||
session->backend->events.newSwitch.emit(SP<ISwitch>(switchy));
|
||||
}
|
||||
|
||||
// FIXME: other devices
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_TOOL)) {
|
||||
tablet = makeShared<CLibinputTablet>(self.lock());
|
||||
if (session->backend->ready)
|
||||
session->backend->events.newTablet.emit(SP<ITablet>(tablet));
|
||||
}
|
||||
|
||||
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD)) {
|
||||
tabletPad = makeShared<CLibinputTabletPad>(self.lock());
|
||||
if (session->backend->ready)
|
||||
session->backend->events.newTabletPad.emit(SP<ITabletPad>(tabletPad));
|
||||
}
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputDevice::~CLibinputDevice() {
|
||||
libinput_device_unref(device);
|
||||
}
|
||||
|
||||
SP<CLibinputTabletTool> Aquamarine::CLibinputDevice::toolFrom(libinput_tablet_tool* tool) {
|
||||
for (auto& t : tabletTools) {
|
||||
if (t->libinputTool == tool)
|
||||
return t;
|
||||
}
|
||||
|
||||
auto newt = makeShared<CLibinputTabletTool>(self.lock(), tool);
|
||||
tabletTools.emplace_back(newt);
|
||||
if (session->backend->ready)
|
||||
session->backend->events.newTabletTool.emit(SP<ITabletTool>(newt));
|
||||
return newt;
|
||||
}
|
||||
|
||||
static ITabletTool::eTabletToolType aqTypeFromLibinput(libinput_tablet_tool_type value) {
|
||||
switch (value) {
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_PEN: return ITabletTool::AQ_TABLET_TOOL_TYPE_PEN;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_ERASER: return ITabletTool::AQ_TABLET_TOOL_TYPE_ERASER;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_BRUSH: return ITabletTool::AQ_TABLET_TOOL_TYPE_BRUSH;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_PENCIL: return ITabletTool::AQ_TABLET_TOOL_TYPE_PENCIL;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_AIRBRUSH: return ITabletTool::AQ_TABLET_TOOL_TYPE_AIRBRUSH;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_MOUSE: return ITabletTool::AQ_TABLET_TOOL_TYPE_MOUSE;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_LENS: return ITabletTool::AQ_TABLET_TOOL_TYPE_LENS;
|
||||
case LIBINPUT_TABLET_TOOL_TYPE_TOTEM: return ITabletTool::AQ_TABLET_TOOL_TYPE_TOTEM;
|
||||
}
|
||||
return ITabletTool::AQ_TABLET_TOOL_TYPE_INVALID;
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputKeyboard::CLibinputKeyboard(SP<CLibinputDevice> dev) : device(dev) {}
|
||||
|
||||
libinput_device* Aquamarine::CLibinputKeyboard::getLibinputHandle() {
|
||||
|
@ -760,3 +943,135 @@ const std::string& Aquamarine::CLibinputSwitch::getName() {
|
|||
return AQ_UNKNOWN_DEVICE_NAME;
|
||||
return device->name;
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputTablet::CLibinputTablet(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev) : device(dev) {
|
||||
if (libinput_device_get_id_bustype(device->device) == BUS_USB) {
|
||||
usbVendorID = libinput_device_get_id_vendor(device->device);
|
||||
usbProductID = libinput_device_get_id_product(device->device);
|
||||
}
|
||||
|
||||
double w = 0, h = 0;
|
||||
libinput_device_get_size(dev->device, &w, &h);
|
||||
physicalSize = {w, h};
|
||||
|
||||
auto udevice = libinput_device_get_udev_device(device->device);
|
||||
paths.emplace_back(udev_device_get_syspath(udevice));
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::CLibinputTablet::getLibinputHandle() {
|
||||
if (!device)
|
||||
return nullptr;
|
||||
return device->device;
|
||||
}
|
||||
|
||||
const std::string& Aquamarine::CLibinputTablet::getName() {
|
||||
if (!device)
|
||||
return AQ_UNKNOWN_DEVICE_NAME;
|
||||
return device->name;
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputTabletTool::CLibinputTabletTool(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev, libinput_tablet_tool* tool) : device(dev), libinputTool(tool) {
|
||||
type = aqTypeFromLibinput(libinput_tablet_tool_get_type(libinputTool));
|
||||
serial = libinput_tablet_tool_get_serial(libinputTool);
|
||||
id = libinput_tablet_tool_get_tool_id(libinputTool);
|
||||
|
||||
libinput_tablet_tool_ref(tool);
|
||||
|
||||
capabilities = 0;
|
||||
if (libinput_tablet_tool_has_distance(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_DISTANCE;
|
||||
if (libinput_tablet_tool_has_pressure(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_PRESSURE;
|
||||
if (libinput_tablet_tool_has_tilt(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_TILT;
|
||||
if (libinput_tablet_tool_has_rotation(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_ROTATION;
|
||||
if (libinput_tablet_tool_has_slider(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_SLIDER;
|
||||
if (libinput_tablet_tool_has_wheel(tool))
|
||||
capabilities |= AQ_TABLET_TOOL_CAPABILITY_WHEEL;
|
||||
|
||||
libinput_tablet_tool_set_user_data(tool, this);
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputTabletTool::~CLibinputTabletTool() {
|
||||
libinput_tablet_tool_unref(libinputTool);
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::CLibinputTabletTool::getLibinputHandle() {
|
||||
if (!device)
|
||||
return nullptr;
|
||||
return device->device;
|
||||
}
|
||||
|
||||
const std::string& Aquamarine::CLibinputTabletTool::getName() {
|
||||
if (!device)
|
||||
return AQ_UNKNOWN_DEVICE_NAME;
|
||||
return device->name;
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputTabletPad::CLibinputTabletPad(Hyprutils::Memory::CSharedPointer<CLibinputDevice> dev) : device(dev) {
|
||||
buttons = libinput_device_tablet_pad_get_num_buttons(device->device);
|
||||
rings = libinput_device_tablet_pad_get_num_rings(device->device);
|
||||
strips = libinput_device_tablet_pad_get_num_strips(device->device);
|
||||
|
||||
auto udevice = libinput_device_get_udev_device(device->device);
|
||||
paths.emplace_back(udev_device_get_syspath(udevice));
|
||||
|
||||
int groupsno = libinput_device_tablet_pad_get_num_mode_groups(device->device);
|
||||
for (size_t i = 0; i < groupsno; ++i) {
|
||||
auto g = createGroupFromID(i);
|
||||
if (g)
|
||||
groups.emplace_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
Aquamarine::CLibinputTabletPad::~CLibinputTabletPad() {
|
||||
int groups = libinput_device_tablet_pad_get_num_mode_groups(device->device);
|
||||
for (int i = 0; i < groups; ++i) {
|
||||
auto g = libinput_device_tablet_pad_get_mode_group(device->device, i);
|
||||
libinput_tablet_pad_mode_group_unref(g);
|
||||
}
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::CLibinputTabletPad::getLibinputHandle() {
|
||||
if (!device)
|
||||
return nullptr;
|
||||
return device->device;
|
||||
}
|
||||
|
||||
const std::string& Aquamarine::CLibinputTabletPad::getName() {
|
||||
if (!device)
|
||||
return AQ_UNKNOWN_DEVICE_NAME;
|
||||
return device->name;
|
||||
}
|
||||
|
||||
SP<ITabletPad::STabletPadGroup> Aquamarine::CLibinputTabletPad::createGroupFromID(int id) {
|
||||
auto libinputGroup = libinput_device_tablet_pad_get_mode_group(device->device, id);
|
||||
|
||||
auto group = makeShared<STabletPadGroup>();
|
||||
for (size_t i = 0; i < rings; ++i) {
|
||||
if (!libinput_tablet_pad_mode_group_has_ring(libinputGroup, i))
|
||||
continue;
|
||||
|
||||
group->rings.push_back(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < strips; ++i) {
|
||||
if (!libinput_tablet_pad_mode_group_has_strip(libinputGroup, i))
|
||||
continue;
|
||||
|
||||
group->strips.push_back(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < buttons; ++i) {
|
||||
if (!libinput_tablet_pad_mode_group_has_button(libinputGroup, i))
|
||||
continue;
|
||||
|
||||
group->buttons.push_back(i);
|
||||
}
|
||||
|
||||
group->modes = libinput_tablet_pad_mode_group_get_num_modes(libinputGroup);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,18 @@ libinput_device* Aquamarine::ISwitch::getLibinputHandle() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::ITabletTool::getLibinputHandle() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::ITablet::getLibinputHandle() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
libinput_device* Aquamarine::ITabletPad::getLibinputHandle() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Aquamarine::IKeyboard::updateLEDs(uint32_t leds) {
|
||||
;
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ bool Aquamarine::envEnabled(const std::string& env) {
|
|||
return e && e == std::string{"1"};
|
||||
}
|
||||
|
||||
static bool trace = []() -> bool {
|
||||
return Aquamarine::envEnabled("AQ_TRACE");
|
||||
}();
|
||||
static bool trace = []() -> bool { return Aquamarine::envEnabled("AQ_TRACE"); }();
|
||||
|
||||
bool Aquamarine::isTrace() {
|
||||
return trace;
|
||||
|
|
Loading…
Reference in a new issue