14#include "qwayland-server-tablet-unstable-v2.h"
22static int s_version = 1;
40 Resource *r = resourceMap().value(*client);
41 return r ? r->handle :
nullptr;
52TabletV2Interface::TabletV2Interface(uint32_t vendorId, uint32_t productId,
const QString &name,
const QStringList &paths, QObject *parent)
60 const auto tabletResources = d->resourceMap();
61 for (TabletV2InterfacePrivate::Resource *resource : tabletResources) {
62 d->send_removed(resource->handle);
68 return d->resourceForSurface(surface);
103TabletSurfaceCursorV2::TabletSurfaceCursorV2()
136 const QList<TabletToolV2Interface::Capability> &capabilities)
137 : zwp_tablet_tool_v2()
149 std::ranges::subrange<QMultiMap<struct ::wl_client *, Resource *>::const_iterator>
targetResources()
const
155 const auto [start, end] = resourceMap().equal_range(*client);
156 return std::ranges::subrange(start, end);
179 static SurfaceRole cursorRole(QByteArrayLiteral(
"tablet_cursor_v2"));
181 if (role != &cursorRole) {
182 wl_resource_post_error(resource->handle, 0,
183 "the wl_surface already has a role assigned %s", role->name().constData());
192 c->d->update(serial, surface, {hotspot_x, hotspot_y});
194 if (std::any_of(resources.begin(), resources.end(), [resource](
const Resource *res) {
195 return res->handle == resource->handle;
203 if (!resourceMap().contains(resource->client())) {
204 delete m_cursors.take(resource->client());
206 if (
m_removed && resourceMap().isEmpty()) {
213 wl_resource_destroy(resource->handle);
231TabletToolV2Interface::TabletToolV2Interface(
Display *display,
237 const QList<Capability> &capabilities)
244 const auto toolResources = d->resourceMap();
245 for (TabletToolV2InterfacePrivate::Resource *resource : toolResources) {
246 d->send_removed(resource->handle);
253 return tabletToolPrivate->q;
260 return d->m_capabilities.contains(capability);
270 if (d->m_surface == surface)
274 if (d->m_surface && d->resourceMap().contains(*d->m_surface->client())) {
279 d->m_surface = surface;
281 if (lastTablet && lastTablet->d->resourceForSurface(surface)) {
284 d->m_lastTablet = lastTablet;
287 if (surface !=
nullptr) {
288 if (
auto *
const cursor = d->m_cursors.value(*surface->
client())) {
296 return d->m_proximitySerial;
301 return d->m_downSerial;
306 return d->m_surface && !d->targetResources().empty();
311 const auto serial = d->m_display->nextSerial();
312 for (
auto *resource : d->targetResources()) {
313 d->send_button(resource->handle,
316 pressed ? QtWaylandServer::zwp_tablet_tool_v2::button_state_pressed : QtWaylandServer::zwp_tablet_tool_v2::button_state_released);
322 const QPointF surfacePos = d->m_surface->toSurfaceLocal(pos);
323 for (
auto *resource : d->targetResources()) {
324 d->send_motion(resource->handle, wl_fixed_from_double(surfacePos.x()), wl_fixed_from_double(surfacePos.y()));
330 for (
auto *resource : d->targetResources()) {
331 d->send_distance(resource->handle, distance);
337 for (
auto *resource : d->targetResources()) {
338 d->send_frame(resource->handle, time);
342 d->m_surface =
nullptr;
343 d->m_lastTablet =
nullptr;
344 d->m_cleanup =
false;
350 for (
auto *resource : d->targetResources()) {
351 d->send_pressure(resource->handle, pressure);
357 for (
auto *resource : d->targetResources()) {
358 d->send_rotation(resource->handle, wl_fixed_from_double(rotation));
364 for (
auto *resource : d->targetResources()) {
365 d->send_slider(resource->handle, position);
371 for (
auto *resource : d->targetResources()) {
372 d->send_tilt(resource->handle, wl_fixed_from_double(degreesX), wl_fixed_from_double(degreesY));
378 for (
auto *resource : d->targetResources()) {
379 d->send_wheel(resource->handle, degrees, clicks);
385 wl_resource *tabletResource = tablet->d->resourceForSurface(d->m_surface);
386 const auto serial = d->m_display->nextSerial();
387 for (
auto *resource : d->targetResources()) {
388 d->send_proximity_in(resource->handle, serial, tabletResource, d->m_surface->resource());
390 d->m_proximitySerial = serial;
391 d->m_lastTablet = tablet;
396 for (
auto *resource : d->targetResources()) {
397 d->send_proximity_out(resource->handle);
404 const auto serial = d->m_display->nextSerial();
405 for (
auto *resource : d->targetResources()) {
406 d->send_down(resource->handle, serial);
408 d->m_downSerial = serial;
413 for (
auto *resource : d->targetResources()) {
414 d->send_up(resource->handle);
416 d->m_downSerial.reset();
423 : zwp_tablet_pad_ring_v2()
431 const auto [start, end] = resourceMap().equal_range(*client);
432 return std::ranges::subrange(start, end);
437 wl_resource_destroy(resource->handle);
454 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
455 d->send_angle(resource->handle, wl_fixed_from_double(angle));
461 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
462 d->send_frame(resource->handle, time);
468 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
469 d->send_source(resource->handle, source);
475 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
476 d->send_stop(resource->handle);
484 : zwp_tablet_pad_strip_v2()
492 const auto [start, end] = resourceMap().equal_range(*client);
493 return std::ranges::subrange(start, end);
498 wl_resource_destroy(resource->handle);
515 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
516 d->send_frame(resource->handle, time);
522 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
523 d->send_position(resource->handle, position);
529 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
530 d->send_source(resource->handle, source);
536 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
537 d->send_stop(resource->handle);
545 : zwp_tablet_pad_group_v2()
554 const auto [start, end] = resourceMap().equal_range(*client);
555 return std::ranges::subrange(start, end);
560 wl_resource_destroy(resource->handle);
568TabletPadGroupV2Interface::TabletPadGroupV2Interface(quint32 currentMode,
TabletPadV2Interface *parent)
579 d->m_currentMode = mode;
580 for (
auto *resource : d->resourcesForSurface(d->m_pad->currentSurface())) {
581 d->send_mode_switch(resource->handle, time, serial, mode);
596 : zwp_tablet_pad_v2()
604 for (uint i = 0; i < buttons; ++i) {
609 for (quint32 i = 0; i < rings; ++i) {
614 for (quint32 i = 0; i < strips; ++i) {
627 wl_resource_destroy(resource->handle);
638 const auto [start, end] = resourceMap().equal_range(*client);
639 return std::ranges::subrange(start, end);
656TabletPadV2Interface::TabletPadV2Interface(
const QString &path,
672 const auto tabletPadResources = d->resourceMap();
673 for (TabletPadV2InterfacePrivate::Resource *resource : tabletPadResources) {
674 d->send_removed(resource->handle);
680 const auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(time).count();
682 d->send_button(resource->handle, milliseconds, button, pressed);
688 return d->m_rings[at];
693 return d->m_strips[at];
698 if (surface == d->m_currentSurface) {
702 if (d->m_currentSurface) {
703 auto serial = d->m_display->nextSerial();
704 for (
auto *resource : d->resourcesForSurface(d->m_currentSurface)) {
705 d->send_leave(resource->handle, serial, d->m_currentSurface->resource());
709 d->m_currentSurface = surface;
711 wl_resource *tabletResource = tablet->d->resourceForSurface(surface);
713 auto serial = d->m_display->nextSerial();
714 for (
auto *resource : d->resourcesForSurface(surface)) {
715 d->send_enter(resource->handle, serial, tabletResource, surface->
resource());
717 d->m_padGroup->sendModeSwitch(0, d->m_display->nextSerial(), d->m_padGroup->d->m_currentMode);
723 return d->m_currentSurface;
730 : zwp_tablet_seat_v2()
738 for (
auto tablet : std::as_const(
m_tablets)) {
742 for (
auto pad : std::as_const(
m_pads)) {
746 for (
const auto &tools : std::as_const(
m_tools)) {
747 for (
auto *tool : tools) {
755 wl_resource_destroy(resource->handle);
760 wl_resource *toolResource = tool->d->add(resource->client(), resource->version())->handle;
761 send_tool_added(resource->handle, toolResource);
763 tool->d->send_type(toolResource, tool->d->m_type);
764 tool->d->send_hardware_serial(toolResource, tool->d->m_hardwareSerialHigh, tool->d->m_hardwareSerialLow);
765 tool->d->send_hardware_id_wacom(toolResource, tool->d->m_hardwareIdHigh, tool->d->m_hardwareIdLow);
766 for (uint32_t cap : std::as_const(tool->d->m_capabilities)) {
767 tool->d->send_capability(toolResource, cap);
769 tool->d->send_done(toolResource);
773 wl_resource *tabletResource = tablet->d->add(resource->client(), resource->version())->handle;
774 send_tablet_added(resource->handle, tabletResource);
776 tablet->d->send_name(tabletResource, tablet->d->m_name);
777 if (tablet->d->m_vendorId && tablet->d->m_productId) {
778 tablet->d->send_id(tabletResource, tablet->d->m_vendorId, tablet->d->m_productId);
780 for (
const QString &path : std::as_const(tablet->d->m_paths)) {
781 tablet->d->send_path(tabletResource, path);
783 tablet->d->send_done(tabletResource);
788 wl_resource *tabletResource = pad->d->add(resource->client(), resource->version())->handle;
789 send_pad_added(resource->handle, tabletResource);
791 pad->d->send_buttons(tabletResource, pad->d->m_buttons.size());
792 pad->d->send_path(tabletResource, pad->d->m_path);
794 auto groupResource = pad->d->m_padGroup->d->add(resource->client(), resource->version());
795 pad->d->send_group(tabletResource, groupResource->handle);
796 pad->d->m_padGroup->d->send_modes(groupResource->handle, pad->d->m_modes);
798 pad->d->m_padGroup->d->send_buttons(
799 groupResource->handle,
800 QByteArray::fromRawData(
reinterpret_cast<const char *
>(pad->d->m_buttons.data()), pad->d->m_buttons.size() *
sizeof(quint32)));
802 for (
auto ring : std::as_const(pad->d->m_rings)) {
803 auto ringResource = ring->d->add(resource->client(), resource->version());
804 pad->d->m_padGroup->d->send_ring(groupResource->handle, ringResource->handle);
807 for (
auto strip : std::as_const(pad->d->m_strips)) {
808 auto stripResource = strip->d->add(resource->client(), resource->version());
809 pad->d->m_padGroup->d->send_strip(groupResource->handle, stripResource->handle);
811 pad->d->m_padGroup->d->send_done(groupResource->handle);
812 pad->d->send_done(tabletResource);
816 QHash<QString, QList<TabletToolV2Interface *>>
m_tools;
818 QHash<QString, TabletPadV2Interface *>
m_pads;
822TabletSeatV2Interface::TabletSeatV2Interface(
Display *display, QObject *parent)
831 quint64 hardwareSerial,
833 const QList<TabletToolV2Interface::Capability> &capabilities,
834 const QString &deviceSysName)
836 constexpr auto MAX_UINT_32 = std::numeric_limits<quint32>::max();
839 hardwareSerial >> 32,
840 hardwareSerial & MAX_UINT_32,
842 hardwareId & MAX_UINT_32,
844 for (QtWaylandServer::zwp_tablet_seat_v2::Resource *resource : d->resourceMap()) {
845 d->sendToolAdded(resource, tool);
848 d->m_tools[deviceSysName].append(tool);
855 Q_ASSERT(!d->m_tablets.contains(sysname));
859 for (QtWaylandServer::zwp_tablet_seat_v2::Resource *r : d->resourceMap()) {
860 d->sendTabletAdded(r, iface);
863 d->m_tablets[sysname] = iface;
869 const QStringList &paths,
877 auto iface =
new TabletPadV2Interface(paths.at(0), buttons, rings, strips, modes, currentMode, d->m_display,
this);
878 iface->d->m_seat =
this;
879 for (
auto r : d->resourceMap()) {
880 d->sendPadAdded(r, iface);
883 tablet->d->m_pad = iface;
885 d->m_pads[sysname] = iface;
891 delete d->m_tablets.take(sysname);
892 delete d->m_pads.take(sysname);
894 qDeleteAll(d->m_tools.take(sysname));
899 for (
const auto &tools : std::as_const(d->m_tools)) {
901 if (tool->d->hardwareId() == hardwareId) {
911 for (
const auto &tools : std::as_const(d->m_tools)) {
913 if (tool->d->hardwareSerial() == hardwareSerial && tool->d->m_type ==
type) {
923 Q_ASSERT(d->m_pads.contains(name));
924 return d->m_pads.value(name);
931 : zwp_tablet_manager_v2(*display, s_version)
941 tsi->d->add(resource->client(), tablet_seat, s_version);
955 QHash<SeatInterface *, TabletSeatV2Interface *>
m_seats;
971 return d->resourceMap().value(*client);
976 return std::any_of(d->m_tools.cbegin(), d->m_tools.cend(), [serial](
const auto &tools) {
977 return std::any_of(tools.cbegin(), tools.cend(), [serial](const auto tool) {
978 return tool->downSerial() == serial;
983TabletManagerV2Interface::~TabletManagerV2Interface() =
default;
987#include "moc_tablet_v2.cpp"
Convenient Class which represents a wl_client.
wl_client * client() const
Class holding the Wayland server display loop.
ClientConnection * getConnection(wl_client *client)
Represents a Seat on the Wayland Display.
static SeatInterface * get(wl_resource *native)
Resource representing a wl_surface.
ClientConnection * client() const
static SurfaceInterface * get(wl_resource *native)
SurfaceRole * role() const
wl_resource * resource() const
void setRole(SurfaceRole *role)
TabletManagerV2Interface(Display *d, QObject *parent)
TabletSeatV2Interface * seat(SeatInterface *seat) const
TabletSeatV2Interface * get(SeatInterface *seat)
TabletManagerV2Interface *const q
TabletManagerV2InterfacePrivate(Display *display, TabletManagerV2Interface *q)
QHash< SeatInterface *, TabletSeatV2Interface * > m_seats
void zwp_tablet_manager_v2_get_tablet_seat(Resource *resource, uint32_t tablet_seat, struct ::wl_resource *seat_resource) override
void sendModeSwitch(quint32 time, quint32 serial, quint32 mode)
virtual ~TabletPadGroupV2Interface()
std::ranges::subrange< QMultiMap< struct ::wl_client *, Resource * >::const_iterator > resourcesForSurface(SurfaceInterface *surface) const
TabletPadGroupV2Interface *const q
TabletPadGroupV2InterfacePrivate(quint32 currentMode, TabletPadGroupV2Interface *q)
void zwp_tablet_pad_group_v2_destroy(Resource *resource) override
TabletPadV2Interface * m_pad
void sendAngle(qreal angle)
void sendFrame(quint32 time)
void sendSource(Source source)
virtual ~TabletPadRingV2Interface()
void zwp_tablet_pad_ring_v2_destroy(Resource *resource) override
std::ranges::subrange< QMultiMap< struct ::wl_client *, Resource * >::const_iterator > resourcesForSurface(SurfaceInterface *surface) const
TabletPadRingV2Interface *const q
TabletPadV2Interface * m_pad
TabletPadRingV2InterfacePrivate(TabletPadRingV2Interface *q)
void sendPosition(quint32 position)
virtual ~TabletPadStripV2Interface()
void sendSource(Source source)
void sendFrame(quint32 time)
TabletPadV2Interface * m_pad
void zwp_tablet_pad_strip_v2_destroy(Resource *resource) override
TabletPadStripV2InterfacePrivate(TabletPadStripV2Interface *q)
TabletPadStripV2Interface *const q
std::ranges::subrange< QMultiMap< struct ::wl_client *, Resource * >::const_iterator > resourcesForSurface(SurfaceInterface *surface) const
SurfaceInterface * currentSurface() const
TabletPadRingV2Interface * ring(uint at) const
void sendButton(std::chrono::microseconds time, quint32 button, bool pressed)
TabletPadStripV2Interface * strip(uint at) const
virtual ~TabletPadV2Interface()
void feedback(KWin::ClientConnection *client, quint32 button, const QString &description, quint32 serial)
void setCurrentSurface(SurfaceInterface *surface, TabletV2Interface *tablet)
QList< TabletPadRingV2Interface * > m_rings
TabletPadV2InterfacePrivate(const QString &path, quint32 buttons, quint32 rings, quint32 strips, quint32 modes, quint32 currentMode, Display *display, TabletPadV2Interface *q)
TabletSeatV2Interface * m_seat
std::ranges::subrange< QMultiMap< struct ::wl_client *, Resource * >::const_iterator > resourcesForSurface(SurfaceInterface *surface) const
TabletPadV2Interface *const q
~TabletPadV2InterfacePrivate() override
QList< TabletPadStripV2Interface * > m_strips
QPointer< SurfaceInterface > m_currentSurface
TabletPadGroupV2Interface *const m_padGroup
void zwp_tablet_pad_v2_set_feedback(Resource *resource, quint32 button, const QString &description, quint32 serial) override
QList< quint32 > m_buttons
void zwp_tablet_pad_v2_destroy(Resource *resource) override
virtual ~TabletSeatV2Interface()
bool isClientSupported(ClientConnection *client) const
TabletPadV2Interface * addTabletPad(const QString &sysname, const QString &name, const QStringList &paths, quint32 buttons, quint32 rings, quint32 strips, quint32 modes, quint32 currentMode, TabletV2Interface *tablet)
TabletPadV2Interface * padByName(const QString &sysname) const
TabletToolV2Interface * toolByHardwareSerial(quint64 hardwareSerial, TabletToolV2Interface::Type type) const
TabletToolV2Interface * addTool(TabletToolV2Interface::Type type, quint64 hardwareSerial, quint64 hardwareId, const QList< TabletToolV2Interface::Capability > &capabilities, const QString &deviceSysName)
void removeDevice(const QString &sysname)
TabletV2Interface * addTablet(quint32 vendorId, quint32 productId, const QString &sysname, const QString &name, const QStringList &paths)
TabletToolV2Interface * toolByHardwareId(quint64 hardwareId) const
bool hasImplicitGrab(quint32 serial) const
TabletSeatV2InterfacePrivate(Display *display, TabletSeatV2Interface *q)
void sendToolAdded(Resource *resource, TabletToolV2Interface *tool)
void sendPadAdded(Resource *resource, TabletPadV2Interface *pad)
void sendTabletAdded(Resource *resource, TabletV2Interface *tablet)
void zwp_tablet_seat_v2_destroy(Resource *resource) override
QHash< QString, TabletPadV2Interface * > m_pads
QHash< QString, QList< TabletToolV2Interface * > > m_tools
void zwp_tablet_seat_v2_bind_resource(Resource *resource) override
QHash< QString, TabletV2Interface * > m_tablets
TabletSeatV2Interface *const q
~TabletSurfaceCursorV2() override
quint32 enteredSerial() const
SurfaceInterface * surface() const
TabletSurfaceCursorV2 *const q
void update(quint32 serial, SurfaceInterface *surface, const QPoint &hotspot)
TabletSurfaceCursorV2Private(TabletSurfaceCursorV2 *q)
QPointer< SurfaceInterface > m_surface
TabletPadV2Interface * pad() const
virtual ~TabletV2Interface()
bool isSurfaceSupported(SurfaceInterface *surface) const
const uint32_t m_productId
TabletPadV2Interface * m_pad
const QStringList m_paths
TabletV2InterfacePrivate(TabletV2Interface *q, uint32_t vendorId, uint32_t productId, const QString &name, const QStringList &paths)
TabletV2Interface *const q
const uint32_t m_vendorId
wl_resource * resourceForSurface(SurfaceInterface *surface) const