File indexing completed on 2024-12-22 05:09:20

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "keyboard.h"
0007 #include "surface.h"
0008 #include "wayland_pointer_p.h"
0009 #include <QPointer>
0010 // wayland
0011 #include <wayland-client-protocol.h>
0012 
0013 namespace KWayland
0014 {
0015 namespace Client
0016 {
0017 class Q_DECL_HIDDEN Keyboard::Private
0018 {
0019 public:
0020     Private(Keyboard *q);
0021     void setup(wl_keyboard *k);
0022 
0023     WaylandPointer<wl_keyboard, wl_keyboard_release> keyboard;
0024     QPointer<Surface> enteredSurface;
0025 
0026     struct {
0027         qint32 charactersPerSecond = 0;
0028         qint32 delay = 0;
0029     } repeatInfo;
0030 
0031 private:
0032     void enter(uint32_t serial, wl_surface *surface, wl_array *keys);
0033     void leave(uint32_t serial);
0034     static void keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size);
0035     static void enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys);
0036     static void leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface);
0037     static void keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
0038     static void
0039     modifiersCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group);
0040     static void repeatInfoCallback(void *data, wl_keyboard *keyboard, int32_t charactersPerSecond, int32_t delay);
0041     Keyboard *q;
0042     static const wl_keyboard_listener s_listener;
0043 };
0044 
0045 Keyboard::Private::Private(Keyboard *q)
0046     : q(q)
0047 {
0048 }
0049 
0050 void Keyboard::Private::setup(wl_keyboard *k)
0051 {
0052     Q_ASSERT(k);
0053     Q_ASSERT(!keyboard);
0054     keyboard.setup(k);
0055     wl_keyboard_add_listener(keyboard, &s_listener, this);
0056 }
0057 
0058 const wl_keyboard_listener Keyboard::Private::s_listener = {keymapCallback, enterCallback, leaveCallback, keyCallback, modifiersCallback, repeatInfoCallback};
0059 
0060 Keyboard::Keyboard(QObject *parent)
0061     : QObject(parent)
0062     , d(new Private(this))
0063 {
0064 }
0065 
0066 Keyboard::~Keyboard()
0067 {
0068     release();
0069 }
0070 
0071 void Keyboard::release()
0072 {
0073     d->keyboard.release();
0074 }
0075 
0076 void Keyboard::destroy()
0077 {
0078     d->keyboard.destroy();
0079 }
0080 
0081 void Keyboard::setup(wl_keyboard *keyboard)
0082 {
0083     d->setup(keyboard);
0084 }
0085 
0086 void Keyboard::Private::enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys)
0087 {
0088     auto k = reinterpret_cast<Private *>(data);
0089     Q_ASSERT(k->keyboard == keyboard);
0090     k->enter(serial, surface, keys);
0091 }
0092 
0093 void Keyboard::Private::enter(uint32_t serial, wl_surface *surface, wl_array *keys)
0094 {
0095     Q_UNUSED(keys)
0096     enteredSurface = Surface::get(surface);
0097     Q_EMIT q->entered(serial);
0098 }
0099 
0100 void Keyboard::Private::leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface)
0101 {
0102     Q_UNUSED(surface)
0103     auto k = reinterpret_cast<Private *>(data);
0104     Q_ASSERT(k->keyboard == keyboard);
0105     k->leave(serial);
0106 }
0107 
0108 void Keyboard::Private::leave(uint32_t serial)
0109 {
0110     enteredSurface.clear();
0111     Q_EMIT q->left(serial);
0112 }
0113 
0114 void Keyboard::Private::keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
0115 {
0116     Q_UNUSED(serial)
0117     auto k = reinterpret_cast<Keyboard::Private *>(data);
0118     Q_ASSERT(k->keyboard == keyboard);
0119     auto toState = [state] {
0120         if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
0121             return KeyState::Released;
0122         } else {
0123             return KeyState::Pressed;
0124         }
0125     };
0126     Q_EMIT k->q->keyChanged(key, toState(), time);
0127 }
0128 
0129 void Keyboard::Private::keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size)
0130 {
0131     auto k = reinterpret_cast<Keyboard::Private *>(data);
0132     Q_ASSERT(k->keyboard == keyboard);
0133     if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
0134         return;
0135     }
0136     Q_EMIT k->q->keymapChanged(fd, size);
0137 }
0138 
0139 void Keyboard::Private::modifiersCallback(void *data,
0140                                           wl_keyboard *keyboard,
0141                                           uint32_t serial,
0142                                           uint32_t modsDepressed,
0143                                           uint32_t modsLatched,
0144                                           uint32_t modsLocked,
0145                                           uint32_t group)
0146 {
0147     Q_UNUSED(serial)
0148     auto k = reinterpret_cast<Keyboard::Private *>(data);
0149     Q_ASSERT(k->keyboard == keyboard);
0150     Q_EMIT k->q->modifiersChanged(modsDepressed, modsLatched, modsLocked, group);
0151 }
0152 
0153 void Keyboard::Private::repeatInfoCallback(void *data, wl_keyboard *keyboard, int32_t charactersPerSecond, int32_t delay)
0154 {
0155     auto k = reinterpret_cast<Keyboard::Private *>(data);
0156     Q_ASSERT(k->keyboard == keyboard);
0157     k->repeatInfo.charactersPerSecond = qMax(charactersPerSecond, 0);
0158     k->repeatInfo.delay = qMax(delay, 0);
0159     Q_EMIT k->q->keyRepeatChanged();
0160 }
0161 
0162 Surface *Keyboard::enteredSurface()
0163 {
0164     return d->enteredSurface.data();
0165 }
0166 
0167 Surface *Keyboard::enteredSurface() const
0168 {
0169     return d->enteredSurface.data();
0170 }
0171 
0172 bool Keyboard::isValid() const
0173 {
0174     return d->keyboard.isValid();
0175 }
0176 
0177 bool Keyboard::isKeyRepeatEnabled() const
0178 {
0179     return d->repeatInfo.charactersPerSecond > 0;
0180 }
0181 
0182 qint32 Keyboard::keyRepeatDelay() const
0183 {
0184     return d->repeatInfo.delay;
0185 }
0186 
0187 qint32 Keyboard::keyRepeatRate() const
0188 {
0189     return d->repeatInfo.charactersPerSecond;
0190 }
0191 
0192 Keyboard::operator wl_keyboard *()
0193 {
0194     return d->keyboard;
0195 }
0196 
0197 Keyboard::operator wl_keyboard *() const
0198 {
0199     return d->keyboard;
0200 }
0201 
0202 }
0203 }
0204 
0205 #include "moc_keyboard.cpp"