mirror of
https://github.com/KDE/krfb
synced 2026-07-01 07:41:17 -07:00
Format project
Command used to format: git ls-files | grep -E '\.(cpp|h|hpp|c)$' | xargs clang-format -i --style file
This commit is contained in:
@@ -13,13 +13,13 @@
|
|||||||
#include <QtGui/private/qtx11extras_p.h>
|
#include <QtGui/private/qtx11extras_p.h>
|
||||||
|
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/keysym.h>
|
|
||||||
#include <X11/extensions/XTest.h>
|
#include <X11/extensions/XTest.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LEFTSHIFT = 1,
|
LEFTSHIFT = 1,
|
||||||
RIGHTSHIFT = 2,
|
RIGHTSHIFT = 2,
|
||||||
ALTGR = 4
|
ALTGR = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventData
|
class EventData
|
||||||
@@ -27,7 +27,7 @@ class EventData
|
|||||||
public:
|
public:
|
||||||
EventData();
|
EventData();
|
||||||
|
|
||||||
//keyboard
|
// keyboard
|
||||||
Display *dpy = nullptr;
|
Display *dpy = nullptr;
|
||||||
signed char modifiers[0x100] = {};
|
signed char modifiers[0x100] = {};
|
||||||
KeyCode keycodes[0x100] = {};
|
KeyCode keycodes[0x100] = {};
|
||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
KeyCode altGrCode = 0;
|
KeyCode altGrCode = 0;
|
||||||
char modifierState = 0;
|
char modifierState = 0;
|
||||||
|
|
||||||
//mouse
|
// mouse
|
||||||
int buttonMask = 0;
|
int buttonMask = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
@@ -57,7 +57,7 @@ void EventData::init()
|
|||||||
buttonMask = 0;
|
buttonMask = 0;
|
||||||
|
|
||||||
dpy = QX11Info::display();
|
dpy = QX11Info::display();
|
||||||
//initialize keycodes
|
// initialize keycodes
|
||||||
KeySym key, *keymap;
|
KeySym key, *keymap;
|
||||||
int i, j, minkey, maxkey, syms_per_keycode;
|
int i, j, minkey, maxkey, syms_per_keycode;
|
||||||
|
|
||||||
@@ -66,14 +66,14 @@ void EventData::init()
|
|||||||
XDisplayKeycodes(dpy, &minkey, &maxkey);
|
XDisplayKeycodes(dpy, &minkey, &maxkey);
|
||||||
Q_ASSERT(minkey >= 8);
|
Q_ASSERT(minkey >= 8);
|
||||||
Q_ASSERT(maxkey < 256);
|
Q_ASSERT(maxkey < 256);
|
||||||
keymap = (KeySym *) XGetKeyboardMapping(dpy, minkey,
|
keymap = (KeySym *)XGetKeyboardMapping(dpy, minkey,
|
||||||
(maxkey - minkey + 1),
|
(maxkey - minkey + 1),
|
||||||
&syms_per_keycode);
|
&syms_per_keycode);
|
||||||
Q_ASSERT(keymap);
|
Q_ASSERT(keymap);
|
||||||
|
|
||||||
for (i = minkey; i <= maxkey; i++) {
|
for (i = minkey; i <= maxkey; i++) {
|
||||||
for (j = 0; j < syms_per_keycode; j++) {
|
for (j = 0; j < syms_per_keycode; j++) {
|
||||||
key = keymap[(i-minkey)*syms_per_keycode+j];
|
key = keymap[(i - minkey) * syms_per_keycode + j];
|
||||||
|
|
||||||
if (key >= ' ' && key < 0x100 && i == XKeysymToKeycode(dpy, key)) {
|
if (key >= ' ' && key < 0x100 && i == XKeysymToKeycode(dpy, key)) {
|
||||||
keycodes[key] = i;
|
keycodes[key] = i;
|
||||||
@@ -128,8 +128,13 @@ static void tweakModifiers(signed char mod, bool down)
|
|||||||
|
|
||||||
void X11EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
|
void X11EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
|
||||||
{
|
{
|
||||||
#define ADJUSTMOD(sym,state) \
|
#define ADJUSTMOD(sym, state) \
|
||||||
if(keySym==sym) { if(down) data->modifierState|=state; else data->modifierState&=~state; }
|
if (keySym == sym) { \
|
||||||
|
if (down) \
|
||||||
|
data->modifierState |= state; \
|
||||||
|
else \
|
||||||
|
data->modifierState &= ~state; \
|
||||||
|
}
|
||||||
|
|
||||||
if (QX11Info::isPlatformX11()) {
|
if (QX11Info::isPlatformX11()) {
|
||||||
ADJUSTMOD(XK_Shift_L, LEFTSHIFT);
|
ADJUSTMOD(XK_Shift_L, LEFTSHIFT);
|
||||||
@@ -160,7 +165,7 @@ void X11EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// Wayland platform and pipweire plugin in use
|
// Wayland platform and pipweire plugin in use
|
||||||
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) {
|
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) {
|
||||||
|
|
||||||
@@ -173,10 +178,10 @@ void X11EventHandler::handlePointer(int buttonMask, int x, int y)
|
|||||||
XTestFakeMotionEvent(data->dpy, 0, x, y, CurrentTime);
|
XTestFakeMotionEvent(data->dpy, 0, x, y, CurrentTime);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
if ((data->buttonMask&(1 << i)) != (buttonMask&(1 << i))) {
|
if ((data->buttonMask & (1 << i)) != (buttonMask & (1 << i))) {
|
||||||
XTestFakeButtonEvent(data->dpy,
|
XTestFakeButtonEvent(data->dpy,
|
||||||
i + 1,
|
i + 1,
|
||||||
(buttonMask&(1 << i)) ? True : False,
|
(buttonMask & (1 << i)) ? True : False,
|
||||||
CurrentTime);
|
CurrentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,15 @@
|
|||||||
class X11EventHandler : public EventHandler
|
class X11EventHandler : public EventHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit X11EventHandler(QObject *parent = nullptr)
|
explicit X11EventHandler(QObject *parent = nullptr)
|
||||||
: EventHandler(parent)
|
: EventHandler(parent)
|
||||||
{
|
{
|
||||||
};
|
}
|
||||||
|
|
||||||
void handleKeyboard(bool down, rfbKeySym key) override;
|
void handleKeyboard(bool down, rfbKeySym key) override;
|
||||||
void handlePointer(int buttonMask, int x, int y) override;
|
void handlePointer(int buttonMask, int x, int y) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ X11EventsPlugin::X11EventsPlugin(QObject *parent, const QVariantList &args)
|
|||||||
EventHandler *X11EventsPlugin::eventHandler()
|
EventHandler *X11EventsPlugin::eventHandler()
|
||||||
{
|
{
|
||||||
// works only under X11
|
// works only under X11
|
||||||
if(!QX11Info::isPlatformX11())
|
if (!QX11Info::isPlatformX11()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return new X11EventHandler();
|
return new X11EventHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "x11eventsplugin.moc"
|
#include "x11eventsplugin.moc"
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class EventHandler;
|
|||||||
class X11EventsPlugin : public EventsPlugin
|
class X11EventsPlugin : public EventsPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
X11EventsPlugin(QObject *parent, const QVariantList &args);
|
X11EventsPlugin(QObject *parent, const QVariantList &args);
|
||||||
|
|
||||||
@@ -25,5 +26,4 @@ private:
|
|||||||
Q_DISABLE_COPY(X11EventsPlugin)
|
Q_DISABLE_COPY(X11EventsPlugin)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class EventData
|
|||||||
public:
|
public:
|
||||||
EventData();
|
EventData();
|
||||||
|
|
||||||
//mouse
|
// mouse
|
||||||
int buttonMask = 0;
|
int buttonMask = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
@@ -68,7 +68,7 @@ void XdpEventHandler::handlePointer(int buttonMask, int x, int y)
|
|||||||
|
|
||||||
if (buttonMask != data->buttonMask) {
|
if (buttonMask != data->buttonMask) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
QList<int> buttons = { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, 0, 0, 0, 0, BTN_SIDE, BTN_EXTRA };
|
QList<int> buttons = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, 0, 0, 0, 0, BTN_SIDE, BTN_EXTRA};
|
||||||
for (auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) {
|
for (auto it = buttons.constBegin(); it != buttons.constEnd(); ++it) {
|
||||||
int prevButtonState = (data->buttonMask >> i) & 0x01;
|
int prevButtonState = (data->buttonMask >> i) & 0x01;
|
||||||
int currentButtonState = (buttonMask >> i) & 0x01;
|
int currentButtonState = (buttonMask >> i) & 0x01;
|
||||||
|
|||||||
@@ -14,11 +14,10 @@
|
|||||||
class XdpEventHandler : public EventHandler
|
class XdpEventHandler : public EventHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void handleKeyboard(bool down, rfbKeySym key) override;
|
void handleKeyboard(bool down, rfbKeySym key) override;
|
||||||
void handlePointer(int buttonMask, int x, int y) override;
|
void handlePointer(int buttonMask, int x, int y) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,4 +26,3 @@ EventHandler *XdpEventsPlugin::eventHandler()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "xdpeventsplugin.moc"
|
#include "xdpeventsplugin.moc"
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class EventHandler;
|
|||||||
class XdpEventsPlugin : public EventsPlugin
|
class XdpEventsPlugin : public EventsPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XdpEventsPlugin(QObject *parent, const QVariantList &args);
|
XdpEventsPlugin(QObject *parent, const QVariantList &args);
|
||||||
|
|
||||||
@@ -27,6 +28,4 @@ private:
|
|||||||
Q_DISABLE_COPY(XdpEventsPlugin)
|
Q_DISABLE_COPY(XdpEventsPlugin)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
#include "config-krfb.h"
|
#include "config-krfb.h"
|
||||||
|
|
||||||
// system
|
// system
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
// Qt
|
// Qt
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
#include <QRandomGenerator>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
#include <QDebug>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
|
|
||||||
#include <KConfigGroup>
|
#include <KConfigGroup>
|
||||||
#include <KSharedConfig>
|
#include <KSharedConfig>
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
// pipewire
|
// pipewire
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
|
||||||
#include "pw_framebuffer.h"
|
|
||||||
#include "xdp_dbus_screencast_interface.h"
|
|
||||||
#include "xdp_dbus_remotedesktop_interface.h"
|
|
||||||
#include "krfb_fb_pipewire_debug.h"
|
#include "krfb_fb_pipewire_debug.h"
|
||||||
|
#include "pw_framebuffer.h"
|
||||||
#include "screencasting.h"
|
#include "screencasting.h"
|
||||||
#include <PipeWireSourceStream>
|
#include "xdp_dbus_remotedesktop_interface.h"
|
||||||
|
#include "xdp_dbus_screencast_interface.h"
|
||||||
#include <DmaBufHandler>
|
#include <DmaBufHandler>
|
||||||
|
#include <PipeWireSourceStream>
|
||||||
|
|
||||||
static const int BYTES_PER_PIXEL = 4;
|
static const int BYTES_PER_PIXEL = 4;
|
||||||
static const uint MIN_SUPPORTED_XDP_KDE_SC_VERSION = 1;
|
static const uint MIN_SUPPORTED_XDP_KDE_SC_VERSION = 1;
|
||||||
@@ -42,7 +42,7 @@ static const uint MIN_SUPPORTED_XDP_KDE_SC_VERSION = 1;
|
|||||||
Q_DECLARE_METATYPE(PWFrameBuffer::Stream);
|
Q_DECLARE_METATYPE(PWFrameBuffer::Stream);
|
||||||
Q_DECLARE_METATYPE(PWFrameBuffer::Streams);
|
Q_DECLARE_METATYPE(PWFrameBuffer::Streams);
|
||||||
|
|
||||||
const QDBusArgument &operator >> (const QDBusArgument &arg, PWFrameBuffer::Stream &stream)
|
const QDBusArgument &operator>>(const QDBusArgument &arg, PWFrameBuffer::Stream &stream)
|
||||||
{
|
{
|
||||||
arg.beginStructure();
|
arg.beginStructure();
|
||||||
arg >> stream.nodeId;
|
arg >> stream.nodeId;
|
||||||
@@ -66,7 +66,8 @@ const QDBusArgument &operator >> (const QDBusArgument &arg, PWFrameBuffer::Strea
|
|||||||
* @brief The PWFrameBuffer::Private class - private counterpart of PWFramebuffer class. This is the entity where
|
* @brief The PWFrameBuffer::Private class - private counterpart of PWFramebuffer class. This is the entity where
|
||||||
* whole logic resides, for more info search for "d-pointer pattern" information.
|
* whole logic resides, for more info search for "d-pointer pattern" information.
|
||||||
*/
|
*/
|
||||||
class PWFrameBuffer::Private {
|
class PWFrameBuffer::Private
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
Private(PWFrameBuffer *q);
|
Private(PWFrameBuffer *q);
|
||||||
~Private();
|
~Private();
|
||||||
@@ -111,7 +112,7 @@ PWFrameBuffer::Private::Private(PWFrameBuffer *q)
|
|||||||
: q(q)
|
: q(q)
|
||||||
, stream(new PipeWireSourceStream(q))
|
, stream(new PipeWireSourceStream(q))
|
||||||
{
|
{
|
||||||
QObject::connect(stream.get(), &PipeWireSourceStream::frameReceived, q, [this] (const PipeWireFrame &frame) {
|
QObject::connect(stream.get(), &PipeWireSourceStream::frameReceived, q, [this](const PipeWireFrame &frame) {
|
||||||
handleFrame(frame);
|
handleFrame(frame);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -138,10 +139,9 @@ void PWFrameBuffer::Private::initDbus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create session
|
// create session
|
||||||
auto sessionParameters = QVariantMap {
|
auto sessionParameters = QVariantMap{
|
||||||
{ QStringLiteral("session_handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) },
|
{QStringLiteral("session_handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())},
|
||||||
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
|
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
|
||||||
};
|
|
||||||
auto sessionReply = dbusXdpRemoteDesktopService->CreateSession(sessionParameters);
|
auto sessionReply = dbusXdpRemoteDesktopService->CreateSession(sessionParameters);
|
||||||
sessionReply.waitForFinished();
|
sessionReply.waitForFinished();
|
||||||
if (!sessionReply.isValid()) {
|
if (!sessionReply.isValid()) {
|
||||||
@@ -182,11 +182,11 @@ void PWFrameBuffer::Private::handleSessionCreated(quint32 code, const QVariantMa
|
|||||||
sessionPath = QDBusObjectPath(results.value(QStringLiteral("session_handle")).toString());
|
sessionPath = QDBusObjectPath(results.value(QStringLiteral("session_handle")).toString());
|
||||||
|
|
||||||
// select sources for the session
|
// select sources for the session
|
||||||
auto selectionOptions = QVariantMap {
|
auto selectionOptions = QVariantMap{
|
||||||
// We have to specify it's an uint, otherwise xdg-desktop-portal will not forward it to backend implementation
|
// We have to specify it's an uint, otherwise xdg-desktop-portal will not forward it to backend implementation
|
||||||
{ QStringLiteral("types"), QVariant::fromValue<uint>(7) }, // request all (KeyBoard, Pointer, TouchScreen)
|
{QStringLiteral("types"), QVariant::fromValue<uint>(7)}, // request all (KeyBoard, Pointer, TouchScreen)
|
||||||
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) },
|
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())},
|
||||||
{ QStringLiteral("persist_mode"), QVariant::fromValue<uint>(2) }, // Persist permission until explicitly revoked by user
|
{QStringLiteral("persist_mode"), QVariant::fromValue<uint>(2)}, // Persist permission until explicitly revoked by user
|
||||||
};
|
};
|
||||||
|
|
||||||
KConfigGroup stateConfig = KSharedConfig::openStateConfig()->group(QStringLiteral("XdgPortal"));
|
KConfigGroup stateConfig = KSharedConfig::openStateConfig()->group(QStringLiteral("XdgPortal"));
|
||||||
@@ -231,11 +231,10 @@ void PWFrameBuffer::Private::handleDevicesSelected(quint32 code, const QVariantM
|
|||||||
}
|
}
|
||||||
|
|
||||||
// select sources for the session
|
// select sources for the session
|
||||||
auto selectionOptions = QVariantMap {
|
auto selectionOptions = QVariantMap{
|
||||||
{ QStringLiteral("types"), QVariant::fromValue<uint>(1) }, // only MONITOR is supported
|
{QStringLiteral("types"), QVariant::fromValue<uint>(1)}, // only MONITOR is supported
|
||||||
{ QStringLiteral("multiple"), false },
|
{QStringLiteral("multiple"), false},
|
||||||
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
|
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
|
||||||
};
|
|
||||||
auto selectorReply = dbusXdpScreenCastService->SelectSources(sessionPath, selectionOptions);
|
auto selectorReply = dbusXdpScreenCastService->SelectSources(sessionPath, selectionOptions);
|
||||||
selectorReply.waitForFinished();
|
selectorReply.waitForFinished();
|
||||||
if (!selectorReply.isValid()) {
|
if (!selectorReply.isValid()) {
|
||||||
@@ -273,9 +272,8 @@ void PWFrameBuffer::Private::handleSourcesSelected(quint32 code, const QVariantM
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start session
|
// start session
|
||||||
auto startParameters = QVariantMap {
|
auto startParameters = QVariantMap{
|
||||||
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
|
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
|
||||||
};
|
|
||||||
auto startReply = dbusXdpRemoteDesktopService->Start(sessionPath, QString(), startParameters);
|
auto startReply = dbusXdpRemoteDesktopService->Start(sessionPath, QString(), startParameters);
|
||||||
startReply.waitForFinished();
|
startReply.waitForFinished();
|
||||||
QDBusConnection::sessionBus().connect(QString(),
|
QDBusConnection::sessionBus().connect(QString(),
|
||||||
@@ -286,7 +284,6 @@ void PWFrameBuffer::Private::handleSourcesSelected(quint32 code, const QVariantM
|
|||||||
SLOT(handleXdpRemoteDesktopStarted(uint, QVariantMap)));
|
SLOT(handleXdpRemoteDesktopStarted(uint, QVariantMap)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PWFrameBuffer::handleXdpRemoteDesktopStarted(quint32 code, const QVariantMap &results)
|
void PWFrameBuffer::handleXdpRemoteDesktopStarted(quint32 code, const QVariantMap &results)
|
||||||
{
|
{
|
||||||
d->handleRemoteDesktopStarted(code, results);
|
d->handleRemoteDesktopStarted(code, results);
|
||||||
@@ -376,9 +373,9 @@ void PWFrameBuffer::Private::handleFrame(const PipeWireFrame &frame)
|
|||||||
#endif
|
#endif
|
||||||
else if (frame.dmabuf) {
|
else if (frame.dmabuf) {
|
||||||
// FIXME: Assuming stride == width * 4, not sure to which extent this holds
|
// FIXME: Assuming stride == width * 4, not sure to which extent this holds
|
||||||
const QSize size = { frame.dmabuf->width, frame.dmabuf->height };
|
const QSize size = {frame.dmabuf->width, frame.dmabuf->height};
|
||||||
setVideoSize(size);
|
setVideoSize(size);
|
||||||
QImage src(reinterpret_cast<uchar*>(q->fb), size.width(), size.height(), QImage::Format_RGB32);
|
QImage src(reinterpret_cast<uchar *>(q->fb), size.width(), size.height(), QImage::Format_RGB32);
|
||||||
if (!m_dmabufHandler.downloadFrame(src, frame)) {
|
if (!m_dmabufHandler.downloadFrame(src, frame)) {
|
||||||
stream->renegotiateModifierFailed(frame.format, frame.dmabuf->modifier);
|
stream->renegotiateModifierFailed(frame.format, frame.dmabuf->modifier);
|
||||||
qCDebug(KRFB_FB_PIPEWIRE) << "Failed to download frame.";
|
qCDebug(KRFB_FB_PIPEWIRE) << "Failed to download frame.";
|
||||||
@@ -404,7 +401,7 @@ void PWFrameBuffer::Private::setVideoSize(const QSize &size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(q->fb);
|
free(q->fb);
|
||||||
q->fb = static_cast<char*>(malloc(size.width() * size.height() * BYTES_PER_PIXEL));
|
q->fb = static_cast<char *>(malloc(size.width() * size.height() * BYTES_PER_PIXEL));
|
||||||
if (!q->fb) {
|
if (!q->fb) {
|
||||||
qCWarning(KRFB_FB_PIPEWIRE) << "Failed to allocate buffer";
|
qCWarning(KRFB_FB_PIPEWIRE) << "Failed to allocate buffer";
|
||||||
isValid = false;
|
isValid = false;
|
||||||
@@ -420,8 +417,8 @@ PWFrameBuffer::Private::~Private()
|
|||||||
}
|
}
|
||||||
|
|
||||||
PWFrameBuffer::PWFrameBuffer(QObject *parent)
|
PWFrameBuffer::PWFrameBuffer(QObject *parent)
|
||||||
: FrameBuffer (parent),
|
: FrameBuffer(parent)
|
||||||
d(new Private(this))
|
, d(new Private(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +433,7 @@ void PWFrameBuffer::initDBus()
|
|||||||
d->initDbus();
|
d->initDbus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PWFrameBuffer::startVirtualMonitor(const QString& name, const QSize& resolution, qreal dpr)
|
void PWFrameBuffer::startVirtualMonitor(const QString &name, const QSize &resolution, qreal dpr)
|
||||||
{
|
{
|
||||||
d->videoSize = resolution * dpr;
|
d->videoSize = resolution * dpr;
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
@@ -448,13 +445,14 @@ void PWFrameBuffer::startVirtualMonitor(const QString& name, const QSize& resolu
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto registry = new Registry(this);
|
auto registry = new Registry(this);
|
||||||
connect(registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this, registry, name, dpr, resolution] (const QByteArray &interfaceName, quint32 wlname, quint32 version) {
|
connect(registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this, registry, name, dpr, resolution](const QByteArray &interfaceName, quint32 wlname, quint32 version) {
|
||||||
if (interfaceName != "zkde_screencast_unstable_v1")
|
if (interfaceName != "zkde_screencast_unstable_v1") {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto screencasting = new Screencasting(registry, wlname, version, this);
|
auto screencasting = new Screencasting(registry, wlname, version, this);
|
||||||
auto r = screencasting->createVirtualMonitorStream(name, resolution, dpr, Screencasting::Metadata);
|
auto r = screencasting->createVirtualMonitorStream(name, resolution, dpr, Screencasting::Metadata);
|
||||||
connect(r, &ScreencastingStream::created, this, [this] (quint32 nodeId) {
|
connect(r, &ScreencastingStream::created, this, [this](quint32 nodeId) {
|
||||||
d->stream->createStream(nodeId, 0);
|
d->stream->createStream(nodeId, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -498,19 +496,18 @@ void PWFrameBuffer::getServerFormat(rfbPixelFormat &format)
|
|||||||
|
|
||||||
void PWFrameBuffer::startMonitor()
|
void PWFrameBuffer::startMonitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PWFrameBuffer::stopMonitor()
|
void PWFrameBuffer::stopMonitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant PWFrameBuffer::customProperty(const QString &property) const
|
QVariant PWFrameBuffer::customProperty(const QString &property) const
|
||||||
{
|
{
|
||||||
if (property == QLatin1String("stream_node_id")) {
|
if (property == QLatin1String("stream_node_id")) {
|
||||||
return QVariant::fromValue<uint>(d->stream->nodeId());
|
return QVariant::fromValue<uint>(d->stream->nodeId());
|
||||||
} if (property == QLatin1String("session_handle")) {
|
}
|
||||||
|
if (property == QLatin1String("session_handle")) {
|
||||||
return QVariant::fromValue<QDBusObjectPath>(d->sessionPath);
|
return QVariant::fromValue<QDBusObjectPath>(d->sessionPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
|
#define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
|
||||||
|
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include <QWidget>
|
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The PWFrameBuffer class - framebuffer implementation based on XDG Desktop Portal ScreenCast interface.
|
* @brief The PWFrameBuffer class - framebuffer implementation based on XDG Desktop Portal ScreenCast interface.
|
||||||
@@ -17,11 +17,13 @@
|
|||||||
*
|
*
|
||||||
* @author Oleg Chernovskiy <kanedias@xaker.ru>
|
* @author Oleg Chernovskiy <kanedias@xaker.ru>
|
||||||
*/
|
*/
|
||||||
class PWFrameBuffer: public FrameBuffer
|
class PWFrameBuffer : public FrameBuffer
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Stream = struct {
|
using Stream = struct
|
||||||
|
{
|
||||||
uint nodeId;
|
uint nodeId;
|
||||||
QVariantMap map;
|
QVariantMap map;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "pw_framebufferplugin.h"
|
#include "pw_framebufferplugin.h"
|
||||||
#include "pw_framebuffer.h"
|
#include "pw_framebuffer.h"
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
@@ -16,7 +15,6 @@ PWFrameBufferPlugin::PWFrameBufferPlugin(QObject *parent, const QVariantList &ar
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FrameBuffer *PWFrameBufferPlugin::frameBuffer(const QVariantMap &args)
|
FrameBuffer *PWFrameBufferPlugin::frameBuffer(const QVariantMap &args)
|
||||||
{
|
{
|
||||||
auto pwfb = new PWFrameBuffer;
|
auto pwfb = new PWFrameBuffer;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* This file is part of the KDE project
|
/* This file is part of the KDE project
|
||||||
SPDX-FileCopyrightText: 2018 Oleg Chernovskiy <kanedias@xaker.ru>
|
SPDX-FileCopyrightText: 2018 Oleg Chernovskiy <kanedias@xaker.ru>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
@@ -7,12 +7,11 @@
|
|||||||
#ifndef KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
|
#ifndef KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
|
||||||
#define KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
|
#define KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
|
||||||
|
|
||||||
|
|
||||||
#include "framebufferplugin.h"
|
#include "framebufferplugin.h"
|
||||||
|
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
|
|
||||||
class PWFrameBufferPlugin: public FrameBufferPlugin
|
class PWFrameBufferPlugin : public FrameBufferPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -25,5 +24,4 @@ private:
|
|||||||
Q_DISABLE_COPY(PWFrameBufferPlugin)
|
Q_DISABLE_COPY(PWFrameBufferPlugin)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <KWayland/Client/registry.h>
|
#include <KWayland/Client/registry.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRect>
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QRect>
|
||||||
|
|
||||||
using namespace KWayland::Client;
|
using namespace KWayland::Client;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ Screencasting::Screencasting(Registry *registry, int id, int version, QObject *p
|
|||||||
|
|
||||||
Screencasting::~Screencasting() = default;
|
Screencasting::~Screencasting() = default;
|
||||||
|
|
||||||
ScreencastingStream * Screencasting::createVirtualMonitorStream(const QString& name, const QSize& resolution, qreal dpr, Screencasting::CursorMode mode)
|
ScreencastingStream *Screencasting::createVirtualMonitorStream(const QString &name, const QSize &resolution, qreal dpr, Screencasting::CursorMode mode)
|
||||||
{
|
{
|
||||||
auto stream = new ScreencastingStream(this);
|
auto stream = new ScreencastingStream(this);
|
||||||
stream->d->init(d->stream_virtual_output(name, resolution.width(), resolution.height(), wl_fixed_from_double(dpr), mode));
|
stream->d->init(d->stream_virtual_output(name, resolution.width(), resolution.height(), wl_fixed_from_double(dpr), mode));
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QList>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
struct zkde_screencast_unstable_v1;
|
struct zkde_screencast_unstable_v1;
|
||||||
@@ -17,9 +17,11 @@ namespace KWayland
|
|||||||
{
|
{
|
||||||
namespace Client
|
namespace Client
|
||||||
{
|
{
|
||||||
|
|
||||||
class PlasmaWindow;
|
class PlasmaWindow;
|
||||||
class Registry;
|
class Registry;
|
||||||
class Output;
|
class Output;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ class ScreencastingStreamPrivate;
|
|||||||
class ScreencastingStream : public QObject
|
class ScreencastingStream : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScreencastingStream(QObject *parent);
|
ScreencastingStream(QObject *parent);
|
||||||
~ScreencastingStream() override;
|
~ScreencastingStream() override;
|
||||||
@@ -48,6 +51,7 @@ private:
|
|||||||
class Screencasting : public QObject
|
class Screencasting : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Screencasting(QObject *parent = nullptr);
|
explicit Screencasting(QObject *parent = nullptr);
|
||||||
explicit Screencasting(KWayland::Client::Registry *registry, int id, int version, QObject *parent = nullptr);
|
explicit Screencasting(KWayland::Client::Registry *registry, int id, int version, QObject *parent = nullptr);
|
||||||
|
|||||||
@@ -7,22 +7,22 @@
|
|||||||
#include "xcb_framebuffer.h"
|
#include "xcb_framebuffer.h"
|
||||||
#include "krfb_fb_xcb_debug.h"
|
#include "krfb_fb_xcb_debug.h"
|
||||||
|
|
||||||
#include <xcb/xproto.h>
|
|
||||||
#include <xcb/damage.h>
|
#include <xcb/damage.h>
|
||||||
#include <xcb/shm.h>
|
#include <xcb/shm.h>
|
||||||
#include <xcb/xcb_image.h>
|
#include <xcb/xcb_image.h>
|
||||||
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
|
||||||
|
#include <QAbstractNativeEventFilter>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QAbstractNativeEventFilter>
|
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
|
||||||
#include <QtGui/private/qtx11extras_p.h>
|
#include <QtGui/private/qtx11extras_p.h>
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
||||||
class KrfbXCBEventFilter: public QAbstractNativeEventFilter
|
class KrfbXCBEventFilter : public QAbstractNativeEventFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KrfbXCBEventFilter(XCBFrameBuffer *owner);
|
KrfbXCBEventFilter(XCBFrameBuffer *owner);
|
||||||
@@ -39,12 +39,13 @@ public:
|
|||||||
XCBFrameBuffer *fb_owner;
|
XCBFrameBuffer *fb_owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner)
|
||||||
|
: xdamageBaseEvent(0)
|
||||||
KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
|
, xdamageBaseError(0)
|
||||||
xdamageBaseEvent(0), xdamageBaseError(0),
|
, xshmBaseEvent(0)
|
||||||
xshmBaseEvent(0), xshmBaseError(0), xshmAvail(false),
|
, xshmBaseError(0)
|
||||||
fb_owner(owner)
|
, xshmAvail(false)
|
||||||
|
, fb_owner(owner)
|
||||||
{
|
{
|
||||||
const xcb_query_extension_reply_t *xdamage_data = xcb_get_extension_data(
|
const xcb_query_extension_reply_t *xdamage_data = xcb_get_extension_data(
|
||||||
QX11Info::connection(), &xcb_damage_id);
|
QX11Info::connection(), &xcb_damage_id);
|
||||||
@@ -64,8 +65,7 @@ KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: XDamage extension version:" <<
|
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: XDamage extension version:" << xdamage_version->major_version << "." << xdamage_version->minor_version;
|
||||||
xdamage_version->major_version << "." << xdamage_version->minor_version;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(xdamage_version);
|
free(xdamage_version);
|
||||||
@@ -93,12 +93,14 @@ KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
|
bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
|
||||||
void *message, qintptr *result) {
|
void *message, qintptr *result)
|
||||||
|
{
|
||||||
Q_UNUSED(result); // "result" is only used on windows
|
Q_UNUSED(result); // "result" is only used on windows
|
||||||
|
|
||||||
if (xdamageBaseEvent == 0) return false; // no xdamage extension
|
if (xdamageBaseEvent == 0) {
|
||||||
|
return false; // no xdamage extension
|
||||||
|
}
|
||||||
|
|
||||||
if (eventType == "xcb_generic_event_t") {
|
if (eventType == "xcb_generic_event_t") {
|
||||||
auto ev = static_cast<xcb_generic_event_t *>(message);
|
auto ev = static_cast<xcb_generic_event_t *>(message);
|
||||||
@@ -113,8 +115,8 @@ bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class XCBFrameBuffer::P
|
||||||
class XCBFrameBuffer::P {
|
{
|
||||||
public:
|
public:
|
||||||
xcb_damage_damage_t damage;
|
xcb_damage_damage_t damage;
|
||||||
xcb_shm_segment_info_t shminfo;
|
xcb_shm_segment_info_t shminfo;
|
||||||
@@ -130,20 +132,21 @@ public:
|
|||||||
WId win;
|
WId win;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static xcb_screen_t *get_xcb_screen(xcb_connection_t *conn, int screen_num)
|
||||||
static xcb_screen_t *get_xcb_screen(xcb_connection_t *conn, int screen_num) {
|
{
|
||||||
xcb_screen_t *screen = nullptr;
|
xcb_screen_t *screen = nullptr;
|
||||||
xcb_screen_iterator_t screens_iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
|
xcb_screen_iterator_t screens_iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
|
||||||
for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter))
|
for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter)) {
|
||||||
if (screen_num == 0)
|
if (screen_num == 0) {
|
||||||
screen = screens_iter.data;
|
screen = screens_iter.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XCBFrameBuffer::XCBFrameBuffer(QObject *parent)
|
||||||
|
: FrameBuffer(parent)
|
||||||
XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
|
, d(new XCBFrameBuffer::P)
|
||||||
FrameBuffer(parent), d(new XCBFrameBuffer::P)
|
|
||||||
{
|
{
|
||||||
d->running = false;
|
d->running = false;
|
||||||
d->damage = XCB_NONE;
|
d->damage = XCB_NONE;
|
||||||
@@ -160,11 +163,11 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
|
|||||||
|
|
||||||
QScreen *primaryScreen = QGuiApplication::primaryScreen();
|
QScreen *primaryScreen = QGuiApplication::primaryScreen();
|
||||||
if (primaryScreen) {
|
if (primaryScreen) {
|
||||||
QPlatformNativeInterface* native = qApp->platformNativeInterface();
|
QPlatformNativeInterface *native = qApp->platformNativeInterface();
|
||||||
d->win = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), primaryScreen));
|
d->win = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), primaryScreen));
|
||||||
qreal scaleFactor = primaryScreen->devicePixelRatio();
|
qreal scaleFactor = primaryScreen->devicePixelRatio();
|
||||||
d->area = { primaryScreen->geometry().topLeft() * scaleFactor,
|
d->area = {primaryScreen->geometry().topLeft() * scaleFactor,
|
||||||
primaryScreen->geometry().bottomRight() * scaleFactor };
|
primaryScreen->geometry().bottomRight() * scaleFactor};
|
||||||
|
|
||||||
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: Primary screen: " << primaryScreen->name()
|
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: Primary screen: " << primaryScreen->name()
|
||||||
<< ", geometry: " << primaryScreen->geometry()
|
<< ", geometry: " << primaryScreen->geometry()
|
||||||
@@ -285,8 +288,8 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
|
|||||||
QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter);
|
QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XCBFrameBuffer::~XCBFrameBuffer()
|
||||||
XCBFrameBuffer::~XCBFrameBuffer() {
|
{
|
||||||
// first - uninstall x11 event filter
|
// first - uninstall x11 event filter
|
||||||
QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter);
|
QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter);
|
||||||
//
|
//
|
||||||
@@ -296,13 +299,16 @@ XCBFrameBuffer::~XCBFrameBuffer() {
|
|||||||
}
|
}
|
||||||
if (d->x11EvtFilter->xshmAvail) {
|
if (d->x11EvtFilter->xshmAvail) {
|
||||||
// detach shared memory
|
// detach shared memory
|
||||||
if (d->shminfo.shmseg != XCB_NONE)
|
if (d->shminfo.shmseg != XCB_NONE) {
|
||||||
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); // detach from X server
|
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); // detach from X server
|
||||||
if (d->shminfo.shmaddr)
|
}
|
||||||
|
if (d->shminfo.shmaddr) {
|
||||||
shmdt(d->shminfo.shmaddr); // detach addr from our address space
|
shmdt(d->shminfo.shmaddr); // detach addr from our address space
|
||||||
if (d->shminfo.shmid != XCB_NONE)
|
}
|
||||||
|
if (d->shminfo.shmid != XCB_NONE) {
|
||||||
shmctl(d->shminfo.shmid, IPC_RMID, nullptr); // mark shm segment as removed
|
shmctl(d->shminfo.shmid, IPC_RMID, nullptr); // mark shm segment as removed
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// and delete image used for shared mem
|
// and delete image used for shared mem
|
||||||
if (d->updateTile) {
|
if (d->updateTile) {
|
||||||
d->updateTile->base = nullptr;
|
d->updateTile->base = nullptr;
|
||||||
@@ -316,40 +322,43 @@ XCBFrameBuffer::~XCBFrameBuffer() {
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XCBFrameBuffer::depth()
|
||||||
int XCBFrameBuffer::depth() {
|
{
|
||||||
if (d->framebufferImage) {
|
if (d->framebufferImage) {
|
||||||
return d->framebufferImage->depth;
|
return d->framebufferImage->depth;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XCBFrameBuffer::height()
|
||||||
int XCBFrameBuffer::height() {
|
{
|
||||||
if (d->framebufferImage) {
|
if (d->framebufferImage) {
|
||||||
return d->framebufferImage->height;
|
return d->framebufferImage->height;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int XCBFrameBuffer::width()
|
||||||
int XCBFrameBuffer::width() {
|
{
|
||||||
if (d->framebufferImage) {
|
if (d->framebufferImage) {
|
||||||
return d->framebufferImage->width;
|
return d->framebufferImage->width;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int XCBFrameBuffer::paddedWidth() {
|
int XCBFrameBuffer::paddedWidth()
|
||||||
|
{
|
||||||
if (d->framebufferImage) {
|
if (d->framebufferImage) {
|
||||||
return d->framebufferImage->stride;
|
return d->framebufferImage->stride;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format)
|
||||||
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
|
{
|
||||||
if (!d->framebufferImage) return;
|
if (!d->framebufferImage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get information about XCB visual params
|
// get information about XCB visual params
|
||||||
xcb_visualtype_t *root_visualtype = nullptr; // visual info
|
xcb_visualtype_t *root_visualtype = nullptr; // visual info
|
||||||
@@ -374,7 +383,6 @@ void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fill in format common info
|
// fill in format common info
|
||||||
format.bitsPerPixel = d->framebufferImage->bpp;
|
format.bitsPerPixel = d->framebufferImage->bpp;
|
||||||
format.depth = d->framebufferImage->depth;
|
format.depth = d->framebufferImage->depth;
|
||||||
@@ -428,8 +436,7 @@ void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
|
|||||||
" Calculated greenShift = %d\n"
|
" Calculated greenShift = %d\n"
|
||||||
" Calculated blueShift = %d\n"
|
" Calculated blueShift = %d\n"
|
||||||
" Calculated max values: R%d G%d B%d",
|
" Calculated max values: R%d G%d B%d",
|
||||||
format.redShift, format.greenShift, format.blueShift
|
format.redShift, format.greenShift, format.blueShift format.redMax, format.greenMax, format.blueMax);
|
||||||
format.redMax, format.greenMax, format.blueMax);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// some kind of fallback (unlikely code execution will go this way)
|
// some kind of fallback (unlikely code execution will go this way)
|
||||||
@@ -461,14 +468,14 @@ void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function contents was taken from X11 framebuffer source code.
|
* This function contents was taken from X11 framebuffer source code.
|
||||||
* It simply several intersecting rectangles into one bigger rect.
|
* It simply several intersecting rectangles into one bigger rect.
|
||||||
* Non-intersecting rects are treated as different rects and exist
|
* Non-intersecting rects are treated as different rects and exist
|
||||||
* separately in this->tiles QList.
|
* separately in this->tiles QList.
|
||||||
*/
|
*/
|
||||||
void XCBFrameBuffer::cleanupRects() {
|
void XCBFrameBuffer::cleanupRects()
|
||||||
|
{
|
||||||
QList<QRect> cpy = tiles;
|
QList<QRect> cpy = tiles;
|
||||||
bool inserted = false;
|
bool inserted = false;
|
||||||
tiles.clear();
|
tiles.clear();
|
||||||
@@ -477,7 +484,9 @@ void XCBFrameBuffer::cleanupRects() {
|
|||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
const QRect &r = iter.next();
|
const QRect &r = iter.next();
|
||||||
// skip rects not intersecting with primary monitor
|
// skip rects not intersecting with primary monitor
|
||||||
if (!r.intersects(d->area)) continue;
|
if (!r.intersects(d->area)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// only take intersection of this rect with primary monitor rect
|
// only take intersection of this rect with primary monitor rect
|
||||||
QRect ri = r.intersected(d->area);
|
QRect ri = r.intersected(d->area);
|
||||||
|
|
||||||
@@ -525,13 +534,13 @@ void XCBFrameBuffer::cleanupRects() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called by RfbServerManager::updateScreens()
|
* This function is called by RfbServerManager::updateScreens()
|
||||||
* approximately every 50ms (!!), driven by QTimer to get all
|
* approximately every 50ms (!!), driven by QTimer to get all
|
||||||
* modified rectangles on the screen
|
* modified rectangles on the screen
|
||||||
*/
|
*/
|
||||||
QList<QRect> XCBFrameBuffer::modifiedTiles() {
|
QList<QRect> XCBFrameBuffer::modifiedTiles()
|
||||||
|
{
|
||||||
QList<QRect> ret;
|
QList<QRect> ret;
|
||||||
if (!d->running) {
|
if (!d->running) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -541,10 +550,9 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
|
|||||||
|
|
||||||
if (tiles.size() > 0) {
|
if (tiles.size() > 0) {
|
||||||
if (d->x11EvtFilter->xshmAvail) {
|
if (d->x11EvtFilter->xshmAvail) {
|
||||||
|
|
||||||
// loop over all damage rectangles gathered up to this time
|
// loop over all damage rectangles gathered up to this time
|
||||||
QListIterator<QRect> iter(tiles);
|
QListIterator<QRect> iter(tiles);
|
||||||
//foreach(const QRect &r, tiles) {
|
// foreach(const QRect &r, tiles) {
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
const QRect &r = iter.next();
|
const QRect &r = iter.next();
|
||||||
|
|
||||||
@@ -604,7 +612,7 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
|
|||||||
} else {
|
} else {
|
||||||
// not using shared memory
|
// not using shared memory
|
||||||
// will use just xcb_image_get() and copy pixels
|
// will use just xcb_image_get() and copy pixels
|
||||||
for (const QRect& r : std::as_const(tiles)) {
|
for (const QRect &r : std::as_const(tiles)) {
|
||||||
// I did not find XGetSubImage() analog in XCB!!
|
// I did not find XGetSubImage() analog in XCB!!
|
||||||
// need function that copies pixels from one image to another
|
// need function that copies pixels from one image to another
|
||||||
xcb_image_t *damagedImage = xcb_image_get(
|
xcb_image_t *damagedImage = xcb_image_get(
|
||||||
@@ -638,14 +646,16 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
|
|||||||
// ^^ If we clear here all our known "damage areas", then we can also clear
|
// ^^ If we clear here all our known "damage areas", then we can also clear
|
||||||
// damaged area for xdamage? No, we don't need to in our case
|
// damaged area for xdamage? No, we don't need to in our case
|
||||||
// (XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES report mode)
|
// (XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES report mode)
|
||||||
//xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
|
// xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XCBFrameBuffer::startMonitor()
|
||||||
void XCBFrameBuffer::startMonitor() {
|
{
|
||||||
if (d->running) return;
|
if (d->running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
d->running = true;
|
d->running = true;
|
||||||
d->damage = xcb_generate_id(QX11Info::connection());
|
d->damage = xcb_generate_id(QX11Info::connection());
|
||||||
@@ -655,17 +665,18 @@ void XCBFrameBuffer::startMonitor() {
|
|||||||
// (currently) we do not call xcb_damage_subtract() EVER, because
|
// (currently) we do not call xcb_damage_subtract() EVER, because
|
||||||
// RAW rectangles are reported. every time some area of the screen
|
// RAW rectangles are reported. every time some area of the screen
|
||||||
// was changed, we get only that rectangle
|
// was changed, we get only that rectangle
|
||||||
//xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
|
// xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XCBFrameBuffer::stopMonitor()
|
||||||
void XCBFrameBuffer::stopMonitor() {
|
{
|
||||||
if (!d->running) return;
|
if (!d->running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
d->running = false;
|
d->running = false;
|
||||||
xcb_damage_destroy(QX11Info::connection(), d->damage);
|
xcb_damage_destroy(QX11Info::connection(), d->damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// void XCBFrameBuffer::acquireEvents() {} // this function was totally unused
|
// void XCBFrameBuffer::acquireEvents() {} // this function was totally unused
|
||||||
// in X11 framebuffer, but it was the only function where XDamageSubtract() was called?
|
// in X11 framebuffer, but it was the only function where XDamageSubtract() was called?
|
||||||
// Also it had a blocking event loop like:
|
// Also it had a blocking event loop like:
|
||||||
@@ -679,12 +690,11 @@ void XCBFrameBuffer::stopMonitor() {
|
|||||||
// This loop takes all available Xdamage events from queue, and ends if there are no
|
// This loop takes all available Xdamage events from queue, and ends if there are no
|
||||||
// more such events in input queue.
|
// more such events in input queue.
|
||||||
|
|
||||||
|
void XCBFrameBuffer::handleXDamageNotify(xcb_generic_event_t *xevent)
|
||||||
void XCBFrameBuffer::handleXDamageNotify(xcb_generic_event_t *xevent) {
|
{
|
||||||
auto xdevt = (xcb_damage_notify_event_t *)xevent;
|
auto xdevt = (xcb_damage_notify_event_t *)xevent;
|
||||||
|
|
||||||
QRect r((int)xdevt->area.x, (int)xdevt->area.y,
|
QRect r((int)xdevt->area.x, (int)xdevt->area.y,
|
||||||
(int)xdevt->area.width, (int)xdevt->area.height);
|
(int)xdevt->area.width, (int)xdevt->area.height);
|
||||||
this->tiles.append(r);
|
this->tiles.append(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,13 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@author Alexey Min <alexey.min@gmail.com>
|
@author Alexey Min <alexey.min@gmail.com>
|
||||||
*/
|
*/
|
||||||
class XCBFrameBuffer: public FrameBuffer
|
class XCBFrameBuffer : public FrameBuffer
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit XCBFrameBuffer(QObject *parent = nullptr);
|
explicit XCBFrameBuffer(QObject *parent = nullptr);
|
||||||
~XCBFrameBuffer() override;
|
~XCBFrameBuffer() override;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "xcb_framebufferplugin.h"
|
#include "xcb_framebufferplugin.h"
|
||||||
#include "xcb_framebuffer.h"
|
#include "xcb_framebuffer.h"
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
@@ -23,4 +22,3 @@ FrameBuffer *XCBFrameBufferPlugin::frameBuffer(const QVariantMap &args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "xcb_framebufferplugin.moc"
|
#include "xcb_framebufferplugin.moc"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* This file is part of the KDE project
|
/* This file is part of the KDE project
|
||||||
SPDX-FileCopyrightText: Alexey Min <alexey.min@gmail.com>
|
SPDX-FileCopyrightText: Alexey Min <alexey.min@gmail.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
@@ -7,14 +7,12 @@
|
|||||||
#ifndef KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
|
#ifndef KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
|
||||||
#define KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
|
#define KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
|
||||||
|
|
||||||
|
|
||||||
#include "framebufferplugin.h"
|
#include "framebufferplugin.h"
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
|
|
||||||
class XCBFrameBufferPlugin: public FrameBufferPlugin
|
class XCBFrameBufferPlugin : public FrameBufferPlugin
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -27,5 +25,4 @@ private:
|
|||||||
Q_DISABLE_COPY(XCBFrameBufferPlugin)
|
Q_DISABLE_COPY(XCBFrameBufferPlugin)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|||||||
@@ -11,20 +11,20 @@
|
|||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KGuiItem>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KStandardGuiItem>
|
#include <KStandardGuiItem>
|
||||||
#include <KConfigGroup>
|
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <KGuiItem>
|
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
template <typename UI>
|
template<typename UI>
|
||||||
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
|
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
{
|
{
|
||||||
setWindowTitle(i18n("New Connection"));
|
setWindowTitle(i18n("New Connection"));
|
||||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
auto mainWidget = new QWidget(this);
|
auto mainWidget = new QWidget(this);
|
||||||
auto mainLayout = new QVBoxLayout;
|
auto mainLayout = new QVBoxLayout;
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|||||||
@@ -12,12 +12,14 @@
|
|||||||
#include "ui_connectionwidget.h"
|
#include "ui_connectionwidget.h"
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
template <typename UI>
|
template<typename UI>
|
||||||
class ConnectionDialog : public QDialog
|
class ConnectionDialog : public QDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ConnectionDialog(QWidget *parent);
|
explicit ConnectionDialog(QWidget *parent);
|
||||||
~ConnectionDialog() override {};
|
~ConnectionDialog() override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void setAllowRemoteControl(bool b);
|
void setAllowRemoteControl(bool b);
|
||||||
bool allowRemoteControl();
|
bool allowRemoteControl();
|
||||||
@@ -27,14 +29,14 @@ protected:
|
|||||||
UI m_ui;
|
UI m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename UI>
|
template<typename UI>
|
||||||
void ConnectionDialog<UI>::setAllowRemoteControl(bool b)
|
void ConnectionDialog<UI>::setAllowRemoteControl(bool b)
|
||||||
{
|
{
|
||||||
m_ui.cbAllowRemoteControl->setChecked(b);
|
m_ui.cbAllowRemoteControl->setChecked(b);
|
||||||
m_ui.cbAllowRemoteControl->setVisible(b);
|
m_ui.cbAllowRemoteControl->setVisible(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename UI>
|
template<typename UI>
|
||||||
bool ConnectionDialog<UI>::allowRemoteControl()
|
bool ConnectionDialog<UI>::allowRemoteControl()
|
||||||
{
|
{
|
||||||
return m_ui.cbAllowRemoteControl->isChecked();
|
return m_ui.cbAllowRemoteControl->isChecked();
|
||||||
@@ -45,12 +47,12 @@ bool ConnectionDialog<UI>::allowRemoteControl()
|
|||||||
class InvitationsConnectionDialog : public ConnectionDialog<Ui::ConnectionWidget>
|
class InvitationsConnectionDialog : public ConnectionDialog<Ui::ConnectionWidget>
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit InvitationsConnectionDialog(QWidget *parent);
|
explicit InvitationsConnectionDialog(QWidget *parent);
|
||||||
void setRemoteHost(const QString & host);
|
void setRemoteHost(const QString &host);
|
||||||
};
|
};
|
||||||
|
|
||||||
//*********
|
//*********
|
||||||
|
|
||||||
#endif // CONNECTIONDIALOG_H
|
#endif // CONNECTIONDIALOG_H
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,15 @@
|
|||||||
#define EVENTS_H
|
#define EVENTS_H
|
||||||
|
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
#include "rfb.h"
|
|
||||||
#include "krfbprivate_export.h"
|
#include "krfbprivate_export.h"
|
||||||
|
#include "rfb.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class KRFBPRIVATE_EXPORT EventHandler : public QObject
|
class KRFBPRIVATE_EXPORT EventHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EventHandler(QObject *parent = nullptr);
|
explicit EventHandler(QObject *parent = nullptr);
|
||||||
~EventHandler() override = default;
|
~EventHandler() override = default;
|
||||||
@@ -29,6 +30,7 @@ public:
|
|||||||
|
|
||||||
void setFrameBufferPlugin(const QSharedPointer<FrameBuffer> &frameBuffer);
|
void setFrameBufferPlugin(const QSharedPointer<FrameBuffer> &frameBuffer);
|
||||||
QSharedPointer<FrameBuffer> frameBuffer();
|
QSharedPointer<FrameBuffer> frameBuffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Used to track framebuffer plugin which we need for xdp event plugin
|
// Used to track framebuffer plugin which we need for xdp event plugin
|
||||||
QSharedPointer<FrameBuffer> fb;
|
QSharedPointer<FrameBuffer> fb;
|
||||||
|
|||||||
@@ -9,15 +9,14 @@
|
|||||||
|
|
||||||
#include "eventsplugin.h"
|
#include "eventsplugin.h"
|
||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "rfbservermanager.h"
|
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
|
#include "rfbservermanager.h"
|
||||||
|
|
||||||
#include <QGlobalStatic>
|
#include <QGlobalStatic>
|
||||||
|
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
#include <KPluginMetaData>
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
|
||||||
class EventsManagerStatic
|
class EventsManagerStatic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ private:
|
|||||||
EventsManager();
|
EventsManager();
|
||||||
|
|
||||||
QMap<QString, EventsPlugin *> m_plugins;
|
QMap<QString, EventsPlugin *> m_plugins;
|
||||||
QList<QWeakPointer<EventHandler> > m_eventHandlers;
|
QList<QWeakPointer<EventHandler>> m_eventHandlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/* This file is part of the KDE project
|
/* This file is part of the KDE project
|
||||||
SPDX-FileCopyrightText: 2016 Oleg Chernovskiy <kanedias@xaker.ru>
|
SPDX-FileCopyrightText: 2016 Oleg Chernovskiy <kanedias@xaker.ru>
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,15 @@
|
|||||||
|
|
||||||
#include "krfbprivate_export.h"
|
#include "krfbprivate_export.h"
|
||||||
|
|
||||||
#include <QtCore/QVariantList>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QtCore/QVariantList>
|
||||||
|
|
||||||
class EventHandler;
|
class EventHandler;
|
||||||
|
|
||||||
class KRFBPRIVATE_EXPORT EventsPlugin : public QObject
|
class KRFBPRIVATE_EXPORT EventsPlugin : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventsPlugin(QObject *parent, const QVariantList &args);
|
EventsPlugin(QObject *parent, const QVariantList &args);
|
||||||
~EventsPlugin() override;
|
~EventsPlugin() override;
|
||||||
@@ -26,4 +27,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,10 @@
|
|||||||
|
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
|
|
||||||
#include <config-krfb.h>
|
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
#include <config-krfb.h>
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer(QObject *parent)
|
FrameBuffer::FrameBuffer(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@@ -27,7 +26,7 @@ char *FrameBuffer::data()
|
|||||||
return fb;
|
return fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< QRect > FrameBuffer::modifiedTiles()
|
QList<QRect> FrameBuffer::modifiedTiles()
|
||||||
{
|
{
|
||||||
QList<QRect> ret = tiles;
|
QList<QRect> ret = tiles;
|
||||||
tiles.clear();
|
tiles.clear();
|
||||||
|
|||||||
@@ -11,13 +11,12 @@
|
|||||||
|
|
||||||
#include "krfbprivate_export.h"
|
#include "krfbprivate_export.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QList>
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
/**
|
/**
|
||||||
@author Alessandro Praduroux <pradu@pradu.it>
|
@author Alessandro Praduroux <pradu@pradu.it>
|
||||||
@@ -25,6 +24,7 @@ class FrameBuffer;
|
|||||||
class KRFBPRIVATE_EXPORT FrameBuffer : public QObject
|
class KRFBPRIVATE_EXPORT FrameBuffer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FrameBuffer(QObject *parent = nullptr);
|
explicit FrameBuffer(QObject *parent = nullptr);
|
||||||
|
|
||||||
@@ -54,7 +54,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(FrameBuffer)
|
Q_DISABLE_COPY(FrameBuffer)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,13 +11,12 @@
|
|||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QGlobalStatic>
|
#include <QGlobalStatic>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
|
||||||
#include <KPluginFactory>
|
#include <KPluginFactory>
|
||||||
#include <KPluginMetaData>
|
#include <KPluginMetaData>
|
||||||
|
|
||||||
|
|
||||||
class FrameBufferManagerStatic
|
class FrameBufferManagerStatic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -28,7 +27,7 @@ Q_GLOBAL_STATIC(FrameBufferManagerStatic, frameBufferManagerStatic)
|
|||||||
|
|
||||||
FrameBufferManager::FrameBufferManager()
|
FrameBufferManager::FrameBufferManager()
|
||||||
{
|
{
|
||||||
const auto platformFilter = [] (const KPluginMetaData &pluginData) {
|
const auto platformFilter = [](const KPluginMetaData &pluginData) {
|
||||||
return pluginData.value(QStringLiteral("X-KDE-OnlyShowOnQtPlatforms"), QStringList()).contains(QGuiApplication::platformName());
|
return pluginData.value(QStringLiteral("X-KDE-OnlyShowOnQtPlatforms"), QStringList()).contains(QGuiApplication::platformName());
|
||||||
};
|
};
|
||||||
const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("krfb/framebuffer"), platformFilter, KPluginMetaData::AllowEmptyMetaData);
|
const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("krfb/framebuffer"), platformFilter, KPluginMetaData::AllowEmptyMetaData);
|
||||||
@@ -59,10 +58,10 @@ QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id, const QVaria
|
|||||||
QWeakPointer<FrameBuffer> weakFrameBuffer = m_frameBuffers.value(id);
|
QWeakPointer<FrameBuffer> weakFrameBuffer = m_frameBuffers.value(id);
|
||||||
|
|
||||||
if (weakFrameBuffer) {
|
if (weakFrameBuffer) {
|
||||||
//qDebug() << "Found cached frame buffer.";
|
// qDebug() << "Found cached frame buffer.";
|
||||||
return weakFrameBuffer.toStrongRef();
|
return weakFrameBuffer.toStrongRef();
|
||||||
} else {
|
} else {
|
||||||
//qDebug() << "Found deleted cached frame buffer. Don't use.";
|
// qDebug() << "Found deleted cached frame buffer. Don't use.";
|
||||||
m_frameBuffers.remove(id);
|
m_frameBuffers.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,7 @@ private:
|
|||||||
FrameBufferManager();
|
FrameBufferManager();
|
||||||
|
|
||||||
QMap<QString, FrameBufferPlugin *> m_plugins;
|
QMap<QString, FrameBufferPlugin *> m_plugins;
|
||||||
QMap<WId, QWeakPointer<FrameBuffer> > m_frameBuffers;
|
QMap<WId, QWeakPointer<FrameBuffer>> m_frameBuffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <QVariantList>
|
#include <QVariantList>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
|
|
||||||
class KRFBPRIVATE_EXPORT FrameBufferPlugin : public QObject
|
class KRFBPRIVATE_EXPORT FrameBufferPlugin : public QObject
|
||||||
@@ -28,4 +27,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|
||||||
|
|||||||
@@ -7,38 +7,42 @@
|
|||||||
|
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#include "rfb.h"
|
|
||||||
#include "invitationsrfbclient.h"
|
#include "invitationsrfbclient.h"
|
||||||
|
#include "connectiondialog.h"
|
||||||
#include "invitationsrfbserver.h"
|
#include "invitationsrfbserver.h"
|
||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "sockethelpers.h"
|
|
||||||
#include "connectiondialog.h"
|
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
|
#include "rfb.h"
|
||||||
|
#include "sockethelpers.h"
|
||||||
|
|
||||||
#include <KNotification>
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
#include <KNotification>
|
||||||
|
|
||||||
|
#include <KConfigGroup>
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <KConfigGroup>
|
|
||||||
|
|
||||||
struct PendingInvitationsRfbClient::Private
|
struct PendingInvitationsRfbClient::Private
|
||||||
{
|
{
|
||||||
Private(rfbClientPtr client) :
|
Private(rfbClientPtr client)
|
||||||
client(client),
|
: client(client)
|
||||||
askOnConnect(true)
|
, askOnConnect(true)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
rfbClientPtr client;
|
rfbClientPtr client;
|
||||||
QSocketNotifier *notifier = nullptr;
|
QSocketNotifier *notifier = nullptr;
|
||||||
bool askOnConnect;
|
bool askOnConnect;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
|
static void clientGoneHookNoop(rfbClientPtr cl)
|
||||||
|
{
|
||||||
|
Q_UNUSED(cl);
|
||||||
|
}
|
||||||
|
|
||||||
PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent) :
|
PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent)
|
||||||
PendingRfbClient(client, parent),
|
: PendingRfbClient(client, parent)
|
||||||
d(new Private(client))
|
, d(new Private(client))
|
||||||
{
|
{
|
||||||
d->client->clientGoneHook = clientGoneHookNoop;
|
d->client->clientGoneHook = clientGoneHookNoop;
|
||||||
}
|
}
|
||||||
@@ -53,13 +57,11 @@ void PendingInvitationsRfbClient::processNewClient()
|
|||||||
QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
|
QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
|
||||||
|
|
||||||
if (d->askOnConnect == false) {
|
if (d->askOnConnect == false) {
|
||||||
|
|
||||||
KNotification::event(QStringLiteral("NewConnectionAutoAccepted"),
|
KNotification::event(QStringLiteral("NewConnectionAutoAccepted"),
|
||||||
i18n("Accepted connection from %1", host));
|
i18n("Accepted connection from %1", host));
|
||||||
accept(new InvitationsRfbClient(m_rfbClient, parent()));
|
accept(new InvitationsRfbClient(m_rfbClient, parent()));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
KNotification::event(QStringLiteral("NewConnectionOnHold"),
|
KNotification::event(QStringLiteral("NewConnectionOnHold"),
|
||||||
i18n("Received connection from %1, on hold (waiting for confirmation)",
|
i18n("Received connection from %1, on hold (waiting for confirmation)",
|
||||||
host));
|
host));
|
||||||
@@ -75,13 +77,11 @@ void PendingInvitationsRfbClient::processNewClient()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PendingInvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
|
bool PendingInvitationsRfbClient::checkPassword(const QByteArray &encryptedPassword)
|
||||||
{
|
{
|
||||||
qCDebug(KRFB) << "about to start authentication";
|
qCDebug(KRFB) << "about to start authentication";
|
||||||
|
|
||||||
if(InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword(
|
if (InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword(InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(), encryptedPassword)) {
|
||||||
InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(),
|
|
||||||
encryptedPassword) ) {
|
|
||||||
d->askOnConnect = false;
|
d->askOnConnect = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,28 +12,30 @@
|
|||||||
class InvitationsRfbClient : public RfbClient
|
class InvitationsRfbClient : public RfbClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit InvitationsRfbClient(rfbClientPtr client, QObject* parent = nullptr)
|
explicit InvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr)
|
||||||
: RfbClient(client, parent) {}
|
: RfbClient(client, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PendingInvitationsRfbClient : public PendingRfbClient
|
class PendingInvitationsRfbClient : public PendingRfbClient
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
explicit PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
||||||
~PendingInvitationsRfbClient() override;
|
~PendingInvitationsRfbClient() override;
|
||||||
|
|
||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
void processNewClient() override;
|
void processNewClient() override;
|
||||||
bool checkPassword(const QByteArray & encryptedPassword) override;
|
bool checkPassword(const QByteArray &encryptedPassword) override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void dialogAccepted();
|
void dialogAccepted();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Private;
|
struct Private;
|
||||||
Private* const d;
|
Private *const d;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INVITATIONSRFBCLIENT_H
|
#endif // INVITATIONSRFBCLIENT_H
|
||||||
|
|||||||
@@ -11,14 +11,14 @@
|
|||||||
#include "invitationsrfbclient.h"
|
#include "invitationsrfbclient.h"
|
||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
#include <QTimer>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
#include <QRandomGenerator>
|
#include <QRandomGenerator>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KUser>
|
|
||||||
#include <KStringHandler>
|
#include <KStringHandler>
|
||||||
|
#include <KUser>
|
||||||
#include <KWallet>
|
#include <KWallet>
|
||||||
|
|
||||||
#include <KDNSSD/PublicService>
|
#include <KDNSSD/PublicService>
|
||||||
@@ -28,10 +28,10 @@ using KWallet::Wallet;
|
|||||||
// used for KWallet folder name
|
// used for KWallet folder name
|
||||||
static const QString s_krfbFolderName(QStringLiteral("krfb"));
|
static const QString s_krfbFolderName(QStringLiteral("krfb"));
|
||||||
|
|
||||||
//static
|
// static
|
||||||
InvitationsRfbServer *InvitationsRfbServer::instance;
|
InvitationsRfbServer *InvitationsRfbServer::instance;
|
||||||
|
|
||||||
//static
|
// static
|
||||||
void InvitationsRfbServer::init()
|
void InvitationsRfbServer::init()
|
||||||
{
|
{
|
||||||
instance = new InvitationsRfbServer;
|
instance = new InvitationsRfbServer;
|
||||||
@@ -53,12 +53,12 @@ void InvitationsRfbServer::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& InvitationsRfbServer::desktopPassword() const
|
const QString &InvitationsRfbServer::desktopPassword() const
|
||||||
{
|
{
|
||||||
return m_desktopPassword;
|
return m_desktopPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvitationsRfbServer::setDesktopPassword(const QString& password)
|
void InvitationsRfbServer::setDesktopPassword(const QString &password)
|
||||||
{
|
{
|
||||||
m_desktopPassword = password;
|
m_desktopPassword = password;
|
||||||
// this is called from GUI every time desktop password is edited.
|
// this is called from GUI every time desktop password is edited.
|
||||||
@@ -66,12 +66,12 @@ void InvitationsRfbServer::setDesktopPassword(const QString& password)
|
|||||||
saveSecuritySettings();
|
saveSecuritySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& InvitationsRfbServer::unattendedPassword() const
|
const QString &InvitationsRfbServer::unattendedPassword() const
|
||||||
{
|
{
|
||||||
return m_unattendedPassword;
|
return m_unattendedPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvitationsRfbServer::setUnattendedPassword(const QString& password)
|
void InvitationsRfbServer::setUnattendedPassword(const QString &password)
|
||||||
{
|
{
|
||||||
m_unattendedPassword = password;
|
m_unattendedPassword = password;
|
||||||
// this is called from GUI every time unattended password is edited.
|
// this is called from GUI every time unattended password is edited.
|
||||||
@@ -86,9 +86,10 @@ bool InvitationsRfbServer::allowUnattendedAccess() const
|
|||||||
|
|
||||||
bool InvitationsRfbServer::start()
|
bool InvitationsRfbServer::start()
|
||||||
{
|
{
|
||||||
if(RfbServer::start()) {
|
if (RfbServer::start()) {
|
||||||
if(KrfbConfig::publishService())
|
if (KrfbConfig::publishService()) {
|
||||||
m_publicService->publishAsync();
|
m_publicService->publishAsync();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -96,8 +97,9 @@ bool InvitationsRfbServer::start()
|
|||||||
|
|
||||||
void InvitationsRfbServer::stop()
|
void InvitationsRfbServer::stop()
|
||||||
{
|
{
|
||||||
if(m_publicService->isPublished())
|
if (m_publicService->isPublished()) {
|
||||||
m_publicService->stop();
|
m_publicService->stop();
|
||||||
|
}
|
||||||
RfbServer::stop();
|
RfbServer::stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,9 +115,10 @@ InvitationsRfbServer::InvitationsRfbServer()
|
|||||||
{
|
{
|
||||||
m_desktopPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3);
|
m_desktopPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3);
|
||||||
m_unattendedPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3);
|
m_unattendedPassword = readableRandomString(4) + QLatin1Char('-') + readableRandomString(3);
|
||||||
KConfigGroup krfbConfig(KSharedConfig::openConfig(),QStringLiteral("Security"));
|
KConfigGroup krfbConfig(KSharedConfig::openConfig(), QStringLiteral("Security"));
|
||||||
m_allowUnattendedAccess = krfbConfig.readEntry(
|
m_allowUnattendedAccess = krfbConfig.readEntry(
|
||||||
"allowUnattendedAccess", QVariant(false)).toBool();
|
"allowUnattendedAccess", QVariant(false))
|
||||||
|
.toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
InvitationsRfbServer::~InvitationsRfbServer()
|
InvitationsRfbServer::~InvitationsRfbServer()
|
||||||
@@ -129,7 +132,7 @@ InvitationsRfbServer::~InvitationsRfbServer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
|
PendingRfbClient *InvitationsRfbServer::newClient(rfbClientPtr client)
|
||||||
{
|
{
|
||||||
return new PendingInvitationsRfbClient(client, this);
|
return new PendingInvitationsRfbClient(client, this);
|
||||||
}
|
}
|
||||||
@@ -157,15 +160,13 @@ void InvitationsRfbServer::walletOpened(bool opened)
|
|||||||
QString unattendedPassword;
|
QString unattendedPassword;
|
||||||
Q_ASSERT(m_wallet);
|
Q_ASSERT(m_wallet);
|
||||||
|
|
||||||
if (opened && m_wallet->hasFolder(s_krfbFolderName) && m_wallet->setFolder(s_krfbFolderName) ) {
|
if (opened && m_wallet->hasFolder(s_krfbFolderName) && m_wallet->setFolder(s_krfbFolderName)) {
|
||||||
if (m_wallet->readPassword(QStringLiteral("desktopSharingPassword"), desktopPassword) == 0 &&
|
if (m_wallet->readPassword(QStringLiteral("desktopSharingPassword"), desktopPassword) == 0 && !desktopPassword.isEmpty()) {
|
||||||
!desktopPassword.isEmpty()) {
|
|
||||||
m_desktopPassword = desktopPassword;
|
m_desktopPassword = desktopPassword;
|
||||||
Q_EMIT passwordChanged(m_desktopPassword);
|
Q_EMIT passwordChanged(m_desktopPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_wallet->readPassword(QStringLiteral("unattendedAccessPassword"), unattendedPassword) == 0 &&
|
if (m_wallet->readPassword(QStringLiteral("unattendedAccessPassword"), unattendedPassword) == 0 && !unattendedPassword.isEmpty()) {
|
||||||
!unattendedPassword.isEmpty()) {
|
|
||||||
m_unattendedPassword = unattendedPassword;
|
m_unattendedPassword = unattendedPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,13 +191,7 @@ QString InvitationsRfbServer::readableRandomString(int length)
|
|||||||
r += 6;
|
r += 6;
|
||||||
}
|
}
|
||||||
char c = char(r);
|
char c = char(r);
|
||||||
if ((c == 'i') ||
|
if ((c == 'i') || (c == 'I') || (c == '1') || (c == 'l') || (c == 'o') || (c == 'O') || (c == '0')) {
|
||||||
(c == 'I') ||
|
|
||||||
(c == '1') ||
|
|
||||||
(c == 'l') ||
|
|
||||||
(c == 'o') ||
|
|
||||||
(c == 'O') ||
|
|
||||||
(c == '0')) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
str += QLatin1Char(c);
|
str += QLatin1Char(c);
|
||||||
@@ -237,18 +232,18 @@ void InvitationsRfbServer::readPasswordFromConfig()
|
|||||||
{
|
{
|
||||||
QString desktopPassword;
|
QString desktopPassword;
|
||||||
QString unattendedPassword;
|
QString unattendedPassword;
|
||||||
KConfigGroup krfbConfig(KSharedConfig::openConfig(),QStringLiteral("Security"));
|
KConfigGroup krfbConfig(KSharedConfig::openConfig(), QStringLiteral("Security"));
|
||||||
|
|
||||||
desktopPassword = KStringHandler::obscure(krfbConfig.readEntry(
|
desktopPassword = KStringHandler::obscure(krfbConfig.readEntry(
|
||||||
"desktopPassword", QString()));
|
"desktopPassword", QString()));
|
||||||
if(!desktopPassword.isEmpty()) {
|
if (!desktopPassword.isEmpty()) {
|
||||||
m_desktopPassword = desktopPassword;
|
m_desktopPassword = desktopPassword;
|
||||||
Q_EMIT passwordChanged(m_desktopPassword);
|
Q_EMIT passwordChanged(m_desktopPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
unattendedPassword = KStringHandler::obscure(krfbConfig.readEntry(
|
unattendedPassword = KStringHandler::obscure(krfbConfig.readEntry(
|
||||||
"unattendedPassword", QString()));
|
"unattendedPassword", QString()));
|
||||||
if(!unattendedPassword.isEmpty()) {
|
if (!unattendedPassword.isEmpty()) {
|
||||||
m_unattendedPassword = unattendedPassword;
|
m_unattendedPassword = unattendedPassword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,29 +11,36 @@
|
|||||||
|
|
||||||
#include "rfbserver.h"
|
#include "rfbserver.h"
|
||||||
|
|
||||||
namespace KWallet {
|
namespace KWallet
|
||||||
class Wallet;
|
{
|
||||||
|
|
||||||
|
class Wallet;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace KDNSSD {
|
namespace KDNSSD
|
||||||
class PublicService;
|
{
|
||||||
|
|
||||||
|
class PublicService;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvitationsRfbServer : public RfbServer
|
class InvitationsRfbServer : public RfbServer
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static InvitationsRfbServer *instance;
|
static InvitationsRfbServer *instance;
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
const QString& desktopPassword() const;
|
const QString &desktopPassword() const;
|
||||||
void setDesktopPassword(const QString&);
|
void setDesktopPassword(const QString &);
|
||||||
const QString& unattendedPassword() const;
|
const QString &unattendedPassword() const;
|
||||||
void setUnattendedPassword(const QString&);
|
void setUnattendedPassword(const QString &);
|
||||||
bool allowUnattendedAccess() const;
|
bool allowUnattendedAccess() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void passwordChanged(const QString&);
|
void passwordChanged(const QString &);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
bool start() override;
|
bool start() override;
|
||||||
@@ -46,7 +53,7 @@ public Q_SLOTS:
|
|||||||
protected:
|
protected:
|
||||||
InvitationsRfbServer();
|
InvitationsRfbServer();
|
||||||
~InvitationsRfbServer() override;
|
~InvitationsRfbServer() override;
|
||||||
PendingRfbClient* newClient(rfbClientPtr client) override;
|
PendingRfbClient *newClient(rfbClientPtr client) override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void walletOpened(bool);
|
void walletOpened(bool);
|
||||||
|
|||||||
@@ -4,28 +4,29 @@
|
|||||||
SPDX-License-Identifier: GPL-3.0-or-later
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QCommandLineParser>
|
|
||||||
#include <QCommandLineOption>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <KCrash>
|
|
||||||
#include <KNotification>
|
|
||||||
#include <KLocalizedString>
|
|
||||||
#include <KWindowSystem>
|
|
||||||
#include <KAboutData>
|
|
||||||
#include "sockethelpers.h"
|
|
||||||
#include "krfb_version.h"
|
#include "krfb_version.h"
|
||||||
#include "rfbserver.h"
|
#include "rfbserver.h"
|
||||||
#include <signal.h>
|
|
||||||
#include "rfbservermanager.h"
|
#include "rfbservermanager.h"
|
||||||
|
#include "sockethelpers.h"
|
||||||
|
#include <KAboutData>
|
||||||
|
#include <KCrash>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
#include <KNotification>
|
||||||
|
#include <KWindowSystem>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCommandLineOption>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
class VirtualMonitorRfbClient : public RfbClient
|
class VirtualMonitorRfbClient : public RfbClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit VirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
|
explicit VirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
|
||||||
: RfbClient(client, parent)
|
: RfbClient(client, parent)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PendingVirtualMonitorRfbClient : public PendingRfbClient
|
class PendingVirtualMonitorRfbClient : public PendingRfbClient
|
||||||
@@ -33,20 +34,25 @@ class PendingVirtualMonitorRfbClient : public PendingRfbClient
|
|||||||
public:
|
public:
|
||||||
explicit PendingVirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
|
explicit PendingVirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
|
||||||
: PendingRfbClient(client, parent)
|
: PendingRfbClient(client, parent)
|
||||||
{}
|
{
|
||||||
~PendingVirtualMonitorRfbClient() override {}
|
}
|
||||||
|
~PendingVirtualMonitorRfbClient() override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static QByteArray password;
|
static QByteArray password;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void processNewClient() override {
|
void processNewClient() override
|
||||||
|
{
|
||||||
qDebug() << "new client!";
|
qDebug() << "new client!";
|
||||||
const QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
|
const QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
|
||||||
|
|
||||||
KNotification::event(QStringLiteral("NewConnectionAutoAccepted"),
|
KNotification::event(QStringLiteral("NewConnectionAutoAccepted"),
|
||||||
i18n("Creating a Virtual Monitor from %1", host));
|
i18n("Creating a Virtual Monitor from %1", host));
|
||||||
}
|
}
|
||||||
bool checkPassword(const QByteArray & encryptedPassword) override {
|
bool checkPassword(const QByteArray &encryptedPassword) override
|
||||||
|
{
|
||||||
bool b = vncAuthCheckPassword(password, encryptedPassword);
|
bool b = vncAuthCheckPassword(password, encryptedPassword);
|
||||||
if (b) {
|
if (b) {
|
||||||
QTimer::singleShot(0, this, [this] {
|
QTimer::singleShot(0, this, [this] {
|
||||||
@@ -62,7 +68,8 @@ QByteArray PendingVirtualMonitorRfbClient::password;
|
|||||||
class VirtualMonitorRfbServer : public RfbServer
|
class VirtualMonitorRfbServer : public RfbServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PendingRfbClient *newClient(rfbClientPtr client) override {
|
PendingRfbClient *newClient(rfbClientPtr client) override
|
||||||
|
{
|
||||||
qDebug() << "new client request";
|
qDebug() << "new client request";
|
||||||
return new PendingVirtualMonitorRfbClient(client, this);
|
return new PendingVirtualMonitorRfbClient(client, this);
|
||||||
}
|
}
|
||||||
@@ -107,34 +114,34 @@ int main(int argc, char *argv[])
|
|||||||
aboutData.setupCommandLine(&parser);
|
aboutData.setupCommandLine(&parser);
|
||||||
|
|
||||||
const QCommandLineOption resolutionOption(
|
const QCommandLineOption resolutionOption(
|
||||||
{ QStringLiteral("resolution") },
|
{QStringLiteral("resolution")},
|
||||||
i18n("Logical resolution of the new monitor"),
|
i18n("Logical resolution of the new monitor"),
|
||||||
i18n("resolution"),
|
i18n("resolution"),
|
||||||
QStringLiteral("1920x1080"));
|
QStringLiteral("1920x1080"));
|
||||||
parser.addOption(resolutionOption);
|
parser.addOption(resolutionOption);
|
||||||
|
|
||||||
const QCommandLineOption nameOption(
|
const QCommandLineOption nameOption(
|
||||||
{ QStringLiteral("name") },
|
{QStringLiteral("name")},
|
||||||
i18n("Name of the monitor"),
|
i18n("Name of the monitor"),
|
||||||
i18n("name"),
|
i18n("name"),
|
||||||
QStringLiteral("Monitor"));
|
QStringLiteral("Monitor"));
|
||||||
parser.addOption(nameOption);
|
parser.addOption(nameOption);
|
||||||
|
|
||||||
const QCommandLineOption passwordOption(
|
const QCommandLineOption passwordOption(
|
||||||
{ QStringLiteral("password") },
|
{QStringLiteral("password")},
|
||||||
i18n("Password for the client to connect to it"),
|
i18n("Password for the client to connect to it"),
|
||||||
i18n("password"));
|
i18n("password"));
|
||||||
parser.addOption(passwordOption);
|
parser.addOption(passwordOption);
|
||||||
|
|
||||||
const QCommandLineOption scaleOption(
|
const QCommandLineOption scaleOption(
|
||||||
{ QStringLiteral("scale") },
|
{QStringLiteral("scale")},
|
||||||
i18n("The device-pixel-ratio of the device, the scaling factor"),
|
i18n("The device-pixel-ratio of the device, the scaling factor"),
|
||||||
i18n("dpr"),
|
i18n("dpr"),
|
||||||
QStringLiteral("1"));
|
QStringLiteral("1"));
|
||||||
parser.addOption(scaleOption);
|
parser.addOption(scaleOption);
|
||||||
|
|
||||||
const QCommandLineOption portOption(
|
const QCommandLineOption portOption(
|
||||||
{ QStringLiteral("port") },
|
{QStringLiteral("port")},
|
||||||
i18n("The port we will be listening to"),
|
i18n("The port we will be listening to"),
|
||||||
i18n("number"),
|
i18n("number"),
|
||||||
QStringLiteral("5900"));
|
QStringLiteral("5900"));
|
||||||
@@ -151,16 +158,16 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
const QString res = parser.value(resolutionOption);
|
const QString res = parser.value(resolutionOption);
|
||||||
const auto resSplit = res.split(QLatin1Char('x'));
|
const auto resSplit = res.split(QLatin1Char('x'));
|
||||||
const QSize size = { resSplit[0].toInt(), resSplit[1].toInt() };
|
const QSize size = {resSplit[0].toInt(), resSplit[1].toInt()};
|
||||||
if (resSplit.size() != 2 || size.isEmpty()) {
|
if (resSplit.size() != 2 || size.isEmpty()) {
|
||||||
qCritical() << "The resolution should be formatted as WIDTHxHEIGHT (e.g. --resolution 1920x1080).";
|
qCritical() << "The resolution should be formatted as WIDTHxHEIGHT (e.g. --resolution 1920x1080).";
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
RfbServerManager::s_pluginArgs = {
|
RfbServerManager::s_pluginArgs = {
|
||||||
{ QStringLiteral("name"), parser.value(nameOption) },
|
{QStringLiteral("name"), parser.value(nameOption)},
|
||||||
{ QStringLiteral("resolution"), size },
|
{QStringLiteral("resolution"), size},
|
||||||
{ QStringLiteral("scale"), parser.value(scaleOption).toDouble() },
|
{QStringLiteral("scale"), parser.value(scaleOption).toDouble()},
|
||||||
};
|
};
|
||||||
|
|
||||||
VirtualMonitorRfbServer server;
|
VirtualMonitorRfbServer server;
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "invitationsrfbserver.h"
|
||||||
|
#include "krfb_version.h"
|
||||||
|
#include "krfbconfig.h"
|
||||||
|
#include "krfbdebug.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "trayicon.h"
|
#include "trayicon.h"
|
||||||
#include "invitationsrfbserver.h"
|
|
||||||
#include "krfbconfig.h"
|
|
||||||
#include "krfb_version.h"
|
|
||||||
#include "krfbdebug.h"
|
|
||||||
|
|
||||||
#include <KAboutData>
|
#include <KAboutData>
|
||||||
#include <KCrash>
|
#include <KCrash>
|
||||||
@@ -18,14 +18,13 @@
|
|||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
|
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <qwindowdefs.h>
|
|
||||||
#include <QtGui/private/qtx11extras_p.h>
|
#include <QtGui/private/qtx11extras_p.h>
|
||||||
|
#include <qwindowdefs.h>
|
||||||
|
|
||||||
#include <csignal>
|
|
||||||
#include <X11/extensions/XTest.h>
|
|
||||||
#include <QCommandLineParser>
|
|
||||||
#include <QCommandLineOption>
|
#include <QCommandLineOption>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <X11/extensions/XTest.h>
|
||||||
|
#include <csignal>
|
||||||
|
|
||||||
static bool checkX11Capabilities()
|
static bool checkX11Capabilities()
|
||||||
{
|
{
|
||||||
@@ -44,7 +43,8 @@ static bool checkX11Capabilities()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkOldX11PluginConfig() {
|
static void checkOldX11PluginConfig()
|
||||||
|
{
|
||||||
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
|
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
|
||||||
qCDebug(KRFB) << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
|
qCDebug(KRFB) << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
|
||||||
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
|
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
|
||||||
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
aboutData.setupCommandLine(&parser);
|
aboutData.setupCommandLine(&parser);
|
||||||
const QCommandLineOption nodialogOption(QStringList{ QStringLiteral("nodialog") }, i18n("Do not show the invitations management dialog at startup"));
|
const QCommandLineOption nodialogOption(QStringList{QStringLiteral("nodialog")}, i18n("Do not show the invitations management dialog at startup"));
|
||||||
parser.addOption(nodialogOption);
|
parser.addOption(nodialogOption);
|
||||||
|
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
@@ -144,10 +144,10 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//init the core
|
// init the core
|
||||||
InvitationsRfbServer::init();
|
InvitationsRfbServer::init();
|
||||||
|
|
||||||
//init the GUI
|
// init the GUI
|
||||||
MainWindow mainWindow;
|
MainWindow mainWindow;
|
||||||
TrayIcon trayicon(&mainWindow);
|
TrayIcon trayicon(&mainWindow);
|
||||||
|
|
||||||
|
|||||||
@@ -8,42 +8,46 @@
|
|||||||
#include "invitationsrfbserver.h"
|
#include "invitationsrfbserver.h"
|
||||||
|
|
||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "ui_configtcp.h"
|
|
||||||
#include "ui_configsecurity.h"
|
|
||||||
#include "ui_configframebuffer.h"
|
#include "ui_configframebuffer.h"
|
||||||
|
#include "ui_configsecurity.h"
|
||||||
|
#include "ui_configtcp.h"
|
||||||
|
|
||||||
|
#include <KActionCollection>
|
||||||
#include <KConfigDialog>
|
#include <KConfigDialog>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KMessageBox>
|
#include <KMessageBox>
|
||||||
#include <KMessageWidget>
|
#include <KMessageWidget>
|
||||||
#include <KStandardAction>
|
|
||||||
#include <KActionCollection>
|
|
||||||
#include <KNewPasswordDialog>
|
#include <KNewPasswordDialog>
|
||||||
#include <KPluginMetaData>
|
#include <KPluginMetaData>
|
||||||
|
#include <KStandardAction>
|
||||||
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QSizePolicy>
|
|
||||||
#include <QList>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QNetworkInterface>
|
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QList>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QNetworkInterface>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QSizePolicy>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
class TCP: public QWidget, public Ui::TCP
|
class TCP : public QWidget, public Ui::TCP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TCP(QWidget *parent = nullptr) : QWidget(parent) {
|
explicit TCP(QWidget *parent = nullptr)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Security: public QWidget, public Ui::Security
|
class Security : public QWidget, public Ui::Security
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Security(QWidget *parent = nullptr) : QWidget(parent) {
|
explicit Security(QWidget *parent = nullptr)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
walletWarning = new KMessageWidget(this);
|
walletWarning = new KMessageWidget(this);
|
||||||
walletWarning->setText(i18n("Storing passwords in config file is insecure!"));
|
walletWarning->setText(i18n("Storing passwords in config file is insecure!"));
|
||||||
@@ -53,7 +57,7 @@ public:
|
|||||||
vboxLayout->addWidget(walletWarning);
|
vboxLayout->addWidget(walletWarning);
|
||||||
|
|
||||||
// show warning when "noWallet" checkbox is checked
|
// show warning when "noWallet" checkbox is checked
|
||||||
QObject::connect(kcfg_noWallet, &QCheckBox::toggled, this, [this] (bool checked) {
|
QObject::connect(kcfg_noWallet, &QCheckBox::toggled, this, [this](bool checked) {
|
||||||
walletWarning->setVisible(checked);
|
walletWarning->setVisible(checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -61,10 +65,12 @@ public:
|
|||||||
KMessageWidget *walletWarning = nullptr;
|
KMessageWidget *walletWarning = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigFramebuffer: public QWidget, public Ui::Framebuffer
|
class ConfigFramebuffer : public QWidget, public Ui::Framebuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConfigFramebuffer(QWidget *parent = nullptr) : QWidget(parent) {
|
ConfigFramebuffer(QWidget *parent = nullptr)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
// hide the line edit with framebuffer string
|
// hide the line edit with framebuffer string
|
||||||
kcfg_preferredFrameBufferPlugin->hide();
|
kcfg_preferredFrameBufferPlugin->hide();
|
||||||
@@ -78,7 +84,8 @@ public:
|
|||||||
kcfg_preferredFrameBufferPlugin, &QLineEdit::setText);
|
kcfg_preferredFrameBufferPlugin, &QLineEdit::setText);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillFrameBuffersCombo() {
|
void fillFrameBuffersCombo()
|
||||||
|
{
|
||||||
const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("krfb/framebuffer"), {}, KPluginMetaData::AllowEmptyMetaData);
|
const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("krfb/framebuffer"), {}, KPluginMetaData::AllowEmptyMetaData);
|
||||||
for (const KPluginMetaData &metadata : plugins) {
|
for (const KPluginMetaData &metadata : plugins) {
|
||||||
cb_preferredFrameBufferPlugin->addItem(metadata.pluginId());
|
cb_preferredFrameBufferPlugin->addItem(metadata.pluginId());
|
||||||
@@ -86,7 +93,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
: KXmlGuiWindow(parent)
|
: KXmlGuiWindow(parent)
|
||||||
{
|
{
|
||||||
@@ -123,12 +129,12 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
// Figure out the address
|
// Figure out the address
|
||||||
int port = KrfbConfig::port();
|
int port = KrfbConfig::port();
|
||||||
const QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
|
const QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
|
||||||
for (const QNetworkInterface& interface : interfaceList) {
|
for (const QNetworkInterface &interface : interfaceList) {
|
||||||
if(interface.flags() & QNetworkInterface::IsLoopBack)
|
if (interface.flags() & QNetworkInterface::IsLoopBack) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(interface.flags() & QNetworkInterface::IsRunning &&
|
if (interface.flags() & QNetworkInterface::IsRunning && !interface.addressEntries().isEmpty()) {
|
||||||
!interface.addressEntries().isEmpty()) {
|
|
||||||
const QString hostName = QHostInfo::localHostName();
|
const QString hostName = QHostInfo::localHostName();
|
||||||
const QString ipAddress = interface.addressEntries().constFirst().ip().toString();
|
const QString ipAddress = interface.addressEntries().constFirst().ip().toString();
|
||||||
const QString addressLabelText = hostName.isEmpty()
|
const QString addressLabelText = hostName.isEmpty()
|
||||||
@@ -138,7 +144,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Figure out the password
|
// Figure out the password
|
||||||
m_ui.passwordDisplayLabel->setText(
|
m_ui.passwordDisplayLabel->setText(
|
||||||
InvitationsRfbServer::instance->desktopPassword());
|
InvitationsRfbServer::instance->desktopPassword());
|
||||||
|
|
||||||
@@ -160,7 +166,7 @@ MainWindow::~MainWindow()
|
|||||||
|
|
||||||
void MainWindow::editPassword()
|
void MainWindow::editPassword()
|
||||||
{
|
{
|
||||||
if(m_passwordEditable) {
|
if (m_passwordEditable) {
|
||||||
m_passwordEditable = false;
|
m_passwordEditable = false;
|
||||||
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
|
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
|
||||||
m_ui.passwordGridLayout->removeWidget(m_passwordLineEdit);
|
m_ui.passwordGridLayout->removeWidget(m_passwordLineEdit);
|
||||||
@@ -172,7 +178,7 @@ void MainWindow::editPassword()
|
|||||||
} else {
|
} else {
|
||||||
m_passwordEditable = true;
|
m_passwordEditable = true;
|
||||||
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-save")));
|
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-save")));
|
||||||
m_ui.passwordGridLayout->addWidget(m_passwordLineEdit,0,0);
|
m_ui.passwordGridLayout->addWidget(m_passwordLineEdit, 0, 0);
|
||||||
m_passwordLineEdit->setText(
|
m_passwordLineEdit->setText(
|
||||||
InvitationsRfbServer::instance->desktopPassword());
|
InvitationsRfbServer::instance->desktopPassword());
|
||||||
m_passwordLineEdit->setVisible(true);
|
m_passwordLineEdit->setVisible(true);
|
||||||
@@ -184,15 +190,15 @@ void MainWindow::editUnattendedPassword()
|
|||||||
{
|
{
|
||||||
KNewPasswordDialog dialog(this);
|
KNewPasswordDialog dialog(this);
|
||||||
dialog.setPrompt(i18n("Enter a new password for Unattended Access"));
|
dialog.setPrompt(i18n("Enter a new password for Unattended Access"));
|
||||||
if(dialog.exec()) {
|
if (dialog.exec()) {
|
||||||
InvitationsRfbServer::instance->setUnattendedPassword(dialog.password());
|
InvitationsRfbServer::instance->setUnattendedPassword(dialog.password());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::toggleDesktopSharing(bool enable)
|
void MainWindow::toggleDesktopSharing(bool enable)
|
||||||
{
|
{
|
||||||
if(enable) {
|
if (enable) {
|
||||||
if(!InvitationsRfbServer::instance->start()) {
|
if (!InvitationsRfbServer::instance->start()) {
|
||||||
KMessageBox::error(this,
|
KMessageBox::error(this,
|
||||||
i18n("Failed to start the krfb server. Desktop sharing "
|
i18n("Failed to start the krfb server. Desktop sharing "
|
||||||
"will not work. Try setting another port in the settings "
|
"will not work. Try setting another port in the settings "
|
||||||
@@ -200,7 +206,7 @@ void MainWindow::toggleDesktopSharing(bool enable)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
InvitationsRfbServer::instance->stop();
|
InvitationsRfbServer::instance->stop();
|
||||||
if(m_passwordEditable) {
|
if (m_passwordEditable) {
|
||||||
m_passwordEditable = false;
|
m_passwordEditable = false;
|
||||||
m_passwordLineEdit->setVisible(false);
|
m_passwordLineEdit->setVisible(false);
|
||||||
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
|
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
|
||||||
@@ -208,7 +214,7 @@ void MainWindow::toggleDesktopSharing(bool enable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::passwordChanged(const QString& password)
|
void MainWindow::passwordChanged(const QString &password)
|
||||||
{
|
{
|
||||||
m_passwordLineEdit->setText(password);
|
m_passwordLineEdit->setText(password);
|
||||||
m_ui.passwordDisplayLabel->setText(password);
|
m_ui.passwordDisplayLabel->setText(password);
|
||||||
@@ -247,7 +253,7 @@ void MainWindow::showConfiguration()
|
|||||||
dialog->addPage(new Security, i18n("Security"), QStringLiteral("security-high"));
|
dialog->addPage(new Security, i18n("Security"), QStringLiteral("security-high"));
|
||||||
dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), QStringLiteral("video-display"));
|
dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), QStringLiteral("video-display"));
|
||||||
dialog->show();
|
dialog->show();
|
||||||
connect(dialog, &KConfigDialog::settingsChanged, this, [this] () {
|
connect(dialog, &KConfigDialog::settingsChanged, this, [this]() {
|
||||||
// check if framebuffer plugin config has changed
|
// check if framebuffer plugin config has changed
|
||||||
if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) {
|
if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) {
|
||||||
KMessageBox::information(this, i18n("To apply framebuffer plugin setting, "
|
KMessageBox::information(this, i18n("To apply framebuffer plugin setting, "
|
||||||
@@ -269,7 +275,7 @@ void MainWindow::showConfiguration()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::readProperties(const KConfigGroup& group)
|
void MainWindow::readProperties(const KConfigGroup &group)
|
||||||
{
|
{
|
||||||
if (group.readEntry("Visible", true)) {
|
if (group.readEntry("Visible", true)) {
|
||||||
show();
|
show();
|
||||||
@@ -277,7 +283,7 @@ void MainWindow::readProperties(const KConfigGroup& group)
|
|||||||
KMainWindow::readProperties(group);
|
KMainWindow::readProperties(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::saveProperties(KConfigGroup& group)
|
void MainWindow::saveProperties(KConfigGroup &group)
|
||||||
{
|
{
|
||||||
group.writeEntry("Visible", isVisible());
|
group.writeEntry("Visible", isVisible());
|
||||||
KMainWindow::saveProperties(group);
|
KMainWindow::saveProperties(group);
|
||||||
|
|||||||
@@ -18,26 +18,26 @@ class MainWindow : public KXmlGuiWindow
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = nullptr);
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
~MainWindow() override;
|
~MainWindow() override;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void showConfiguration();
|
void showConfiguration();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void readProperties(const KConfigGroup & group) override;
|
void readProperties(const KConfigGroup &group) override;
|
||||||
void saveProperties(KConfigGroup & group) override;
|
void saveProperties(KConfigGroup &group) override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void editPassword();
|
void editPassword();
|
||||||
void editUnattendedPassword();
|
void editUnattendedPassword();
|
||||||
void toggleDesktopSharing(bool enable);
|
void toggleDesktopSharing(bool enable);
|
||||||
void passwordChanged(const QString&);
|
void passwordChanged(const QString &);
|
||||||
void aboutConnectionAddress();
|
void aboutConnectionAddress();
|
||||||
void aboutUnattendedMode();
|
void aboutUnattendedMode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWidget m_ui;
|
Ui::MainWidget m_ui;
|
||||||
bool m_passwordEditable;
|
bool m_passwordEditable;
|
||||||
QLineEdit *m_passwordLineEdit = nullptr;
|
QLineEdit *m_passwordLineEdit = nullptr;
|
||||||
|
|||||||
@@ -16,4 +16,3 @@
|
|||||||
#undef FALSE
|
#undef FALSE
|
||||||
|
|
||||||
#endif // Header guard
|
#endif // Header guard
|
||||||
|
|
||||||
|
|||||||
@@ -8,20 +8,21 @@
|
|||||||
*/
|
*/
|
||||||
#include "rfbclient.h"
|
#include "rfbclient.h"
|
||||||
#include "connectiondialog.h"
|
#include "connectiondialog.h"
|
||||||
#include "krfbconfig.h"
|
|
||||||
#include "sockethelpers.h"
|
|
||||||
#include "eventsmanager.h"
|
#include "eventsmanager.h"
|
||||||
|
#include "krfbconfig.h"
|
||||||
|
#include "krfbdebug.h"
|
||||||
|
#include "sockethelpers.h"
|
||||||
#include <QSocketNotifier>
|
#include <QSocketNotifier>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <strings.h> //for bzero()
|
#include <strings.h> //for bzero()
|
||||||
#include "krfbdebug.h"
|
|
||||||
|
|
||||||
struct RfbClient::Private
|
struct RfbClient::Private
|
||||||
{
|
{
|
||||||
Private(rfbClientPtr client) :
|
Private(rfbClientPtr client)
|
||||||
controlEnabled(KrfbConfig::allowDesktopControl()),
|
: controlEnabled(KrfbConfig::allowDesktopControl())
|
||||||
client(client)
|
, client(client)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool controlEnabled;
|
bool controlEnabled;
|
||||||
rfbClientPtr client;
|
rfbClientPtr client;
|
||||||
@@ -30,11 +31,11 @@ struct RfbClient::Private
|
|||||||
QString remoteAddressString;
|
QString remoteAddressString;
|
||||||
};
|
};
|
||||||
|
|
||||||
RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
|
RfbClient::RfbClient(rfbClientPtr client, QObject *parent)
|
||||||
: QObject(parent), d(new Private(client))
|
: QObject(parent)
|
||||||
|
, d(new Private(client))
|
||||||
{
|
{
|
||||||
d->remoteAddressString = peerAddress(d->client->sock) + QLatin1Char(':') +
|
d->remoteAddressString = peerAddress(d->client->sock) + QLatin1Char(':') + QString::number(peerPort(d->client->sock));
|
||||||
QString::number(peerPort(d->client->sock));
|
|
||||||
|
|
||||||
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
|
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
|
||||||
d->notifier->setEnabled(false);
|
d->notifier->setEnabled(false);
|
||||||
@@ -45,7 +46,7 @@ RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
|
|||||||
|
|
||||||
RfbClient::~RfbClient()
|
RfbClient::~RfbClient()
|
||||||
{
|
{
|
||||||
//qDebug();
|
// qDebug();
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ QString RfbClient::name() const
|
|||||||
return d->remoteAddressString;
|
return d->remoteAddressString;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
bool RfbClient::controlCanBeEnabled()
|
bool RfbClient::controlCanBeEnabled()
|
||||||
{
|
{
|
||||||
return KrfbConfig::allowDesktopControl();
|
return KrfbConfig::allowDesktopControl();
|
||||||
@@ -115,23 +116,23 @@ void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
|
|||||||
|
|
||||||
void RfbClient::onSocketActivated()
|
void RfbClient::onSocketActivated()
|
||||||
{
|
{
|
||||||
//Process not only one, but all pending messages.
|
// Process not only one, but all pending messages.
|
||||||
//poll() idea/code copied from vino:
|
// poll() idea/code copied from vino:
|
||||||
// Copyright (C) 2003 Sun Microsystems, Inc.
|
// Copyright (C) 2003 Sun Microsystems, Inc.
|
||||||
// License: GPL v2 or later
|
// License: GPL v2 or later
|
||||||
struct pollfd pollfd = { d->client->sock, POLLIN|POLLPRI, 0 };
|
struct pollfd pollfd = {d->client->sock, POLLIN | POLLPRI, 0};
|
||||||
|
|
||||||
while(poll(&pollfd, 1, 0) == 1) {
|
while (poll(&pollfd, 1, 0) == 1) {
|
||||||
rfbProcessClientMessage(d->client);
|
rfbProcessClientMessage(d->client);
|
||||||
|
|
||||||
//This is how we handle disconnection.
|
// This is how we handle disconnection.
|
||||||
//if rfbProcessClientMessage() finds out that it can't read the socket,
|
// if rfbProcessClientMessage() finds out that it can't read the socket,
|
||||||
//it closes it and sets it to -1. So, we just have to check this here
|
// it closes it and sets it to -1. So, we just have to check this here
|
||||||
//and call rfbClientConnectionGone() if necessary. This will call
|
// and call rfbClientConnectionGone() if necessary. This will call
|
||||||
//the clientGoneHook which in turn will remove this RfbClient instance
|
// the clientGoneHook which in turn will remove this RfbClient instance
|
||||||
//from the server manager and will call deleteLater() to delete it
|
// from the server manager and will call deleteLater() to delete it
|
||||||
if (d->client->sock == -1) {
|
if (d->client->sock == -1) {
|
||||||
//qDebug() << "disconnected from socket signal";
|
// qDebug() << "disconnected from socket signal";
|
||||||
d->notifier->setEnabled(false);
|
d->notifier->setEnabled(false);
|
||||||
rfbClientConnectionGone(d->client);
|
rfbClientConnectionGone(d->client);
|
||||||
break;
|
break;
|
||||||
@@ -143,14 +144,14 @@ void RfbClient::update()
|
|||||||
{
|
{
|
||||||
rfbUpdateClient(d->client);
|
rfbUpdateClient(d->client);
|
||||||
|
|
||||||
//This is how we handle disconnection.
|
// This is how we handle disconnection.
|
||||||
//if rfbUpdateClient() finds out that it can't write to the socket,
|
// if rfbUpdateClient() finds out that it can't write to the socket,
|
||||||
//it closes it and sets it to -1. So, we just have to check this here
|
// it closes it and sets it to -1. So, we just have to check this here
|
||||||
//and call rfbClientConnectionGone() if necessary. This will call
|
// and call rfbClientConnectionGone() if necessary. This will call
|
||||||
//the clientGoneHook which in turn will remove this RfbClient instance
|
// the clientGoneHook which in turn will remove this RfbClient instance
|
||||||
//from the server manager and will call deleteLater() to delete it
|
// from the server manager and will call deleteLater() to delete it
|
||||||
if (d->client->sock == -1) {
|
if (d->client->sock == -1) {
|
||||||
//qDebug() << "disconnected during update";
|
// qDebug() << "disconnected during update";
|
||||||
d->notifier->setEnabled(false);
|
d->notifier->setEnabled(false);
|
||||||
rfbClientConnectionGone(d->client);
|
rfbClientConnectionGone(d->client);
|
||||||
}
|
}
|
||||||
@@ -159,7 +160,8 @@ void RfbClient::update()
|
|||||||
//*************
|
//*************
|
||||||
|
|
||||||
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
|
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
|
||||||
: QObject(parent), m_rfbClient(client)
|
: QObject(parent)
|
||||||
|
, m_rfbClient(client)
|
||||||
, m_notifier(new QSocketNotifier(client->sock, QSocketNotifier::Read, this))
|
, m_notifier(new QSocketNotifier(client->sock, QSocketNotifier::Read, this))
|
||||||
{
|
{
|
||||||
m_rfbClient->clientData = this;
|
m_rfbClient->clientData = this;
|
||||||
@@ -170,11 +172,12 @@ PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PendingRfbClient::~PendingRfbClient()
|
PendingRfbClient::~PendingRfbClient()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void PendingRfbClient::accept(RfbClient *newClient)
|
void PendingRfbClient::accept(RfbClient *newClient)
|
||||||
{
|
{
|
||||||
//qDebug() << "accepted connection";
|
// qDebug() << "accepted connection";
|
||||||
|
|
||||||
m_rfbClient->clientData = newClient;
|
m_rfbClient->clientData = newClient;
|
||||||
newClient->setOnHold(false);
|
newClient->setOnHold(false);
|
||||||
@@ -183,13 +186,16 @@ void PendingRfbClient::accept(RfbClient *newClient)
|
|||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
|
static void clientGoneHookNoop(rfbClientPtr cl)
|
||||||
|
{
|
||||||
|
Q_UNUSED(cl);
|
||||||
|
}
|
||||||
|
|
||||||
void PendingRfbClient::reject()
|
void PendingRfbClient::reject()
|
||||||
{
|
{
|
||||||
//qDebug() << "refused connection";
|
// qDebug() << "refused connection";
|
||||||
|
|
||||||
//override the clientGoneHook that was previously set by RfbServer
|
// override the clientGoneHook that was previously set by RfbServer
|
||||||
m_rfbClient->clientGoneHook = clientGoneHookNoop;
|
m_rfbClient->clientGoneHook = clientGoneHookNoop;
|
||||||
rfbCloseClient(m_rfbClient);
|
rfbCloseClient(m_rfbClient);
|
||||||
rfbClientConnectionGone(m_rfbClient);
|
rfbClientConnectionGone(m_rfbClient);
|
||||||
@@ -198,20 +204,20 @@ void PendingRfbClient::reject()
|
|||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PendingRfbClient::checkPassword(const QByteArray & encryptedPassword)
|
bool PendingRfbClient::checkPassword(const QByteArray &encryptedPassword)
|
||||||
{
|
{
|
||||||
Q_UNUSED(encryptedPassword);
|
Q_UNUSED(encryptedPassword);
|
||||||
|
|
||||||
return m_rfbClient->screen->authPasswdData == (void*)nullptr;
|
return m_rfbClient->screen->authPasswdData == (void *)nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PendingRfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const
|
bool PendingRfbClient::vncAuthCheckPassword(const QByteArray &password, const QByteArray &encryptedPassword) const
|
||||||
{
|
{
|
||||||
if (password.isEmpty() && encryptedPassword.isEmpty()) {
|
if (password.isEmpty() && encryptedPassword.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char passwd[MAXPWLEN+1]; // +1 to make sure there's a nullptr at the end
|
char passwd[MAXPWLEN + 1]; // +1 to make sure there's a nullptr at the end
|
||||||
unsigned char challenge[CHALLENGESIZE];
|
unsigned char challenge[CHALLENGESIZE];
|
||||||
|
|
||||||
memcpy(challenge, m_rfbClient->authChallenge, CHALLENGESIZE);
|
memcpy(challenge, m_rfbClient->authChallenge, CHALLENGESIZE);
|
||||||
@@ -228,27 +234,27 @@ bool PendingRfbClient::vncAuthCheckPassword(const QByteArray& password, const QB
|
|||||||
|
|
||||||
void PendingRfbClient::onSocketActivated()
|
void PendingRfbClient::onSocketActivated()
|
||||||
{
|
{
|
||||||
//Process not only one, but all pending messages.
|
// Process not only one, but all pending messages.
|
||||||
//poll() idea/code copied from vino:
|
// poll() idea/code copied from vino:
|
||||||
// Copyright (C) 2003 Sun Microsystems, Inc.
|
// Copyright (C) 2003 Sun Microsystems, Inc.
|
||||||
// License: GPL v2 or later
|
// License: GPL v2 or later
|
||||||
struct pollfd pollfd = { m_rfbClient->sock, POLLIN|POLLPRI, 0 };
|
struct pollfd pollfd = {m_rfbClient->sock, POLLIN | POLLPRI, 0};
|
||||||
|
|
||||||
while(poll(&pollfd, 1, 0) == 1) {
|
while (poll(&pollfd, 1, 0) == 1) {
|
||||||
if(m_rfbClient->state == rfbClientRec::RFB_INITIALISATION) {
|
if (m_rfbClient->state == rfbClientRec::RFB_INITIALISATION) {
|
||||||
m_notifier->setEnabled(false);
|
m_notifier->setEnabled(false);
|
||||||
//Client is Authenticated
|
// Client is Authenticated
|
||||||
processNewClient();
|
processNewClient();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rfbProcessClientMessage(m_rfbClient);
|
rfbProcessClientMessage(m_rfbClient);
|
||||||
|
|
||||||
//This is how we handle disconnection.
|
// This is how we handle disconnection.
|
||||||
//if rfbProcessClientMessage() finds out that it can't read the socket,
|
// if rfbProcessClientMessage() finds out that it can't read the socket,
|
||||||
//it closes it and sets it to -1. So, we just have to check this here
|
// it closes it and sets it to -1. So, we just have to check this here
|
||||||
//and call rfbClientConnectionGone() if necessary. This will call
|
// and call rfbClientConnectionGone() if necessary. This will call
|
||||||
//the clientGoneHook which in turn will remove this RfbClient instance
|
// the clientGoneHook which in turn will remove this RfbClient instance
|
||||||
//from the server manager and will call deleteLater() to delete it
|
// from the server manager and will call deleteLater() to delete it
|
||||||
if (m_rfbClient->sock == -1) {
|
if (m_rfbClient->sock == -1) {
|
||||||
qCDebug(KRFB) << "disconnected from socket signal";
|
qCDebug(KRFB) << "disconnected from socket signal";
|
||||||
m_notifier->setEnabled(false);
|
m_notifier->setEnabled(false);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class RfbClient : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled NOTIFY controlEnabledChanged)
|
Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled NOTIFY controlEnabledChanged)
|
||||||
Q_PROPERTY(bool onHold READ isOnHold WRITE setOnHold NOTIFY holdStatusChanged)
|
Q_PROPERTY(bool onHold READ isOnHold WRITE setOnHold NOTIFY holdStatusChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
explicit RfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
||||||
~RfbClient() override;
|
~RfbClient() override;
|
||||||
@@ -40,7 +41,7 @@ Q_SIGNALS:
|
|||||||
void holdStatusChanged(bool onHold);
|
void holdStatusChanged(bool onHold);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class RfbServer; //the following event handling methods are called by RfbServer
|
friend class RfbServer; // the following event handling methods are called by RfbServer
|
||||||
|
|
||||||
rfbClientPtr getRfbClientPtr();
|
rfbClientPtr getRfbClientPtr();
|
||||||
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
|
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
|
||||||
@@ -50,8 +51,8 @@ private Q_SLOTS:
|
|||||||
void onSocketActivated();
|
void onSocketActivated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///called by RfbServerManager to send framebuffer updates
|
/// called by RfbServerManager to send framebuffer updates
|
||||||
///and check for possible disconnection
|
/// and check for possible disconnection
|
||||||
void update();
|
void update();
|
||||||
friend class RfbServerManager;
|
friend class RfbServerManager;
|
||||||
|
|
||||||
@@ -59,10 +60,10 @@ private:
|
|||||||
Private *const d;
|
Private *const d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PendingRfbClient : public QObject
|
class PendingRfbClient : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PendingRfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
explicit PendingRfbClient(rfbClientPtr client, QObject *parent = nullptr);
|
||||||
~PendingRfbClient() override;
|
~PendingRfbClient() override;
|
||||||
@@ -77,22 +78,21 @@ protected Q_SLOTS:
|
|||||||
void reject();
|
void reject();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class RfbServer; // Following two methods are handled by RfbServer
|
||||||
friend class RfbServer; //Following two methods are handled by RfbServer
|
|
||||||
|
|
||||||
/** This method is supposed to check if the provided \a encryptedPassword
|
/** This method is supposed to check if the provided \a encryptedPassword
|
||||||
* matches the criteria for authenticating the client.
|
* matches the criteria for authenticating the client.
|
||||||
* The default implementation returns false if a password is required.
|
* The default implementation returns false if a password is required.
|
||||||
* Reimplement to do more useful stuff.
|
* Reimplement to do more useful stuff.
|
||||||
*/
|
*/
|
||||||
virtual bool checkPassword(const QByteArray & encryptedPassword);
|
virtual bool checkPassword(const QByteArray &encryptedPassword);
|
||||||
|
|
||||||
/** This method checks if the \a encryptedPassword that was sent from the remote
|
/** This method checks if the \a encryptedPassword that was sent from the remote
|
||||||
* user matches the \a password that you have specified locally to be the password
|
* user matches the \a password that you have specified locally to be the password
|
||||||
* for this connection. This assumes that the standard VNC authentication mechanism
|
* for this connection. This assumes that the standard VNC authentication mechanism
|
||||||
* is used. Returns true if the password matches or false otherwise.
|
* is used. Returns true if the password matches or false otherwise.
|
||||||
*/
|
*/
|
||||||
bool vncAuthCheckPassword(const QByteArray & password, const QByteArray & encryptedPassword) const;
|
bool vncAuthCheckPassword(const QByteArray &password, const QByteArray &encryptedPassword) const;
|
||||||
|
|
||||||
rfbClientPtr m_rfbClient;
|
rfbClientPtr m_rfbClient;
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#include "rfbserver.h"
|
#include "rfbserver.h"
|
||||||
#include "rfbservermanager.h"
|
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
#include <QSocketNotifier>
|
#include "rfbservermanager.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QSocketNotifier>
|
||||||
#include <QtGui/private/qtx11extras_p.h>
|
#include <QtGui/private/qtx11extras_p.h>
|
||||||
|
|
||||||
struct RfbServer::Private
|
struct RfbServer::Private
|
||||||
@@ -27,7 +27,8 @@ struct RfbServer::Private
|
|||||||
};
|
};
|
||||||
|
|
||||||
RfbServer::RfbServer(QObject *parent)
|
RfbServer::RfbServer(QObject *parent)
|
||||||
: QObject(parent), d(new Private)
|
: QObject(parent)
|
||||||
|
, d(new Private)
|
||||||
{
|
{
|
||||||
d->listeningAddress = "0.0.0.0";
|
d->listeningAddress = "0.0.0.0";
|
||||||
d->listeningPort = 0;
|
d->listeningPort = 0;
|
||||||
@@ -68,7 +69,7 @@ bool RfbServer::passwordSet() const
|
|||||||
return d->passwordSet;
|
return d->passwordSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServer::setListeningAddress(const QByteArray& address)
|
void RfbServer::setListeningAddress(const QByteArray &address)
|
||||||
{
|
{
|
||||||
d->listeningAddress = address;
|
d->listeningAddress = address;
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ bool RfbServer::start()
|
|||||||
d->screen->setXCutText = clipboardHook;
|
d->screen->setXCutText = clipboardHook;
|
||||||
d->screen->setXCutTextUTF8 = clipboardHookUtf8;
|
d->screen->setXCutTextUTF8 = clipboardHookUtf8;
|
||||||
} else {
|
} else {
|
||||||
//if we already have a screen, stop listening first
|
// if we already have a screen, stop listening first
|
||||||
rfbShutdownServer(d->screen, false);
|
rfbShutdownServer(d->screen, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,11 +183,11 @@ void RfbServer::updateFrameBuffer(char *fb, int width, int height, int depth)
|
|||||||
rfbNewFramebuffer(d->screen, fb, width, height, 8, 3, bpp);
|
rfbNewFramebuffer(d->screen, fb, width, height, 8, 3, bpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServer::updateScreen(const QList<QRect> & modifiedTiles)
|
void RfbServer::updateScreen(const QList<QRect> &modifiedTiles)
|
||||||
{
|
{
|
||||||
if (d->screen) {
|
if (d->screen) {
|
||||||
QList<QRect>::const_iterator it = modifiedTiles.constBegin();
|
QList<QRect>::const_iterator it = modifiedTiles.constBegin();
|
||||||
for(; it != modifiedTiles.constEnd(); ++it) {
|
for (; it != modifiedTiles.constEnd(); ++it) {
|
||||||
rfbMarkRectAsModified(d->screen, it->x(), it->y(), it->right(), it->bottom());
|
rfbMarkRectAsModified(d->screen, it->x(), it->y(), it->right(), it->bottom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,8 +204,9 @@ void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int
|
|||||||
rfbClientIteratorPtr iterator;
|
rfbClientIteratorPtr iterator;
|
||||||
rfbClientPtr cl;
|
rfbClientPtr cl;
|
||||||
|
|
||||||
if (x == screen->cursorX || y == screen->cursorY)
|
if (x == screen->cursorX || y == screen->cursorY) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOCK(screen->cursorMutex);
|
LOCK(screen->cursorMutex);
|
||||||
screen->cursorX = x;
|
screen->cursorX = x;
|
||||||
@@ -224,7 +226,7 @@ void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServer::updateCursorPosition(const QPoint & position)
|
void RfbServer::updateCursorPosition(const QPoint &position)
|
||||||
{
|
{
|
||||||
if (d->screen) {
|
if (d->screen) {
|
||||||
krfb_rfbSetCursorPosition(d->screen, nullptr, position.x(), position.y());
|
krfb_rfbSetCursorPosition(d->screen, nullptr, position.x(), position.y());
|
||||||
@@ -249,18 +251,18 @@ void RfbServer::onListenSocketActivated()
|
|||||||
|
|
||||||
void RfbServer::pendingClientFinished(RfbClient *client)
|
void RfbServer::pendingClientFinished(RfbClient *client)
|
||||||
{
|
{
|
||||||
//qDebug();
|
// qDebug();
|
||||||
if (client) {
|
if (client) {
|
||||||
RfbServerManager::instance()->addClient(client);
|
RfbServerManager::instance()->addClient(client);
|
||||||
client->getRfbClientPtr()->clientGoneHook = clientGoneHook;
|
client->getRfbClientPtr()->clientGoneHook = clientGoneHook;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
|
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
|
||||||
{
|
{
|
||||||
//qDebug() << "New client";
|
// qDebug() << "New client";
|
||||||
auto server = static_cast<RfbServer*>(cl->screen->screenData);
|
auto server = static_cast<RfbServer *>(cl->screen->screenData);
|
||||||
|
|
||||||
PendingRfbClient *pendingClient = server->newClient(cl);
|
PendingRfbClient *pendingClient = server->newClient(cl);
|
||||||
connect(pendingClient, &PendingRfbClient::finished,
|
connect(pendingClient, &PendingRfbClient::finished,
|
||||||
@@ -269,39 +271,39 @@ rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
|
|||||||
return RFB_CLIENT_ON_HOLD;
|
return RFB_CLIENT_ON_HOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
void RfbServer::clientGoneHook(rfbClientPtr cl)
|
void RfbServer::clientGoneHook(rfbClientPtr cl)
|
||||||
{
|
{
|
||||||
//qDebug() << "client gone";
|
// qDebug() << "client gone";
|
||||||
auto client = static_cast<RfbClient*>(cl->clientData);
|
auto client = static_cast<RfbClient *>(cl->clientData);
|
||||||
|
|
||||||
RfbServerManager::instance()->removeClient(client);
|
RfbServerManager::instance()->removeClient(client);
|
||||||
client->deleteLater();
|
client->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
|
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
|
||||||
{
|
{
|
||||||
auto client = static_cast<PendingRfbClient*>(cl->clientData);
|
auto client = static_cast<PendingRfbClient *>(cl->clientData);
|
||||||
Q_ASSERT(client);
|
Q_ASSERT(client);
|
||||||
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
|
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
|
void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
|
||||||
{
|
{
|
||||||
auto client = static_cast<RfbClient*>(cl->clientData);
|
auto client = static_cast<RfbClient *>(cl->clientData);
|
||||||
client->handleKeyboardEvent(down ? true : false, keySym);
|
client->handleKeyboardEvent(down ? true : false, keySym);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
|
void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
|
||||||
{
|
{
|
||||||
auto client = static_cast<RfbClient*>(cl->clientData);
|
auto client = static_cast<RfbClient *>(cl->clientData);
|
||||||
client->handleMouseEvent(bm, x, y);
|
client->handleMouseEvent(bm, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr /*cl*/)
|
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr /*cl*/)
|
||||||
{
|
{
|
||||||
QString text = QString::fromLatin1(str, len);
|
QString text = QString::fromLatin1(str, len);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
class RfbServer : public QObject
|
class RfbServer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RfbServer(QObject *parent = nullptr);
|
explicit RfbServer(QObject *parent = nullptr);
|
||||||
~RfbServer() override;
|
~RfbServer() override;
|
||||||
@@ -25,7 +26,7 @@ public:
|
|||||||
bool passwordRequired() const;
|
bool passwordRequired() const;
|
||||||
bool passwordSet() const;
|
bool passwordSet() const;
|
||||||
|
|
||||||
void setListeningAddress(const QByteArray & address);
|
void setListeningAddress(const QByteArray &address);
|
||||||
void setListeningPort(int port);
|
void setListeningPort(int port);
|
||||||
void setPasswordRequired(bool passwordRequired);
|
void setPasswordRequired(bool passwordRequired);
|
||||||
void setPasswordSet(bool passwordSet);
|
void setPasswordSet(bool passwordSet);
|
||||||
@@ -35,8 +36,8 @@ public Q_SLOTS:
|
|||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
|
||||||
void updateFrameBuffer(char *fb, int width, int height, int depth);
|
void updateFrameBuffer(char *fb, int width, int height, int depth);
|
||||||
void updateScreen(const QList<QRect> & modifiedTiles);
|
void updateScreen(const QList<QRect> &modifiedTiles);
|
||||||
void updateCursorPosition(const QPoint & position);
|
void updateCursorPosition(const QPoint &position);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void krfbSendServerCutText();
|
void krfbSendServerCutText();
|
||||||
|
|||||||
@@ -8,20 +8,20 @@
|
|||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#include "rfbservermanager.h"
|
#include "rfbservermanager.h"
|
||||||
#include "rfbserver.h"
|
|
||||||
#include "framebuffermanager.h"
|
#include "framebuffermanager.h"
|
||||||
#include "sockethelpers.h"
|
|
||||||
#include "krfbconfig.h"
|
#include "krfbconfig.h"
|
||||||
#include "krfbdebug.h"
|
#include "krfbdebug.h"
|
||||||
#include <QTimer>
|
#include "rfbserver.h"
|
||||||
|
#include "sockethelpers.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QGlobalStatic>
|
#include <QGlobalStatic>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
|
#include <QTimer>
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KUser>
|
|
||||||
#include <KNotification>
|
#include <KNotification>
|
||||||
|
#include <KUser>
|
||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
@@ -69,7 +69,6 @@ static const char *mask =
|
|||||||
" xxxxx "
|
" xxxxx "
|
||||||
" xxx ";
|
" xxx ";
|
||||||
|
|
||||||
|
|
||||||
struct RfbServerManagerStatic
|
struct RfbServerManagerStatic
|
||||||
{
|
{
|
||||||
RfbServerManager server;
|
RfbServerManager server;
|
||||||
@@ -77,7 +76,7 @@ struct RfbServerManagerStatic
|
|||||||
|
|
||||||
Q_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
|
Q_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
|
||||||
|
|
||||||
RfbServerManager* RfbServerManager::instance()
|
RfbServerManager *RfbServerManager::instance()
|
||||||
{
|
{
|
||||||
return &s_instance->server;
|
return &s_instance->server;
|
||||||
}
|
}
|
||||||
@@ -88,13 +87,13 @@ struct RfbServerManager::Private
|
|||||||
rfbCursorPtr myCursor;
|
rfbCursorPtr myCursor;
|
||||||
QByteArray desktopName;
|
QByteArray desktopName;
|
||||||
QTimer rfbUpdateTimer;
|
QTimer rfbUpdateTimer;
|
||||||
QSet<RfbServer*> servers;
|
QSet<RfbServer *> servers;
|
||||||
QSet<RfbClient*> clients;
|
QSet<RfbClient *> clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
RfbServerManager::RfbServerManager()
|
RfbServerManager::RfbServerManager()
|
||||||
: QObject(), d(new Private)
|
: QObject()
|
||||||
|
, d(new Private)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -113,19 +112,20 @@ QVariantMap RfbServerManager::s_pluginArgs;
|
|||||||
|
|
||||||
void RfbServerManager::init()
|
void RfbServerManager::init()
|
||||||
{
|
{
|
||||||
//qDebug();
|
// qDebug();
|
||||||
WId rootWindow = 0;
|
WId rootWindow = 0;
|
||||||
|
|
||||||
if (KWindowSystem::isPlatformX11()) {
|
if (KWindowSystem::isPlatformX11()) {
|
||||||
QPlatformNativeInterface* native = qApp->platformNativeInterface();
|
QPlatformNativeInterface *native = qApp->platformNativeInterface();
|
||||||
rootWindow = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), QGuiApplication::primaryScreen()));
|
rootWindow = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), QGuiApplication::primaryScreen()));
|
||||||
}
|
}
|
||||||
|
|
||||||
d->fb = FrameBufferManager::instance()->frameBuffer(rootWindow, s_pluginArgs);
|
d->fb = FrameBufferManager::instance()->frameBuffer(rootWindow, s_pluginArgs);
|
||||||
d->myCursor = rfbMakeXCursor(19, 19, (char *) cur, (char *) mask);
|
d->myCursor = rfbMakeXCursor(19, 19, (char *)cur, (char *)mask);
|
||||||
d->myCursor->cleanup = false;
|
d->myCursor->cleanup = false;
|
||||||
d->desktopName = QStringLiteral("%1@%2 (shared desktop)") //FIXME check if we can use utf8
|
d->desktopName = QStringLiteral("%1@%2 (shared desktop)") // FIXME check if we can use utf8
|
||||||
.arg(KUser().loginName(),QHostInfo::localHostName()).toLatin1();
|
.arg(KUser().loginName(), QHostInfo::localHostName())
|
||||||
|
.toLatin1();
|
||||||
|
|
||||||
connect(d->fb.data(), &FrameBuffer::frameBufferChanged, this, &RfbServerManager::updateFrameBuffer);
|
connect(d->fb.data(), &FrameBuffer::frameBufferChanged, this, &RfbServerManager::updateFrameBuffer);
|
||||||
connect(&d->rfbUpdateTimer, &QTimer::timeout, this, &RfbServerManager::updateScreens);
|
connect(&d->rfbUpdateTimer, &QTimer::timeout, this, &RfbServerManager::updateScreens);
|
||||||
@@ -144,26 +144,26 @@ void RfbServerManager::updateScreens()
|
|||||||
QList<QRect> rects = d->fb->modifiedTiles();
|
QList<QRect> rects = d->fb->modifiedTiles();
|
||||||
const QPoint currentCursorPos = d->fb->cursorPosition();
|
const QPoint currentCursorPos = d->fb->cursorPosition();
|
||||||
|
|
||||||
for (RfbServer* server : std::as_const(d->servers)) {
|
for (RfbServer *server : std::as_const(d->servers)) {
|
||||||
server->updateScreen(rects);
|
server->updateScreen(rects);
|
||||||
server->updateCursorPosition(currentCursorPos);
|
server->updateCursorPosition(currentCursorPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
//update() might disconnect some of the clients, which will synchronously
|
// update() might disconnect some of the clients, which will synchronously
|
||||||
//call the removeClient() method and will change d->clients, so we need
|
// call the removeClient() method and will change d->clients, so we need
|
||||||
//to copy the set here to avoid problems.
|
// to copy the set here to avoid problems.
|
||||||
const QSet<RfbClient*> clients = d->clients;
|
const QSet<RfbClient *> clients = d->clients;
|
||||||
for (RfbClient* client : clients) {
|
for (RfbClient *client : clients) {
|
||||||
client->update();
|
client->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServerManager::cleanup()
|
void RfbServerManager::cleanup()
|
||||||
{
|
{
|
||||||
//qDebug();
|
// qDebug();
|
||||||
|
|
||||||
//copy because d->servers is going to be modified while we delete the servers
|
// copy because d->servers is going to be modified while we delete the servers
|
||||||
const QSet<RfbServer*> servers = d->servers;
|
const QSet<RfbServer *> servers = d->servers;
|
||||||
qDeleteAll(servers);
|
qDeleteAll(servers);
|
||||||
|
|
||||||
Q_ASSERT(d->servers.isEmpty());
|
Q_ASSERT(d->servers.isEmpty());
|
||||||
@@ -174,12 +174,12 @@ void RfbServerManager::cleanup()
|
|||||||
d->fb.clear();
|
d->fb.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServerManager::registerServer(RfbServer* server)
|
void RfbServerManager::registerServer(RfbServer *server)
|
||||||
{
|
{
|
||||||
d->servers.insert(server);
|
d->servers.insert(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServerManager::unregisterServer(RfbServer* server)
|
void RfbServerManager::unregisterServer(RfbServer *server)
|
||||||
{
|
{
|
||||||
d->servers.remove(server);
|
d->servers.remove(server);
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
|
|||||||
bpp = 4;
|
bpp = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
//qDebug() << "bpp: " << bpp;
|
// qDebug() << "bpp: " << bpp;
|
||||||
|
|
||||||
rfbLogEnable(KRFB().isDebugEnabled());
|
rfbLogEnable(KRFB().isDebugEnabled());
|
||||||
|
|
||||||
@@ -213,10 +213,10 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
|
|||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServerManager::addClient(RfbClient* cc)
|
void RfbServerManager::addClient(RfbClient *cc)
|
||||||
{
|
{
|
||||||
if (d->clients.size() == 0) {
|
if (d->clients.size() == 0) {
|
||||||
//qDebug() << "Starting framebuffer monitor";
|
// qDebug() << "Starting framebuffer monitor";
|
||||||
d->fb->startMonitor();
|
d->fb->startMonitor();
|
||||||
d->rfbUpdateTimer.start(50ms);
|
d->rfbUpdateTimer.start(50ms);
|
||||||
}
|
}
|
||||||
@@ -228,11 +228,11 @@ void RfbServerManager::addClient(RfbClient* cc)
|
|||||||
Q_EMIT clientConnected(cc);
|
Q_EMIT clientConnected(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RfbServerManager::removeClient(RfbClient* cc)
|
void RfbServerManager::removeClient(RfbClient *cc)
|
||||||
{
|
{
|
||||||
d->clients.remove(cc);
|
d->clients.remove(cc);
|
||||||
if (d->clients.size() == 0) {
|
if (d->clients.size() == 0) {
|
||||||
//qDebug() << "Stopping framebuffer monitor";
|
// qDebug() << "Stopping framebuffer monitor";
|
||||||
d->fb->stopMonitor();
|
d->fb->stopMonitor();
|
||||||
d->rfbUpdateTimer.stop();
|
d->rfbUpdateTimer.stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#ifndef RFBSERVERMANAGER_H
|
#ifndef RFBSERVERMANAGER_H
|
||||||
#define RFBSERVERMANAGER_H
|
#define RFBSERVERMANAGER_H
|
||||||
|
|
||||||
#include "rfb.h"
|
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
|
#include "rfb.h"
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ class RfbServer;
|
|||||||
class RfbServerManager : public QObject
|
class RfbServerManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static RfbServerManager *instance();
|
static RfbServerManager *instance();
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
|
|
||||||
#include "sockethelpers.h"
|
#include "sockethelpers.h"
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
QString peerAddress(int sock)
|
QString peerAddress(int sock)
|
||||||
{
|
{
|
||||||
@@ -86,4 +86,3 @@ unsigned short localPort(int sock)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include "trayicon.h"
|
#include "trayicon.h"
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "rfbservermanager.h"
|
|
||||||
#include "rfbclient.h"
|
#include "rfbclient.h"
|
||||||
|
#include "rfbservermanager.h"
|
||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@@ -17,11 +17,11 @@
|
|||||||
#include <KAboutApplicationDialog>
|
#include <KAboutApplicationDialog>
|
||||||
#include <KAboutData>
|
#include <KAboutData>
|
||||||
#include <KActionCollection>
|
#include <KActionCollection>
|
||||||
#include <QDialog>
|
#include <KConfigGroup>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KStandardAction>
|
#include <KStandardAction>
|
||||||
#include <KToggleAction>
|
#include <KToggleAction>
|
||||||
#include <KConfigGroup>
|
#include <QDialog>
|
||||||
|
|
||||||
class ClientActions
|
class ClientActions
|
||||||
{
|
{
|
||||||
@@ -37,7 +37,7 @@ private:
|
|||||||
QAction *m_separator = nullptr;
|
QAction *m_separator = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
ClientActions::ClientActions(RfbClient* client, QMenu* menu, QAction* before)
|
ClientActions::ClientActions(RfbClient *client, QMenu *menu, QAction *before)
|
||||||
: m_menu(menu)
|
: m_menu(menu)
|
||||||
{
|
{
|
||||||
m_title = m_menu->insertSection(before, client->name());
|
m_title = m_menu->insertSection(before, client->name());
|
||||||
@@ -99,20 +99,20 @@ TrayIcon::TrayIcon(QWidget *mainWindow)
|
|||||||
contextMenu()->addAction(m_aboutAction);
|
contextMenu()->addAction(m_aboutAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::onClientConnected(RfbClient* client)
|
void TrayIcon::onClientConnected(RfbClient *client)
|
||||||
{
|
{
|
||||||
if (m_clientActions.isEmpty()) { //first client connected
|
if (m_clientActions.isEmpty()) { // first client connected
|
||||||
setIconByName(QStringLiteral("krfb-symbolic"));
|
setIconByName(QStringLiteral("krfb-symbolic"));
|
||||||
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
|
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
|
||||||
setStatus(KStatusNotifierItem::Active);
|
setStatus(KStatusNotifierItem::Active);
|
||||||
} else { //Nth client connected, N != 1
|
} else { // Nth client connected, N != 1
|
||||||
setToolTipTitle(i18n("Desktop Sharing - connected"));
|
setToolTipTitle(i18n("Desktop Sharing - connected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clientActions[client] = new ClientActions(client, contextMenu(), m_aboutAction);
|
m_clientActions[client] = new ClientActions(client, contextMenu(), m_aboutAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrayIcon::onClientDisconnected(RfbClient* client)
|
void TrayIcon::onClientDisconnected(RfbClient *client)
|
||||||
{
|
{
|
||||||
ClientActions *actions = m_clientActions.take(client);
|
ClientActions *actions = m_clientActions.take(client);
|
||||||
delete actions;
|
delete actions;
|
||||||
@@ -121,7 +121,7 @@ void TrayIcon::onClientDisconnected(RfbClient* client)
|
|||||||
setIconByPixmap(QIcon::fromTheme(QStringLiteral("krfb-symbolic")).pixmap(22, 22, QIcon::Disabled));
|
setIconByPixmap(QIcon::fromTheme(QStringLiteral("krfb-symbolic")).pixmap(22, 22, QIcon::Disabled));
|
||||||
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
|
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
|
||||||
setStatus(KStatusNotifierItem::Passive);
|
setStatus(KStatusNotifierItem::Passive);
|
||||||
} else if (m_clientActions.size() == 1) { //clients number dropped back to 1
|
} else if (m_clientActions.size() == 1) { // clients number dropped back to 1
|
||||||
RfbClient *client = m_clientActions.constBegin().key();
|
RfbClient *client = m_clientActions.constBegin().key();
|
||||||
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
|
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class ClientActions;
|
|||||||
class TrayIcon : public KStatusNotifierItem
|
class TrayIcon : public KStatusNotifierItem
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TrayIcon(QWidget *mainWindow);
|
explicit TrayIcon(QWidget *mainWindow);
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ public Q_SLOTS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QAction *m_aboutAction;
|
QAction *m_aboutAction;
|
||||||
QHash<RfbClient*, ClientActions*> m_clientActions;
|
QHash<RfbClient *, ClientActions *> m_clientActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user