20 #include "tablet_interface.h"
22 #include "resource_p.h"
23 #include "seat_interface.h"
24 #include "surface_interface.h"
26 #include "qwayland-server-tablet-unstable-v2.h"
29 using namespace KWayland;
30 using namespace Server;
32 static int s_version = 1;
34 class TabletInterface::Private :
public QtWaylandServer::zwp_tablet_v2
37 Private(TabletInterface *q, uint32_t vendorId, uint32_t productId,
const QString name,
const QStringList &paths)
40 , m_vendorId(vendorId)
41 , m_productId(productId)
50 QtWaylandServer::zwp_tablet_v2::Resource *r = resourceMap().value(*client);
51 return r ? r->handle :
nullptr;
54 void zwp_tablet_v2_destroy_resource(QtWaylandServer::zwp_tablet_v2::Resource *resource)
override
57 if (removed && resourceMap().isEmpty()) {
62 TabletInterface *
const q;
63 const uint32_t m_vendorId;
64 const uint32_t m_productId;
70 TabletInterface::TabletInterface(uint32_t vendorId, uint32_t productId,
const QString &name,
const QStringList &paths,
QObject *parent)
72 , d(new Private(this, vendorId, productId, name, paths))
76 TabletInterface::~TabletInterface() =
default;
80 return d->resourceForSurface(surface);
83 void TabletInterface::sendRemoved()
86 for (QtWaylandServer::zwp_tablet_v2::Resource *resource : d->resourceMap()) {
87 d->send_removed(resource->handle);
91 class TabletCursor::Private
94 Private(TabletCursor *q)
101 const bool diff = m_serial != serial && m_surface != surface && m_hotspot != hotspot;
110 TabletCursor *
const q;
112 quint32 m_serial = 0;
117 TabletCursor::TabletCursor()
119 , d(new Private(this))
123 TabletCursor::~TabletCursor() =
default;
125 QPoint TabletCursor::hotspot()
const
130 quint32 TabletCursor::enteredSerial()
const
140 class TabletToolInterface::Private :
public QtWaylandServer::zwp_tablet_tool_v2
143 Private(TabletToolInterface *q,
151 : zwp_tablet_tool_v2()
154 , m_hardwareSerialHigh(hsh)
155 , m_hardwareSerialLow(hsl)
156 , m_hardwareIdHigh(hih)
157 , m_hardwareIdLow(hil)
163 wl_resource *targetResource()
170 const Resource *r = resourceMap().value(*client);
171 return r ? r->handle :
nullptr;
174 quint64 hardwareId()
const
176 return quint64(quint64(m_hardwareIdHigh) << 32) + m_hardwareIdLow;
178 quint64 hardwareSerial()
const
180 return quint64(quint64(m_hardwareSerialHigh) << 32) + m_hardwareSerialLow;
183 void zwp_tablet_tool_v2_bind_resource(QtWaylandServer::zwp_tablet_tool_v2::Resource *resource)
override
185 TabletCursor *&c = m_cursors[resource->handle];
187 c =
new TabletCursor;
191 void zwp_tablet_tool_v2_set_cursor(
Resource *resource, uint32_t serial, struct ::wl_resource *_surface, int32_t hotspot_x, int32_t hotspot_y)
override
193 TabletCursor *c = m_cursors[resource->handle];
195 if (resource->handle == targetResource()) {
200 void zwp_tablet_tool_v2_destroy_resource(
Resource *resource)
override
202 delete m_cursors.
take(resource->handle);
206 bool m_cleanup =
false;
209 const uint32_t m_type;
210 const uint32_t m_hardwareSerialHigh, m_hardwareSerialLow;
211 const uint32_t m_hardwareIdHigh, m_hardwareIdLow;
214 TabletToolInterface *
const q;
217 TabletToolInterface::TabletToolInterface(
Display *display,
230 TabletToolInterface::~TabletToolInterface() =
default;
234 if (d->m_surface == surface) {
238 TabletInterface *
const lastTablet = d->m_lastTablet;
239 if (d->m_surface && d->resourceMap().contains(*d->m_surface->client())) {
244 d->m_surface = surface;
246 if (lastTablet && lastTablet->d->resourceForSurface(surface)) {
247 sendProximityIn(lastTablet);
249 d->m_lastTablet = lastTablet;
252 Q_EMIT cursorChanged(d->m_cursors.value(d->targetResource()));
255 bool TabletToolInterface::isClientSupported()
const
257 return d->m_surface && d->targetResource();
260 void TabletToolInterface::sendButton(uint32_t button,
bool pressed)
262 d->send_button(d->targetResource(),
263 d->m_display->nextSerial(),
265 pressed ? QtWaylandServer::zwp_tablet_tool_v2::button_state_pressed : QtWaylandServer::zwp_tablet_tool_v2::button_state_released);
268 void TabletToolInterface::sendMotion(
const QPointF &pos)
270 d->send_motion(d->targetResource(), wl_fixed_from_double(pos.
x()), wl_fixed_from_double(pos.
y()));
273 void TabletToolInterface::sendDistance(uint32_t distance)
275 d->send_distance(d->targetResource(), distance);
278 void TabletToolInterface::sendFrame(uint32_t time)
280 d->send_frame(d->targetResource(), time);
283 d->m_surface =
nullptr;
284 d->m_lastTablet =
nullptr;
285 d->m_cleanup =
false;
289 void TabletToolInterface::sendPressure(uint32_t pressure)
291 d->send_pressure(d->targetResource(), pressure);
294 void TabletToolInterface::sendRotation(qreal rotation)
296 d->send_rotation(d->targetResource(), wl_fixed_from_double(rotation));
299 void TabletToolInterface::sendSlider(int32_t position)
301 d->send_slider(d->targetResource(), position);
304 void TabletToolInterface::sendTilt(qreal degreesX, qreal degreesY)
306 d->send_tilt(d->targetResource(), wl_fixed_from_double(degreesX), wl_fixed_from_double(degreesY));
309 void TabletToolInterface::sendWheel(int32_t degrees, int32_t clicks)
311 d->send_wheel(d->targetResource(), degrees, clicks);
314 void TabletToolInterface::sendProximityIn(TabletInterface *tablet)
316 wl_resource *tabletResource = tablet->d->resourceForSurface(d->m_surface);
317 d->send_proximity_in(d->targetResource(), d->m_display->nextSerial(), tabletResource, d->m_surface->resource());
318 d->m_lastTablet = tablet;
321 void TabletToolInterface::sendProximityOut()
323 d->send_proximity_out(d->targetResource());
327 void TabletToolInterface::sendDown()
329 d->send_down(d->targetResource(), d->m_display->nextSerial());
332 void TabletToolInterface::sendUp()
334 d->send_up(d->targetResource());
337 void TabletToolInterface::sendRemoved()
339 for (QtWaylandServer::zwp_tablet_tool_v2::Resource *resource : d->resourceMap()) {
340 d->send_removed(resource->handle);
344 class TabletSeatInterface::Private :
public QtWaylandServer::zwp_tablet_seat_v2
348 : zwp_tablet_seat_v2()
354 void zwp_tablet_seat_v2_bind_resource(
Resource *resource)
override
356 for (
auto iface : std::as_const(m_tablets)) {
357 sendTabletAdded(resource, iface);
360 for (
auto *tool : std::as_const(m_tools)) {
361 sendToolAdded(resource, tool);
365 void sendToolAdded(
Resource *resource, TabletToolInterface *tool)
367 wl_resource *toolResource = tool->d->add(resource->
client(), resource->version())->handle;
368 send_tool_added(resource->handle, toolResource);
370 tool->d->send_type(toolResource, tool->d->m_type);
371 tool->d->send_hardware_serial(toolResource, tool->d->m_hardwareSerialHigh, tool->d->m_hardwareSerialLow);
372 tool->d->send_hardware_id_wacom(toolResource, tool->d->m_hardwareIdHigh, tool->d->m_hardwareIdLow);
373 for (uint32_t cap : std::as_const(tool->d->m_capabilities)) {
374 tool->d->send_capability(toolResource, cap);
376 tool->d->send_done(toolResource);
378 void sendTabletAdded(
Resource *resource, TabletInterface *tablet)
380 wl_resource *tabletResource = tablet->d->add(resource->
client(), resource->version())->handle;
381 send_tablet_added(resource->handle, tabletResource);
383 tablet->d->send_name(tabletResource, tablet->d->m_name);
384 if (tablet->d->m_vendorId && tablet->d->m_productId) {
385 tablet->d->send_id(tabletResource, tablet->d->m_vendorId, tablet->d->m_productId);
387 for (
const QString &path : std::as_const(tablet->d->m_paths)) {
388 tablet->d->send_path(tabletResource, path);
390 tablet->d->send_done(tabletResource);
399 TabletSeatInterface::TabletSeatInterface(
Display *display,
QObject *parent)
401 , d(new Private(display, this))
405 TabletSeatInterface::~TabletSeatInterface() =
default;
407 TabletToolInterface *TabletSeatInterface::addTool(TabletToolInterface::Type type,
408 quint64 hardwareSerial,
412 constexpr
auto MAX_UINT_32 = std::numeric_limits<quint32>::max();
413 auto tool =
new TabletToolInterface(d->m_display,
415 hardwareSerial >> 32,
416 hardwareSerial & MAX_UINT_32,
418 hardwareId & MAX_UINT_32,
421 for (QtWaylandServer::zwp_tablet_seat_v2::Resource *resource : d->resourceMap()) {
422 d->sendToolAdded(resource, tool);
425 d->m_tools.append(tool);
427 auto tti =
static_cast<TabletToolInterface *
>(object);
428 tti->d->send_removed();
429 d->m_tools.removeAll(tti);
434 TabletInterface *TabletSeatInterface::addTablet(uint32_t vendorId, uint32_t productId,
const QString &sysname,
const QString &name,
const QStringList &paths)
436 auto iface =
new TabletInterface(vendorId, productId, name, paths,
this);
438 for (QtWaylandServer::zwp_tablet_seat_v2::Resource *r : d->resourceMap()) {
439 d->sendTabletAdded(r, iface);
442 d->m_tablets[sysname] = iface;
446 void TabletSeatInterface::removeTablet(
const QString &sysname)
448 auto tablet = d->m_tablets.
take(sysname);
450 tablet->sendRemoved();
454 TabletToolInterface *TabletSeatInterface::toolByHardwareId(quint64 hardwareId)
const
456 for (TabletToolInterface *tool : d->m_tools) {
457 if (tool->d->hardwareId() == hardwareId) {
464 TabletToolInterface *TabletSeatInterface::toolByHardwareSerial(quint64 hardwareSerial)
const
466 for (TabletToolInterface *tool : d->m_tools) {
467 if (tool->d->hardwareSerial() == hardwareSerial) {
474 TabletInterface *TabletSeatInterface::tabletByName(
const QString &name)
const
476 return d->m_tablets.value(name);
479 class TabletManagerInterface::Private :
public QtWaylandServer::zwp_tablet_manager_v2
482 Private(
Display *display, TabletManagerInterface *q)
483 : zwp_tablet_manager_v2(*display, s_version)
489 void zwp_tablet_manager_v2_get_tablet_seat(
Resource *resource, uint32_t tablet_seat, struct ::wl_resource *seat_resource)
override
493 tsi->d->add(resource->
client(), tablet_seat, s_version);
505 TabletManagerInterface *
const q;
510 TabletManagerInterface::TabletManagerInterface(
Display *display,
QObject *parent)
512 , d(new Private(display, this))
521 TabletManagerInterface::~TabletManagerInterface() =
default;