Implemented VNC input for mouse pointer

This implementation has several serious restrictions
What works:
- single clicks
- mouse move

What doesn't, due to FakeInput protocol:
- absolute mouse move
- keyboard

What is not implemented yet but possibly can be:
- drag'n'drop
This commit is contained in:
Oleg Chernovskiy
2016-03-20 19:19:59 +03:00
parent 09f360ded6
commit 73107409ee
13 changed files with 369 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
add_subdirectory (x11)
#if(HAVE_GBM)
# add_subdirectory (gbm)
#endif()
if(HAVE_GBM)
add_subdirectory (fakeinput)
endif()

View File

@@ -0,0 +1,25 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set (krfb_events_gbm_SRCS
fakeinputevents.cpp
fakeinputeventsplugin.cpp
)
add_library(krfb_events_fakeinput
MODULE
${krfb_events_gbm_SRCS}
)
target_link_libraries (krfb_events_fakeinput
${GBM_XTest_LIB}
KF5::CoreAddons
KF5::WaylandClient
KF5::I18n
krfbprivate
)
install (TARGETS krfb_events_fakeinput
DESTINATION ${PLUGIN_INSTALL_DIR}/krfb
)

View File

@@ -0,0 +1,118 @@
/*
This file is part of the KDE project
Copyright (C) 2016 Oleg Chernovskiy <kanedias@xaker.ru>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "fakeinputevents.h"
// Qt
#include <QApplication>
#include <QDesktopWidget>
#include <QGlobalStatic>
// KDE
#include <KLocalizedString>
// KWayland
#include <KWayland/Client/registry.h>
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/fakeinput.h>
class EventData
{
public:
EventData() = default;
//mouse
int buttonMask = 0;
int oldX = 0;
int oldY = 0;
};
FakeInputEventHandler::FakeInputEventHandler()
: EventHandler(), m_eventData(new EventData())
{
initWaylandConnection();
}
void FakeInputEventHandler::initWaylandConnection()
{
using namespace KWayland::Client;
ConnectionThread *conn = ConnectionThread::fromApplication(this);
Registry *registry = new Registry(this);
registry->create(conn);
connect(registry, &Registry::fakeInputAnnounced, this,
[this, registry] (qint32 name, qint32 version) {
m_interface = registry->createFakeInput(name, version, this);
}
);
registry->setup();
}
void FakeInputEventHandler::authIfNeeded()
{
if (!m_authRequested) {
m_interface->authenticate(i18n("Krfb"), i18n("Remote VNC input"));
m_authRequested = true;
}
}
void FakeInputEventHandler::handleKeyboard(bool down, rfbKeySym keySym)
{
if (!m_interface)
return;
authIfNeeded();
// TODO: implement button handling
// both in FakeInput interface and here
Q_UNUSED(down)
Q_UNUSED(keySym)
}
void FakeInputEventHandler::handlePointer(int buttonMask, int x, int y)
{
if (!m_interface)
return;
authIfNeeded();
int oldMask = m_eventData->buttonMask;
int oldX = m_eventData->oldX;
int oldY = m_eventData->oldY;
if (!(oldMask & 1) && buttonMask & 1) { // single left click
m_interface->requestPointerButtonClick(Qt::LeftButton);
}
if (!(oldMask & 2) && buttonMask & 2) { // single right click
m_interface->requestPointerButtonClick(Qt::RightButton);
}
if (!(oldMask & 4) && buttonMask & 4) { // single middle click
m_interface->requestPointerButtonClick(Qt::MiddleButton);
}
if (!(oldMask & 8) && buttonMask & 8) { // wheel up
m_interface->requestPointerAxis(Qt::Vertical, +10);
}
if (!(oldMask & 16) && buttonMask & 16) { // wheel down
m_interface->requestPointerAxis(Qt::Vertical, -10);
}
if (oldX != x || oldY != y) {
m_interface->requestPointerMove(QSizeF(x - oldX, y - oldY));
}
m_eventData->buttonMask = buttonMask;
}

View File

@@ -0,0 +1,54 @@
/*
This file is part of the KDE project
Copyright (C) 2016 by Oleg Chernovskiy <kanedias@xaker.ru>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef EVENTS_GBMEVENTS_H
#define EVENTS_GBMEVENTS_H
#include "../../krfb/events.h"
#include <QScopedPointer>
namespace KWayland
{
namespace Client
{
class FakeInput;
}
}
class EventData;
class FakeInputEventHandler : public EventHandler
{
public:
FakeInputEventHandler();
virtual void handleKeyboard(bool down, rfbKeySym key);
virtual void handlePointer(int buttonMask, int x, int y);
private:
void initWaylandConnection();
void authIfNeeded();
QScopedPointer<EventData> m_eventData;
KWayland::Client::FakeInput *m_interface = nullptr;
bool m_authRequested = false;
};
#endif

View File

@@ -0,0 +1,41 @@
/* This file is part of the KDE project
Copyright (C) 2016 Oleg Chernovskiy <kanedias@xaker.ru>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "fakeinputeventsplugin.h"
#include "fakeinputevents.h"
#include <KPluginFactory>
K_PLUGIN_FACTORY_WITH_JSON(FakeInputEventsPluginFactory, "krfb_events_fakeinput.json",
registerPlugin<FakeInputEventsPlugin>();)
FakeInputEventsPlugin::FakeInputEventsPlugin(QObject *parent, const QVariantList &args)
: EventsPlugin(parent, args)
{
}
EventHandler *FakeInputEventsPlugin::eventHandler()
{
// works only under Wayland
return new FakeInputEventHandler();
}
#include "fakeinputeventsplugin.moc"

View File

@@ -0,0 +1,45 @@
/* This file is part of the KDE project
Copyright (C) 2016 Oleg Chernovskiy <kanedias@xaker.ru>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KRFB_EVENTS_GBM_GBMEVENTSPLUGIN_H
#define KRFB_EVENTS_GBM_GBMEVENTSPLUGIN_H
#include "eventsplugin.h"
#include <QWidget>
class EventHandler;
class FakeInputEventsPlugin : public EventsPlugin
{
Q_OBJECT
public:
FakeInputEventsPlugin(QObject *parent, const QVariantList &args);
virtual ~FakeInputEventsPlugin() = default;
EventHandler *eventHandler() override;
private:
Q_DISABLE_COPY(FakeInputEventsPlugin)
};
#endif // Header guard

View File

@@ -0,0 +1,17 @@
[Desktop Entry]
Encoding=UTF-8
Comment=KWin FakeInput based event handler for KRfb
Comment[ru]=Обработчик событий для KRfb на базе интерфейса FakeInput KWin
Comment[x-test]=KWin FakeInput based event handler for KRfbxx
Name=KWin FakeInput based event handler for KRfb
Name[ru]=Обработчик событий для KRfb на базе интерфейса FakeInput KWin
Name[x-test]=xxKWin FakeInput based event handler for KRfbxx
Type=Service
ServiceTypes=krfb/events
X-KDE-Library=krfb_events_fakeinput
X-KDE-PluginInfo-Name=fakeinput
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://www.kde.org
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true

View File

@@ -0,0 +1,17 @@
{
"Encoding": "UTF-8",
"KPlugin": {
"Description": "KWin FakeInput based event handler for KRfb",
"Description[x-test]": "xxKWin FakeInput based event handler for KRfbxx",
"EnabledByDefault": true,
"Id": "fakeinput",
"License": "GPL",
"Name": "KWin FakeInput Event handler for KRfb",
"Name[x-test]": "xxKWin FakeInput Event handler for KRfbxx",
"ServiceTypes": [
"krfb/events"
],
"Version": "0.1",
"Website": "http://www.kde.org"
}
}

View File

@@ -195,3 +195,6 @@ void X11EventHandler::handlePointer(int buttonMask, int x, int y)
data->buttonMask = buttonMask;
}
#include "x11events.moc"

View File

@@ -26,7 +26,13 @@
class X11EventHandler : public EventHandler
{
Q_OBJECT
public:
explicit X11EventHandler(QObject *parent = nullptr)
: EventHandler(parent)
{
};
virtual void handleKeyboard(bool down, rfbKeySym key);
virtual void handlePointer(int buttonMask, int x, int y);
};

View File

@@ -11,6 +11,7 @@ include(GenerateExportHeader)
set (krfbprivate_SRCS
framebuffer.cpp
framebufferplugin.cpp
events.cpp
eventsplugin.cpp
)

32
krfb/events.cpp Normal file
View File

@@ -0,0 +1,32 @@
/*
This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "events.h"
EventHandler::EventHandler(QObject *parent)
: QObject(parent)
{
}
#include "events.moc"

View File

@@ -26,13 +26,18 @@
#define EVENTS_H
#include "rfb.h"
#include "krfbprivate_export.h"
class EventHandler
#include <QObject>
class KRFBPRIVATE_EXPORT EventHandler : public QObject
{
Q_OBJECT
public:
explicit EventHandler(QObject *parent = nullptr);
virtual ~EventHandler() = default;
virtual void handleKeyboard(bool down, rfbKeySym key) = 0;
virtual void handlePointer(int buttonMask, int x, int y) = 0;
virtual ~EventHandler() = default;
};
#endif