File indexing completed on 2024-05-19 05:01:29

0001 /*
0002    This file is part of the KDE project
0003 
0004    Copyright (C) 2018-2019 Jan Grulich <jgrulich@redhat.com>
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This program is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    General Public License for more details.
0015 
0016    You should have received a copy of the GNU General Public License
0017    along with this program; see the file COPYING.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "xdpevents.h"
0023 
0024 #include "rfbservermanager.h"
0025 #include "xdp_dbus_remotedesktop_interface.h"
0026 
0027 #include <linux/input.h>
0028 
0029 #include <QApplication>
0030 #include <QGlobalStatic>
0031 
0032 class EventData
0033 {
0034 public:
0035     EventData();
0036 
0037     //mouse
0038     int buttonMask = 0;
0039     int x = 0;
0040     int y = 0;
0041 
0042     QScopedPointer<OrgFreedesktopPortalRemoteDesktopInterface> dbusXdpRemoteDesktopService;
0043 
0044 private:
0045     void init();
0046 };
0047 
0048 Q_GLOBAL_STATIC(EventData, data)
0049 
0050 EventData::EventData()
0051 {
0052     init();
0053 }
0054 
0055 void EventData::init()
0056 {
0057     dbusXdpRemoteDesktopService.reset(new OrgFreedesktopPortalRemoteDesktopInterface(QStringLiteral("org.freedesktop.portal.Desktop"),
0058                                       QStringLiteral("/org/freedesktop/portal/desktop"), QDBusConnection::sessionBus()));
0059 }
0060 
0061 void XdpEventHandler::handleKeyboard(bool down, rfbKeySym keySym)
0062 {
0063     const QDBusObjectPath sessionHandle = frameBuffer()->customProperty(QStringLiteral("session_handle")).value<QDBusObjectPath>();
0064     data->dbusXdpRemoteDesktopService->NotifyKeyboardKeysym(sessionHandle, {}, keySym, down);
0065 }
0066 
0067 void XdpEventHandler::handlePointer(int buttonMask, int x, int y)
0068 {
0069     const uint streamNodeId = frameBuffer()->customProperty(QStringLiteral("stream_node_id")).toUInt();
0070     const QDBusObjectPath sessionHandle = frameBuffer()->customProperty(QStringLiteral("session_handle")).value<QDBusObjectPath>();
0071 
0072     if (streamNodeId == 0 || sessionHandle.path().isEmpty()) {
0073         return;
0074     }
0075 
0076     if (x != data->x || y != data->y) {
0077         data->dbusXdpRemoteDesktopService->NotifyPointerMotionAbsolute(sessionHandle, QVariantMap(), streamNodeId, x, y);
0078         data->x = x;
0079         data->y = y;
0080     }
0081 
0082     if (buttonMask != data->buttonMask) {
0083         int i = 0;
0084         QVector<int> buttons = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, 0, 0, 0, 0, BTN_SIDE, BTN_EXTRA };
0085         for (auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) {
0086             int prevButtonState = (data->buttonMask >> i) & 0x01;
0087             int currentButtonState = (buttonMask >> i) & 0x01;
0088 
0089             if (prevButtonState != currentButtonState) {
0090                 if (*it) {
0091                     data->dbusXdpRemoteDesktopService->NotifyPointerButton(sessionHandle, QVariantMap(), *it, buttonMask);
0092                 } else {
0093                     int axis = 0;
0094                     int steps = 0;
0095                     switch (i) {
0096                     case 3:
0097                         axis = 0;   // Vertical
0098                         steps = -1;
0099                         break;
0100                     case 4:
0101                         axis = 0;   // Vertical
0102                         steps = 1;
0103                         break;
0104                     case 5:
0105                         axis = 1;   // Horizontal
0106                         steps = -1;
0107                         break;
0108                     case 6:
0109                         axis = 1;   // Horizontal
0110                         steps = 1;
0111                         break;
0112                         }
0113 
0114                     data->dbusXdpRemoteDesktopService->NotifyPointerAxisDiscrete(sessionHandle, QVariantMap(), axis, steps);
0115                 }
0116             }
0117             ++i;
0118         }
0119         data->buttonMask = buttonMask;
0120     }
0121 }