[OpenDocString] kdeconnect-kde (cpp)
x11remoteinput.cpp
X11RemoteInput::X11RemoteInput(QObject *parent)
    : AbstractRemoteInput(parent)
    , m_fakekey(nullptr)
{
}
Constructs a remote input object and assigns it to its internal key.
X11RemoteInput::~X11RemoteInput()
{
    if (m_fakekey) {
        free(m_fakekey);
        m_fakekey = nullptr;
    }
}
Frees the fake key object upon destruction.
bool isLeftHanded(Display *display)
{
    unsigned char map[20];
    int num_buttons = XGetPointerMapping(display, map, 20);
    if (num_buttons == 1) {
        return false;
    } else if (num_buttons == 2) {
        return ((int)map[0] == 2 && (int)map[1] == 1);
    } else {
        return ((int)map[0] == 3 && (int)map[2] == 1);
    }
}
This checks if the user is left handed. It first gets the pointer mapping from the internal list of buttons, and if it is it is the left handed button.
bool X11RemoteInput::handlePacket(const NetworkPacket &np)
{
    float dx = np.get(QStringLiteral("dx"), 0);
    float dy = np.get(QStringLiteral("dy"), 0);

    bool isSingleClick = np.get(QStringLiteral("singleclick"), false);
    bool isDoubleClick = np.get(QStringLiteral("doubleclick"), false);
    bool isMiddleClick = np.get(QStringLiteral("middleclick"), false);
    bool isRightClick = np.get(QStringLiteral("rightclick"), false);
    bool isSingleHold = np.get(QStringLiteral("singlehold"), false);
    bool isSingleRelease = np.get(QStringLiteral("singlerelease"), false);
    bool isScroll = np.get(QStringLiteral("scroll"), false);
    QString key = np.get(QStringLiteral("key"), QLatin1String(""));
    int specialKey = np.get(QStringLiteral("specialKey"), 0);

    if (isSingleClick || isDoubleClick || isMiddleClick || isRightClick || isSingleHold || isSingleRelease || isScroll || !key.isEmpty() || specialKey) {
        Display *display = QX11Info::display();
        if (!display) {
            return false;
        }

        bool leftHanded = isLeftHanded(display);
        int mainMouseButton = leftHanded ? RightMouseButton : LeftMouseButton;
        int secondaryMouseButton = leftHanded ? LeftMouseButton : RightMouseButton;

        if (isSingleClick) {
            XTestFakeButtonEvent(display, mainMouseButton, True, 0);
            XTestFakeButtonEvent(display, mainMouseButton, False, 0);
        } else if (isDoubleClick) {
            XTestFakeButtonEvent(display, mainMouseButton, True, 0);
            XTestFakeButtonEvent(display, mainMouseButton, False, 0);
            XTestFakeButtonEvent(display, mainMouseButton, True, 0);
            XTestFakeButtonEvent(display, mainMouseButton, False, 0);
        } else if (isMiddleClick) {
            XTestFakeButtonEvent(display, MiddleMouseButton, True, 0);
            XTestFakeButtonEvent(display, MiddleMouseButton, False, 0);
        } else if (isRightClick) {
            XTestFakeButtonEvent(display, secondaryMouseButton, True, 0);
            XTestFakeButtonEvent(display, secondaryMouseButton, False, 0);
        } else if (isSingleHold) {
            // For drag'n drop
            XTestFakeButtonEvent(display, mainMouseButton, True, 0);
        } else if (isSingleRelease) {
            // For drag'n drop. NEVER USED (release is done by tapping, which actually triggers a isSingleClick). Kept here for future-proofness.
            XTestFakeButtonEvent(display, mainMouseButton, False, 0);
        } else if (isScroll) {
            if (dy < 0) {
                XTestFakeButtonEvent(display, MouseWheelDown, True, 0);
                XTestFakeButtonEvent(display, MouseWheelDown, False, 0);
            } else if (dy > 0) {
                XTestFakeButtonEvent(display, MouseWheelUp, True, 0);
                XTestFakeButtonEvent(display, MouseWheelUp, False, 0);
            }
        } else if (!key.isEmpty() || specialKey) {
            bool ctrl = np.get(QStringLiteral("ctrl"), false);
            bool alt = np.get(QStringLiteral("alt"), false);
            bool shift = np.get(QStringLiteral("shift"), false);
            bool super = np.get(QStringLiteral("super"), false);

            if (ctrl)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Control_L), True, 0);
            if (alt)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Alt_L), True, 0);
            if (shift)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), True, 0);
            if (super)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Super_L), True, 0);

            if (specialKey) {
                if (specialKey >= (int)arraySize(SpecialKeysMap)) {
                    qWarning() << "Unsupported special key identifier";
                    return false;
                }

                int keycode = XKeysymToKeycode(display, SpecialKeysMap[specialKey]);

                XTestFakeKeyEvent(display, keycode, True, 0);
                XTestFakeKeyEvent(display, keycode, False, 0);

            } else {
                if (!m_fakekey) {
                    m_fakekey = fakekey_init(display);
                    if (!m_fakekey) {
                        qWarning() << "Failed to initialize libfakekey";
                        return false;
                    }
                }

                // We use fakekey here instead of XTest (above) because it can handle utf characters instead of keycodes.
                for (int i = 0; i < key.length(); i++) {
                    QByteArray utf8 = QString(key.at(i)).toUtf8();
                    fakekey_press(m_fakekey, (const uchar *)utf8.constData(), utf8.size(), 0);
                    fakekey_release(m_fakekey);
                }
            }

            if (ctrl)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Control_L), False, 0);
            if (alt)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Alt_L), False, 0);
            if (shift)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), False, 0);
            if (super)
                XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Super_L), False, 0);
        }

        XFlush(display);

    } else { // Is a mouse move event
        QPoint point = QCursor::pos();
        QCursor::setPos(point.x() + (int)dx, point.y() + (int)dy);
    }
    return true;
}
This retrieves information about the given network packet, and checks if it is a mouse move event. It creates two objects: single click, doubleclick, middleclick, righthold, scroll, and keycode. If the isSingleClick, isRightClick, isMiddleClick, isRightHold, and scroll, it is a single hold. It also creates fake key object and sets its position in the display object. It also checks if the key is empty, ctrl, alt, super.
bool X11RemoteInput::hasKeyboardSupport()
{
    return true;
}
This implements checking if the keyboard is supported.