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:
Antti Savolainen
2026-04-24 11:36:02 +03:00
parent 88f1636fef
commit c521740404
48 changed files with 704 additions and 679 deletions

View File

@@ -13,13 +13,13 @@
#include <QtGui/private/qtx11extras_p.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
enum {
LEFTSHIFT = 1,
RIGHTSHIFT = 2,
ALTGR = 4
ALTGR = 4,
};
class EventData
@@ -27,7 +27,7 @@ class EventData
public:
EventData();
//keyboard
// keyboard
Display *dpy = nullptr;
signed char modifiers[0x100] = {};
KeyCode keycodes[0x100] = {};
@@ -36,7 +36,7 @@ public:
KeyCode altGrCode = 0;
char modifierState = 0;
//mouse
// mouse
int buttonMask = 0;
int x = 0;
int y = 0;
@@ -57,7 +57,7 @@ void EventData::init()
buttonMask = 0;
dpy = QX11Info::display();
//initialize keycodes
// initialize keycodes
KeySym key, *keymap;
int i, j, minkey, maxkey, syms_per_keycode;
@@ -66,14 +66,14 @@ void EventData::init()
XDisplayKeycodes(dpy, &minkey, &maxkey);
Q_ASSERT(minkey >= 8);
Q_ASSERT(maxkey < 256);
keymap = (KeySym *) XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
keymap = (KeySym *)XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
Q_ASSERT(keymap);
for (i = minkey; i <= maxkey; i++) {
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)) {
keycodes[key] = i;
@@ -128,8 +128,13 @@ static void tweakModifiers(signed char mod, bool down)
void X11EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
{
#define ADJUSTMOD(sym,state) \
if(keySym==sym) { if(down) data->modifierState|=state; else data->modifierState&=~state; }
#define ADJUSTMOD(sym, state) \
if (keySym == sym) { \
if (down) \
data->modifierState |= state; \
else \
data->modifierState &= ~state; \
}
if (QX11Info::isPlatformX11()) {
ADJUSTMOD(XK_Shift_L, LEFTSHIFT);
@@ -160,11 +165,11 @@ void X11EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
}
}
}
/*
// Wayland platform and pipweire plugin in use
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) {
/*
// Wayland platform and pipweire plugin in use
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("pw")) {
}*/
}*/
}
void X11EventHandler::handlePointer(int buttonMask, int x, int y)
@@ -173,11 +178,11 @@ void X11EventHandler::handlePointer(int buttonMask, int x, int y)
XTestFakeMotionEvent(data->dpy, 0, x, y, CurrentTime);
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,
i + 1,
(buttonMask&(1 << i)) ? True : False,
CurrentTime);
i + 1,
(buttonMask & (1 << i)) ? True : False,
CurrentTime);
}
}

View File

@@ -14,15 +14,15 @@
class X11EventHandler : public EventHandler
{
Q_OBJECT
public:
explicit X11EventHandler(QObject *parent = nullptr)
: EventHandler(parent)
{
};
}
void handleKeyboard(bool down, rfbKeySym key) override;
void handlePointer(int buttonMask, int x, int y) override;
};
#endif

View File

@@ -22,11 +22,11 @@ X11EventsPlugin::X11EventsPlugin(QObject *parent, const QVariantList &args)
EventHandler *X11EventsPlugin::eventHandler()
{
// works only under X11
if(!QX11Info::isPlatformX11())
if (!QX11Info::isPlatformX11()) {
return nullptr;
}
return new X11EventHandler();
}
#include "x11eventsplugin.moc"

View File

@@ -16,6 +16,7 @@ class EventHandler;
class X11EventsPlugin : public EventsPlugin
{
Q_OBJECT
public:
X11EventsPlugin(QObject *parent, const QVariantList &args);
@@ -25,5 +26,4 @@ private:
Q_DISABLE_COPY(X11EventsPlugin)
};
#endif // Header guard
#endif // Header guard

View File

@@ -21,7 +21,7 @@ class EventData
public:
EventData();
//mouse
// mouse
int buttonMask = 0;
int x = 0;
int y = 0;
@@ -42,7 +42,7 @@ EventData::EventData()
void EventData::init()
{
dbusXdpRemoteDesktopService.reset(new OrgFreedesktopPortalRemoteDesktopInterface(QStringLiteral("org.freedesktop.portal.Desktop"),
QStringLiteral("/org/freedesktop/portal/desktop"), QDBusConnection::sessionBus()));
QStringLiteral("/org/freedesktop/portal/desktop"), QDBusConnection::sessionBus()));
}
void XdpEventHandler::handleKeyboard(bool down, rfbKeySym keySym)
@@ -68,7 +68,7 @@ void XdpEventHandler::handlePointer(int buttonMask, int x, int y)
if (buttonMask != data->buttonMask) {
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) {
int prevButtonState = (data->buttonMask >> i) & 0x01;
int currentButtonState = (buttonMask >> i) & 0x01;
@@ -81,22 +81,22 @@ void XdpEventHandler::handlePointer(int buttonMask, int x, int y)
int steps = 0;
switch (i) {
case 3:
axis = 0; // Vertical
axis = 0; // Vertical
steps = -1;
break;
case 4:
axis = 0; // Vertical
axis = 0; // Vertical
steps = 1;
break;
case 5:
axis = 1; // Horizontal
axis = 1; // Horizontal
steps = -1;
break;
case 6:
axis = 1; // Horizontal
axis = 1; // Horizontal
steps = 1;
break;
}
}
data->dbusXdpRemoteDesktopService->NotifyPointerAxisDiscrete(sessionHandle, QVariantMap(), axis, steps);
}

View File

@@ -14,11 +14,10 @@
class XdpEventHandler : public EventHandler
{
Q_OBJECT
public:
void handleKeyboard(bool down, rfbKeySym key) override;
void handlePointer(int buttonMask, int x, int y) override;
};
#endif

View File

@@ -26,4 +26,3 @@ EventHandler *XdpEventsPlugin::eventHandler()
}
#include "xdpeventsplugin.moc"

View File

@@ -18,6 +18,7 @@ class EventHandler;
class XdpEventsPlugin : public EventsPlugin
{
Q_OBJECT
public:
XdpEventsPlugin(QObject *parent, const QVariantList &args);
@@ -27,6 +28,4 @@ private:
Q_DISABLE_COPY(XdpEventsPlugin)
};
#endif // Header guard
#endif // Header guard

View File

@@ -8,16 +8,16 @@
#include "config-krfb.h"
// system
#include <sys/mman.h>
#include <cstring>
#include <sys/mman.h>
// Qt
#include <QCoreApplication>
#include <QDebug>
#include <QGuiApplication>
#include <QRandomGenerator>
#include <QScreen>
#include <QSocketNotifier>
#include <QDebug>
#include <QRandomGenerator>
#include <KConfigGroup>
#include <KSharedConfig>
@@ -28,13 +28,13 @@
// pipewire
#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 "pw_framebuffer.h"
#include "screencasting.h"
#include <PipeWireSourceStream>
#include "xdp_dbus_remotedesktop_interface.h"
#include "xdp_dbus_screencast_interface.h"
#include <DmaBufHandler>
#include <PipeWireSourceStream>
static const int BYTES_PER_PIXEL = 4;
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::Streams);
const QDBusArgument &operator >> (const QDBusArgument &arg, PWFrameBuffer::Stream &stream)
const QDBusArgument &operator>>(const QDBusArgument &arg, PWFrameBuffer::Stream &stream)
{
arg.beginStructure();
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
* whole logic resides, for more info search for "d-pointer pattern" information.
*/
class PWFrameBuffer::Private {
class PWFrameBuffer::Private
{
public:
Private(PWFrameBuffer *q);
~Private();
@@ -111,7 +112,7 @@ PWFrameBuffer::Private::Private(PWFrameBuffer *q)
: q(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);
});
}
@@ -125,11 +126,11 @@ void PWFrameBuffer::Private::initDbus()
{
qInfo() << "Initializing D-Bus connectivity with XDG Desktop Portal";
dbusXdpScreenCastService.reset(new OrgFreedesktopPortalScreenCastInterface(QStringLiteral("org.freedesktop.portal.Desktop"),
QStringLiteral("/org/freedesktop/portal/desktop"),
QDBusConnection::sessionBus()));
QStringLiteral("/org/freedesktop/portal/desktop"),
QDBusConnection::sessionBus()));
dbusXdpRemoteDesktopService.reset(new OrgFreedesktopPortalRemoteDesktopInterface(QStringLiteral("org.freedesktop.portal.Desktop"),
QStringLiteral("/org/freedesktop/portal/desktop"),
QDBusConnection::sessionBus()));
QStringLiteral("/org/freedesktop/portal/desktop"),
QDBusConnection::sessionBus()));
auto version = dbusXdpScreenCastService->version();
if (version < MIN_SUPPORTED_XDP_KDE_SC_VERSION) {
qCWarning(KRFB_FB_PIPEWIRE) << "Unsupported XDG Portal screencast interface version:" << version;
@@ -138,10 +139,9 @@ void PWFrameBuffer::Private::initDbus()
}
// create session
auto sessionParameters = QVariantMap {
{ QStringLiteral("session_handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) },
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
};
auto sessionParameters = QVariantMap{
{QStringLiteral("session_handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())},
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
auto sessionReply = dbusXdpRemoteDesktopService->CreateSession(sessionParameters);
sessionReply.waitForFinished();
if (!sessionReply.isValid()) {
@@ -182,11 +182,11 @@ void PWFrameBuffer::Private::handleSessionCreated(quint32 code, const QVariantMa
sessionPath = QDBusObjectPath(results.value(QStringLiteral("session_handle")).toString());
// 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
{ QStringLiteral("types"), QVariant::fromValue<uint>(7) }, // request all (KeyBoard, Pointer, TouchScreen)
{ 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("types"), QVariant::fromValue<uint>(7)}, // request all (KeyBoard, Pointer, TouchScreen)
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())},
{QStringLiteral("persist_mode"), QVariant::fromValue<uint>(2)}, // Persist permission until explicitly revoked by user
};
KConfigGroup stateConfig = KSharedConfig::openStateConfig()->group(QStringLiteral("XdgPortal"));
@@ -231,11 +231,10 @@ void PWFrameBuffer::Private::handleDevicesSelected(quint32 code, const QVariantM
}
// select sources for the session
auto selectionOptions = QVariantMap {
{ QStringLiteral("types"), QVariant::fromValue<uint>(1) }, // only MONITOR is supported
{ QStringLiteral("multiple"), false },
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
};
auto selectionOptions = QVariantMap{
{QStringLiteral("types"), QVariant::fromValue<uint>(1)}, // only MONITOR is supported
{QStringLiteral("multiple"), false},
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
auto selectorReply = dbusXdpScreenCastService->SelectSources(sessionPath, selectionOptions);
selectorReply.waitForFinished();
if (!selectorReply.isValid()) {
@@ -273,9 +272,8 @@ void PWFrameBuffer::Private::handleSourcesSelected(quint32 code, const QVariantM
}
// start session
auto startParameters = QVariantMap {
{ QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate()) }
};
auto startParameters = QVariantMap{
{QStringLiteral("handle_token"), QStringLiteral("krfb%1").arg(QRandomGenerator::global()->generate())}};
auto startReply = dbusXdpRemoteDesktopService->Start(sessionPath, QString(), startParameters);
startReply.waitForFinished();
QDBusConnection::sessionBus().connect(QString(),
@@ -286,7 +284,6 @@ void PWFrameBuffer::Private::handleSourcesSelected(quint32 code, const QVariantM
SLOT(handleXdpRemoteDesktopStarted(uint, QVariantMap)));
}
void PWFrameBuffer::handleXdpRemoteDesktopStarted(quint32 code, const QVariantMap &results)
{
d->handleRemoteDesktopStarted(code, results);
@@ -376,9 +373,9 @@ void PWFrameBuffer::Private::handleFrame(const PipeWireFrame &frame)
#endif
else if (frame.dmabuf) {
// 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);
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)) {
stream->renegotiateModifierFailed(frame.format, frame.dmabuf->modifier);
qCDebug(KRFB_FB_PIPEWIRE) << "Failed to download frame.";
@@ -404,7 +401,7 @@ void PWFrameBuffer::Private::setVideoSize(const QSize &size)
}
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) {
qCWarning(KRFB_FB_PIPEWIRE) << "Failed to allocate buffer";
isValid = false;
@@ -420,8 +417,8 @@ PWFrameBuffer::Private::~Private()
}
PWFrameBuffer::PWFrameBuffer(QObject *parent)
: FrameBuffer (parent),
d(new Private(this))
: FrameBuffer(parent)
, d(new Private(this))
{
}
@@ -436,7 +433,7 @@ void PWFrameBuffer::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;
using namespace KWayland::Client;
@@ -448,13 +445,14 @@ void PWFrameBuffer::startVirtualMonitor(const QString& name, const QSize& resolu
}
auto registry = new Registry(this);
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")
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") {
return;
}
auto screencasting = new Screencasting(registry, wlname, version, this);
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);
});
});
@@ -498,19 +496,18 @@ void PWFrameBuffer::getServerFormat(rfbPixelFormat &format)
void PWFrameBuffer::startMonitor()
{
}
void PWFrameBuffer::stopMonitor()
{
}
QVariant PWFrameBuffer::customProperty(const QString &property) const
{
if (property == QLatin1String("stream_node_id")) {
return QVariant::fromValue<uint>(d->stream->nodeId());
} if (property == QLatin1String("session_handle")) {
}
if (property == QLatin1String("session_handle")) {
return QVariant::fromValue<QDBusObjectPath>(d->sessionPath);
}

View File

@@ -8,8 +8,8 @@
#define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
#include "framebuffer.h"
#include <QWidget>
#include <QVariantMap>
#include <QWidget>
/**
* @brief The PWFrameBuffer class - framebuffer implementation based on XDG Desktop Portal ScreenCast interface.
@@ -17,11 +17,13 @@
*
* @author Oleg Chernovskiy <kanedias@xaker.ru>
*/
class PWFrameBuffer: public FrameBuffer
class PWFrameBuffer : public FrameBuffer
{
Q_OBJECT
public:
using Stream = struct {
using Stream = struct
{
uint nodeId;
QVariantMap map;
};
@@ -33,10 +35,10 @@ public:
void initDBus();
void startVirtualMonitor(const QString &name, const QSize &resolution, qreal dpr);
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
void getServerFormat(rfbPixelFormat &format) override;
void startMonitor() override;
void stopMonitor() override;

View File

@@ -4,7 +4,6 @@
SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "pw_framebufferplugin.h"
#include "pw_framebuffer.h"
#include <KPluginFactory>
@@ -16,7 +15,6 @@ PWFrameBufferPlugin::PWFrameBufferPlugin(QObject *parent, const QVariantList &ar
{
}
FrameBuffer *PWFrameBufferPlugin::frameBuffer(const QVariantMap &args)
{
auto pwfb = new PWFrameBuffer;

View File

@@ -1,29 +1,27 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2018 Oleg Chernovskiy <kanedias@xaker.ru>
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2018 Oleg Chernovskiy <kanedias@xaker.ru>
SPDX-License-Identifier: GPL-3.0-or-later
SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
#define KRFB_FRAMEBUFFER_PW_PWFRAMEBUFFERPLUGIN_H
#include "framebufferplugin.h"
class FrameBuffer;
class PWFrameBufferPlugin: public FrameBufferPlugin
class PWFrameBufferPlugin : public FrameBufferPlugin
{
Q_OBJECT
Q_OBJECT
public:
PWFrameBufferPlugin(QObject *parent, const QVariantList &args);
PWFrameBufferPlugin(QObject *parent, const QVariantList &args);
FrameBuffer *frameBuffer(const QVariantMap &args) override;
FrameBuffer *frameBuffer(const QVariantMap &args) override;
private:
Q_DISABLE_COPY(PWFrameBufferPlugin)
Q_DISABLE_COPY(PWFrameBufferPlugin)
};
#endif // Header guard
#endif // Header guard

View File

@@ -12,8 +12,8 @@
#endif
#include <KWayland/Client/registry.h>
#include <QDebug>
#include <QRect>
#include <QPointer>
#include <QRect>
using namespace KWayland::Client;
@@ -99,7 +99,7 @@ Screencasting::Screencasting(Registry *registry, int id, int version, QObject *p
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);
stream->d->init(d->stream_virtual_output(name, resolution.width(), resolution.height(), wl_fixed_from_double(dpr), mode));

View File

@@ -6,9 +6,9 @@
#pragma once
#include <QList>
#include <QObject>
#include <QSharedPointer>
#include <QList>
#include <optional>
struct zkde_screencast_unstable_v1;
@@ -17,9 +17,11 @@ namespace KWayland
{
namespace Client
{
class PlasmaWindow;
class Registry;
class Output;
}
}
@@ -29,6 +31,7 @@ class ScreencastingStreamPrivate;
class ScreencastingStream : public QObject
{
Q_OBJECT
public:
ScreencastingStream(QObject *parent);
~ScreencastingStream() override;
@@ -48,6 +51,7 @@ private:
class Screencasting : public QObject
{
Q_OBJECT
public:
explicit Screencasting(QObject *parent = nullptr);
explicit Screencasting(KWayland::Client::Registry *registry, int id, int version, QObject *parent = nullptr);

View File

@@ -7,22 +7,22 @@
#include "xcb_framebuffer.h"
#include "krfb_fb_xcb_debug.h"
#include <xcb/xproto.h>
#include <xcb/damage.h>
#include <xcb/shm.h>
#include <xcb/xcb_image.h>
#include <xcb/xproto.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <QAbstractNativeEventFilter>
#include <QApplication>
#include <QGuiApplication>
#include <QScreen>
#include <QAbstractNativeEventFilter>
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/private/qtx11extras_p.h>
#include <qpa/qplatformnativeinterface.h>
class KrfbXCBEventFilter: public QAbstractNativeEventFilter
class KrfbXCBEventFilter : public QAbstractNativeEventFilter
{
public:
KrfbXCBEventFilter(XCBFrameBuffer *owner);
@@ -39,33 +39,33 @@ public:
XCBFrameBuffer *fb_owner;
};
KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
xdamageBaseEvent(0), xdamageBaseError(0),
xshmBaseEvent(0), xshmBaseError(0), xshmAvail(false),
fb_owner(owner)
KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner)
: xdamageBaseEvent(0)
, xdamageBaseError(0)
, xshmBaseEvent(0)
, xshmBaseError(0)
, xshmAvail(false)
, fb_owner(owner)
{
const xcb_query_extension_reply_t *xdamage_data = xcb_get_extension_data(
QX11Info::connection(), &xcb_damage_id);
QX11Info::connection(), &xcb_damage_id);
if (xdamage_data) {
// also query extension version!
// ATTENTION: if we don't do that, xcb_damage_create() will always FAIL!
xcb_damage_query_version_reply_t *xdamage_version = xcb_damage_query_version_reply(
QX11Info::connection(),
xcb_damage_query_version(
QX11Info::connection(),
XCB_DAMAGE_MAJOR_VERSION,
XCB_DAMAGE_MINOR_VERSION),
nullptr);
QX11Info::connection(),
xcb_damage_query_version(
QX11Info::connection(),
XCB_DAMAGE_MAJOR_VERSION,
XCB_DAMAGE_MINOR_VERSION),
nullptr);
if (!xdamage_version) {
qWarning() << "xcb framebuffer: ERROR: Failed to get XDamage extension version!\n";
return;
}
#ifdef _DEBUG
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: XDamage extension version:" <<
xdamage_version->major_version << "." << xdamage_version->minor_version;
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: XDamage extension version:" << xdamage_version->major_version << "." << xdamage_version->minor_version;
#endif
free(xdamage_version);
@@ -76,7 +76,7 @@ KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
// XShm presence is optional. If it is present, all image getting
// operations will be faster, without XShm it will only be slower.
const xcb_query_extension_reply_t *xshm_data = xcb_get_extension_data(
QX11Info::connection(), &xcb_shm_id);
QX11Info::connection(), &xcb_shm_id);
if (xshm_data) {
xshmAvail = true;
xshmBaseEvent = xshm_data->first_event;
@@ -93,19 +93,21 @@ KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
}
}
bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
void *message, qintptr *result) {
Q_UNUSED(result); // "result" is only used on windows
void *message, qintptr *result)
{
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") {
auto ev = static_cast<xcb_generic_event_t *>(message);
if ((ev->response_type & 0x7F) == (xdamageBaseEvent + XCB_DAMAGE_NOTIFY)) {
// this is xdamage notification
this->fb_owner->handleXDamageNotify(ev);
return true; // filter out this event, stop its processing
return true; // filter out this event, stop its processing
}
}
@@ -113,37 +115,38 @@ bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
return false;
}
class XCBFrameBuffer::P {
class XCBFrameBuffer::P
{
public:
xcb_damage_damage_t damage;
xcb_shm_segment_info_t shminfo;
xcb_screen_t *rootScreen; // X screen info (all monitors)
xcb_image_t *framebufferImage;
xcb_image_t *updateTile;
xcb_damage_damage_t damage;
xcb_shm_segment_info_t shminfo;
xcb_screen_t *rootScreen; // X screen info (all monitors)
xcb_image_t *framebufferImage;
xcb_image_t *updateTile;
KrfbXCBEventFilter *x11EvtFilter;
KrfbXCBEventFilter *x11EvtFilter;
bool running;
bool running;
QRect area; // capture area, primary monitor coordinates
WId win;
QRect area; // capture area, primary monitor coordinates
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_iterator_t screens_iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter))
if (screen_num == 0)
for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter)) {
if (screen_num == 0) {
screen = screens_iter.data;
}
}
return screen;
}
XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
FrameBuffer(parent), d(new XCBFrameBuffer::P)
XCBFrameBuffer::XCBFrameBuffer(QObject *parent)
: FrameBuffer(parent)
, d(new XCBFrameBuffer::P)
{
d->running = false;
d->damage = XCB_NONE;
@@ -160,17 +163,17 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
QScreen *primaryScreen = QGuiApplication::primaryScreen();
if (primaryScreen) {
QPlatformNativeInterface* native = qApp->platformNativeInterface();
QPlatformNativeInterface *native = qApp->platformNativeInterface();
d->win = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), primaryScreen));
qreal scaleFactor = primaryScreen->devicePixelRatio();
d->area = { primaryScreen->geometry().topLeft() * scaleFactor,
primaryScreen->geometry().bottomRight() * scaleFactor };
d->area = {primaryScreen->geometry().topLeft() * scaleFactor,
primaryScreen->geometry().bottomRight() * scaleFactor};
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: Primary screen: " << primaryScreen->name()
<< ", geometry: " << primaryScreen->geometry()
<< ", device scaling: " << scaleFactor
<< ", native size: " << d->area
<< ", depth: " << primaryScreen->depth();
<< ", geometry: " << primaryScreen->geometry()
<< ", device scaling: " << scaleFactor
<< ", native size: " << d->area
<< ", depth: " << primaryScreen->depth();
} else {
qWarning() << "xcb framebuffer: ERROR: Failed to get application's primary screen info!";
return;
@@ -187,9 +190,9 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
if (d->framebufferImage) {
#ifdef _DEBUG
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: Got primary screen image. bpp: " << d->framebufferImage->bpp
<< ", size (" << d->framebufferImage->width << d->framebufferImage->height << ")"
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->stride;
<< ", size (" << d->framebufferImage->width << d->framebufferImage->height << ")"
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->stride;
#endif
this->fb = (char *)d->framebufferImage->data;
} else {
@@ -204,25 +207,25 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
// "If base == 0 and bytes == ~0 and data == 0, no storage will be auto-allocated."
// Width and height of the image = size of the capture area.
d->updateTile = xcb_image_create_native(
QX11Info::connection(),
d->area.width(), // width
d->area.height(), // height
XCB_IMAGE_FORMAT_Z_PIXMAP, // image format
d->rootScreen->root_depth, // depth
nullptr, // base address = 0
(uint32_t)~0, // bytes = 0xffffffff
nullptr); // data = 0
QX11Info::connection(),
d->area.width(), // width
d->area.height(), // height
XCB_IMAGE_FORMAT_Z_PIXMAP, // image format
d->rootScreen->root_depth, // depth
nullptr, // base address = 0
(uint32_t)~0, // bytes = 0xffffffff
nullptr); // data = 0
if (d->updateTile) {
#ifdef _DEBUG
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: Successfully created new empty image in native format"
<< "\n size: " << d->updateTile->width << "x" << d->updateTile->height
<< "(stride: " << d->updateTile->stride << ")"
<< "\n bpp, depth: " << d->updateTile->bpp << d->updateTile->depth // 32, 24
<< "\n addr of base, data: " << d->updateTile->base << (void *)d->updateTile->data
<< "\n size: " << d->updateTile->size
<< "\n image byte order = " << d->updateTile->byte_order // == 0 .._LSB_FIRST
<< "\n image bit order = " << d->updateTile->bit_order // == 1 .._MSB_FIRST
<< "\n image plane_mask = " << d->updateTile->plane_mask; // == 16777215 == 0x00FFFFFF
<< "\n size: " << d->updateTile->width << "x" << d->updateTile->height
<< "(stride: " << d->updateTile->stride << ")"
<< "\n bpp, depth: " << d->updateTile->bpp << d->updateTile->depth // 32, 24
<< "\n addr of base, data: " << d->updateTile->base << (void *)d->updateTile->data
<< "\n size: " << d->updateTile->size
<< "\n image byte order = " << d->updateTile->byte_order // == 0 .._LSB_FIRST
<< "\n image bit order = " << d->updateTile->bit_order // == 1 .._MSB_FIRST
<< "\n image plane_mask = " << d->updateTile->plane_mask; // == 16777215 == 0x00FFFFFF
#endif
// allocate shared memory block only once, make its size large enough
@@ -245,13 +248,13 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
// will return 1 on success (yes!)
int shmget_res = xcb_image_shm_get(
QX11Info::connection(),
d->win,
d->updateTile,
d->shminfo,
d->area.left(), // x
d->area.top(), // y (size taken from image structure itself)?
0xFFFFFFFF);
QX11Info::connection(),
d->win,
d->updateTile,
d->shminfo,
d->area.left(), // x
d->area.top(), // y (size taken from image structure itself)?
0xFFFFFFFF);
if (shmget_res == 0) {
// error! shared mem not working?
@@ -277,31 +280,34 @@ XCBFrameBuffer::XCBFrameBuffer(QObject *parent):
#ifdef _DEBUG
qCDebug(KRFB_FB_XCB) << "xcb framebuffer: XCBFrameBuffer(), xshm base event = " << d->x11EvtFilter->xshmBaseEvent
<< ", xshm base error = " << d->x11EvtFilter->xdamageBaseError
<< ", xdamage base event = " << d->x11EvtFilter->xdamageBaseEvent
<< ", xdamage base error = " << d->x11EvtFilter->xdamageBaseError;
<< ", xshm base error = " << d->x11EvtFilter->xdamageBaseError
<< ", xdamage base event = " << d->x11EvtFilter->xdamageBaseEvent
<< ", xdamage base error = " << d->x11EvtFilter->xdamageBaseError;
#endif
QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter);
}
XCBFrameBuffer::~XCBFrameBuffer() {
XCBFrameBuffer::~XCBFrameBuffer()
{
// first - uninstall x11 event filter
QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter);
//
if (d->framebufferImage) {
xcb_image_destroy(d->framebufferImage);
fb = nullptr; // image data was already destroyed by above call
fb = nullptr; // image data was already destroyed by above call
}
if (d->x11EvtFilter->xshmAvail) {
// 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
if (d->shminfo.shmaddr)
}
if (d->shminfo.shmaddr) {
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
}
}
// and delete image used for shared mem
if (d->updateTile) {
@@ -316,43 +322,46 @@ XCBFrameBuffer::~XCBFrameBuffer() {
delete d;
}
int XCBFrameBuffer::depth() {
int XCBFrameBuffer::depth()
{
if (d->framebufferImage) {
return d->framebufferImage->depth;
}
return 0;
}
int XCBFrameBuffer::height() {
int XCBFrameBuffer::height()
{
if (d->framebufferImage) {
return d->framebufferImage->height;
}
return 0;
}
int XCBFrameBuffer::width() {
int XCBFrameBuffer::width()
{
if (d->framebufferImage) {
return d->framebufferImage->width;
}
return 0;
}
int XCBFrameBuffer::paddedWidth() {
int XCBFrameBuffer::paddedWidth()
{
if (d->framebufferImage) {
return d->framebufferImage->stride;
}
return 0;
}
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
if (!d->framebufferImage) return;
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format)
{
if (!d->framebufferImage) {
return;
}
// get information about XCB visual params
xcb_visualtype_t *root_visualtype = nullptr; // visual info
xcb_visualtype_t *root_visualtype = nullptr; // visual info
if (d->rootScreen) {
xcb_visualid_t root_visual = d->rootScreen->root_visual;
xcb_depth_iterator_t depth_iter;
@@ -374,12 +383,11 @@ void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
}
}
// fill in format common info
format.bitsPerPixel = d->framebufferImage->bpp;
format.depth = d->framebufferImage->depth;
format.trueColour = true; // not using color palettes
format.bigEndian = false; // always false for ZPIXMAP format!
format.trueColour = true; // not using color palettes
format.bigEndian = false; // always false for ZPIXMAP format!
// information about pixels layout
@@ -418,57 +426,56 @@ void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
// calculate pixel max value.
// NOTE: bits_per_rgb_value is unreliable, thus should be avoided.
format.redMax = root_visualtype->red_mask >> format.redShift;
format.redMax = root_visualtype->red_mask >> format.redShift;
format.greenMax = root_visualtype->green_mask >> format.greenShift;
format.blueMax = root_visualtype->blue_mask >> format.blueShift;
format.blueMax = root_visualtype->blue_mask >> format.blueShift;
#ifdef _DEBUG
qCDebug(KRFB_FB_XCB,
" Calculated redShift = %d\n"
" Calculated greenShift = %d\n"
" Calculated blueShift = %d\n"
" Calculated max values: R%d G%d B%d",
format.redShift, format.greenShift, format.blueShift
format.redMax, format.greenMax, format.blueMax);
" Calculated redShift = %d\n"
" Calculated greenShift = %d\n"
" Calculated blueShift = %d\n"
" Calculated max values: R%d G%d B%d",
format.redShift, format.greenShift, format.blueShift format.redMax, format.greenMax, format.blueMax);
#endif
} else {
// some kind of fallback (unlikely code execution will go this way)
// idea taken from qt framefuffer sources
if (format.bitsPerPixel == 8) {
format.redShift = 0;
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
format.redMax = 7;
format.blueShift = 6;
format.redMax = 7;
format.greenMax = 7;
format.blueMax = 3;
format.blueMax = 3;
} else if (format.bitsPerPixel == 16) {
// TODO: 16 bits per pixel format ??
// what format of pixels does X server use for 16-bpp?
} else if (format.bitsPerPixel == 32) {
format.redMax = 0xff;
format.redMax = 0xff;
format.greenMax = 0xff;
format.blueMax = 0xff;
format.blueMax = 0xff;
if (format.bigEndian) {
format.redShift = 0;
format.redShift = 0;
format.greenShift = 8;
format.blueShift = 16;
format.blueShift = 16;
} else {
format.redShift = 16;
format.redShift = 16;
format.greenShift = 8;
format.blueShift = 0;
format.blueShift = 0;
}
}
}
}
/**
* This function contents was taken from X11 framebuffer source code.
* It simply several intersecting rectangles into one bigger rect.
* Non-intersecting rects are treated as different rects and exist
* separately in this->tiles QList.
*/
void XCBFrameBuffer::cleanupRects() {
void XCBFrameBuffer::cleanupRects()
{
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
@@ -477,7 +484,9 @@ void XCBFrameBuffer::cleanupRects() {
while (iter.hasNext()) {
const QRect &r = iter.next();
// 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
QRect ri = r.intersected(d->area);
@@ -525,13 +534,13 @@ void XCBFrameBuffer::cleanupRects() {
}
}
/**
* This function is called by RfbServerManager::updateScreens()
* approximately every 50ms (!!), driven by QTimer to get all
* modified rectangles on the screen
*/
QList<QRect> XCBFrameBuffer::modifiedTiles() {
QList<QRect> XCBFrameBuffer::modifiedTiles()
{
QList<QRect> ret;
if (!d->running) {
return ret;
@@ -541,10 +550,9 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
if (tiles.size() > 0) {
if (d->x11EvtFilter->xshmAvail) {
// loop over all damage rectangles gathered up to this time
QListIterator<QRect> iter(tiles);
//foreach(const QRect &r, tiles) {
// foreach(const QRect &r, tiles) {
while (iter.hasNext()) {
const QRect &r = iter.next();
@@ -553,41 +561,41 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
// but we need to get image from the whole screen, so
// translate the coordinates
xcb_shm_get_image_cookie_t sgi_cookie = xcb_shm_get_image(
QX11Info::connection(),
d->win,
d->area.left() + r.left(),
d->area.top() + r.top(),
r.width(),
r.height(),
0xFFFFFFFF,
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->shminfo.shmseg,
0);
QX11Info::connection(),
d->win,
d->area.left() + r.left(),
d->area.top() + r.top(),
r.width(),
r.height(),
0xFFFFFFFF,
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->shminfo.shmseg,
0);
xcb_shm_get_image_reply_t *sgi_reply = xcb_shm_get_image_reply(
QX11Info::connection(), sgi_cookie, nullptr);
QX11Info::connection(), sgi_cookie, nullptr);
if (sgi_reply) {
// create temporary image to get update rect contents into
d->updateTile = xcb_image_create_native(
QX11Info::connection(),
r.width(),
r.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->rootScreen->root_depth,
nullptr, // base == 0
(uint32_t)~0, // bytes == ~0
nullptr);
QX11Info::connection(),
r.width(),
r.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->rootScreen->root_depth,
nullptr, // base == 0
(uint32_t)~0, // bytes == ~0
nullptr);
if (d->updateTile) {
d->updateTile->data = d->shminfo.shmaddr;
// copy pixels from this damage rectangle image
// to our total framebuffer image
int pxsize = d->framebufferImage->bpp / 8;
int pxsize = d->framebufferImage->bpp / 8;
char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize));
char *src = (char *)d->updateTile->data;
for (int i = 0; i < d->updateTile->height; i++) {
memcpy(dest, src, d->updateTile->stride); // copy whole row of pixels
memcpy(dest, src, d->updateTile->stride); // copy whole row of pixels
dest += d->framebufferImage->stride;
src += d->updateTile->stride;
}
@@ -604,28 +612,28 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
} else {
// not using shared memory
// 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!!
// need function that copies pixels from one image to another
xcb_image_t *damagedImage = xcb_image_get(
QX11Info::connection(),
d->win,
r.left(),
r.top(),
r.width(),
r.height(),
0xFFFFFFFF, // AllPlanes
XCB_IMAGE_FORMAT_Z_PIXMAP);
QX11Info::connection(),
d->win,
r.left(),
r.top(),
r.width(),
r.height(),
0xFFFFFFFF, // AllPlanes
XCB_IMAGE_FORMAT_Z_PIXMAP);
// manually copy pixels
int pxsize = d->framebufferImage->bpp / 8;
int pxsize = d->framebufferImage->bpp / 8;
char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize));
char *src = (char *)damagedImage->data;
// loop every row in damaged image
for (int i = 0; i < damagedImage->height; i++) {
// copy whole row of pixels from src image to dest
memcpy(dest, src, damagedImage->stride);
dest += d->framebufferImage->stride; // move 1 row down in dest
src += damagedImage->stride; // move 1 row down in src
dest += d->framebufferImage->stride; // move 1 row down in dest
src += damagedImage->stride; // move 1 row down in src
}
//
xcb_image_destroy(damagedImage);
@@ -638,34 +646,37 @@ QList<QRect> XCBFrameBuffer::modifiedTiles() {
// ^^ 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
// (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;
}
void XCBFrameBuffer::startMonitor() {
if (d->running) return;
void XCBFrameBuffer::startMonitor()
{
if (d->running) {
return;
}
d->running = true;
d->damage = xcb_generate_id(QX11Info::connection());
xcb_damage_create(QX11Info::connection(), d->damage, d->win,
XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
// (currently) we do not call xcb_damage_subtract() EVER, because
// RAW rectangles are reported. every time some area of the screen
// 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() {
if (!d->running) return;
void XCBFrameBuffer::stopMonitor()
{
if (!d->running) {
return;
}
d->running = false;
xcb_damage_destroy(QX11Info::connection(), d->damage);
}
// void XCBFrameBuffer::acquireEvents() {} // this function was totally unused
// in X11 framebuffer, but it was the only function where XDamageSubtract() was called?
// 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
// 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;
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);
this->tiles.append(r);
}

View File

@@ -10,24 +10,23 @@
#include <QWidget>
#include <xcb/xcb.h>
/**
@author Alexey Min <alexey.min@gmail.com>
*/
class XCBFrameBuffer: public FrameBuffer
class XCBFrameBuffer : public FrameBuffer
{
Q_OBJECT
public:
explicit XCBFrameBuffer(QObject *parent = nullptr);
~XCBFrameBuffer() override;
public:
QList<QRect> modifiedTiles() override;
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
void getServerFormat(rfbPixelFormat &format) override;
void startMonitor() override;
void stopMonitor() override;

View File

@@ -4,7 +4,6 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "xcb_framebufferplugin.h"
#include "xcb_framebuffer.h"
#include <KPluginFactory>
@@ -23,4 +22,3 @@ FrameBuffer *XCBFrameBufferPlugin::frameBuffer(const QVariantMap &args)
}
#include "xcb_framebufferplugin.moc"

View File

@@ -1,31 +1,28 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: Alexey Min <alexey.min@gmail.com>
/* This file is part of the KDE project
SPDX-FileCopyrightText: Alexey Min <alexey.min@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
#define KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
#include "framebufferplugin.h"
#include <QWidget>
class FrameBuffer;
class XCBFrameBufferPlugin: public FrameBufferPlugin
class XCBFrameBufferPlugin : public FrameBufferPlugin
{
Q_OBJECT
Q_OBJECT
public:
XCBFrameBufferPlugin(QObject *parent, const QVariantList &args);
XCBFrameBufferPlugin(QObject *parent, const QVariantList &args);
FrameBuffer *frameBuffer(const QVariantMap &args) override;
FrameBuffer *frameBuffer(const QVariantMap &args) override;
private:
Q_DISABLE_COPY(XCBFrameBufferPlugin)
Q_DISABLE_COPY(XCBFrameBufferPlugin)
};
#endif // Header guard
#endif // Header guard

View File

@@ -11,20 +11,20 @@
#include <QCheckBox>
#include <QIcon>
#include <KConfigGroup>
#include <KGuiItem>
#include <KLocalizedString>
#include <KStandardGuiItem>
#include <KConfigGroup>
#include <QDialogButtonBox>
#include <QPushButton>
#include <KGuiItem>
#include <QVBoxLayout>
template <typename UI>
template<typename UI>
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
: QDialog(parent)
{
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 mainLayout = new QVBoxLayout;
setLayout(mainLayout);

View File

@@ -12,12 +12,14 @@
#include "ui_connectionwidget.h"
#include <QDialog>
template <typename UI>
template<typename UI>
class ConnectionDialog : public QDialog
{
public:
explicit ConnectionDialog(QWidget *parent);
~ConnectionDialog() override {};
~ConnectionDialog() override
{
}
void setAllowRemoteControl(bool b);
bool allowRemoteControl();
@@ -27,14 +29,14 @@ protected:
UI m_ui;
};
template <typename UI>
template<typename UI>
void ConnectionDialog<UI>::setAllowRemoteControl(bool b)
{
m_ui.cbAllowRemoteControl->setChecked(b);
m_ui.cbAllowRemoteControl->setVisible(b);
}
template <typename UI>
template<typename UI>
bool ConnectionDialog<UI>::allowRemoteControl()
{
return m_ui.cbAllowRemoteControl->isChecked();
@@ -45,12 +47,12 @@ bool ConnectionDialog<UI>::allowRemoteControl()
class InvitationsConnectionDialog : public ConnectionDialog<Ui::ConnectionWidget>
{
Q_OBJECT
public:
explicit InvitationsConnectionDialog(QWidget *parent);
void setRemoteHost(const QString & host);
void setRemoteHost(const QString &host);
};
//*********
#endif // CONNECTIONDIALOG_H

View File

@@ -13,14 +13,15 @@
#define EVENTS_H
#include "framebuffer.h"
#include "rfb.h"
#include "krfbprivate_export.h"
#include "rfb.h"
#include <QObject>
class KRFBPRIVATE_EXPORT EventHandler : public QObject
{
Q_OBJECT
public:
explicit EventHandler(QObject *parent = nullptr);
~EventHandler() override = default;
@@ -29,6 +30,7 @@ public:
void setFrameBufferPlugin(const QSharedPointer<FrameBuffer> &frameBuffer);
QSharedPointer<FrameBuffer> frameBuffer();
private:
// Used to track framebuffer plugin which we need for xdp event plugin
QSharedPointer<FrameBuffer> fb;

View File

@@ -9,15 +9,14 @@
#include "eventsplugin.h"
#include "krfbconfig.h"
#include "rfbservermanager.h"
#include "krfbdebug.h"
#include "rfbservermanager.h"
#include <QGlobalStatic>
#include <KPluginFactory>
#include <KPluginMetaData>
class EventsManagerStatic
{
public:

View File

@@ -40,8 +40,7 @@ private:
EventsManager();
QMap<QString, EventsPlugin *> m_plugins;
QList<QWeakPointer<EventHandler> > m_eventHandlers;
QList<QWeakPointer<EventHandler>> m_eventHandlers;
};
#endif // Header guard
#endif // Header guard

View File

@@ -1,4 +1,3 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2016 Oleg Chernovskiy <kanedias@xaker.ru>

View File

@@ -10,14 +10,15 @@
#include "krfbprivate_export.h"
#include <QtCore/QVariantList>
#include <QWidget>
#include <QtCore/QVariantList>
class EventHandler;
class KRFBPRIVATE_EXPORT EventsPlugin : public QObject
{
Q_OBJECT
public:
EventsPlugin(QObject *parent, const QVariantList &args);
~EventsPlugin() override;
@@ -25,5 +26,4 @@ public:
virtual EventHandler *eventHandler() = 0;
};
#endif // Header guard
#endif // Header guard

View File

@@ -6,11 +6,10 @@
#include "framebuffer.h"
#include <config-krfb.h>
#include <QCursor>
#include <QGuiApplication>
#include <QScreen>
#include <config-krfb.h>
FrameBuffer::FrameBuffer(QObject *parent)
: QObject(parent)
@@ -27,7 +26,7 @@ char *FrameBuffer::data()
return fb;
}
QList< QRect > FrameBuffer::modifiedTiles()
QList<QRect> FrameBuffer::modifiedTiles()
{
QList<QRect> ret = tiles;
tiles.clear();

View File

@@ -11,13 +11,12 @@
#include "krfbprivate_export.h"
#include <QList>
#include <QObject>
#include <QRect>
#include <QList>
#include <QVariant>
#include <QWidget>
class FrameBuffer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@@ -25,6 +24,7 @@ class FrameBuffer;
class KRFBPRIVATE_EXPORT FrameBuffer : public QObject
{
Q_OBJECT
public:
explicit FrameBuffer(QObject *parent = nullptr);
@@ -54,7 +54,6 @@ protected:
private:
Q_DISABLE_COPY(FrameBuffer)
};
#endif

View File

@@ -11,13 +11,12 @@
#include "krfbconfig.h"
#include "krfbdebug.h"
#include <QGuiApplication>
#include <QGlobalStatic>
#include <QGuiApplication>
#include <KPluginFactory>
#include <KPluginMetaData>
class FrameBufferManagerStatic
{
public:
@@ -28,7 +27,7 @@ Q_GLOBAL_STATIC(FrameBufferManagerStatic, frameBufferManagerStatic)
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());
};
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);
if (weakFrameBuffer) {
//qDebug() << "Found cached frame buffer.";
// qDebug() << "Found cached frame buffer.";
return weakFrameBuffer.toStrongRef();
} else {
//qDebug() << "Found deleted cached frame buffer. Don't use.";
// qDebug() << "Found deleted cached frame buffer. Don't use.";
m_frameBuffers.remove(id);
}
}

View File

@@ -40,9 +40,7 @@ private:
FrameBufferManager();
QMap<QString, FrameBufferPlugin *> m_plugins;
QMap<WId, QWeakPointer<FrameBuffer> > m_frameBuffers;
QMap<WId, QWeakPointer<FrameBuffer>> m_frameBuffers;
};
#endif // Header guard
#endif // Header guard

View File

@@ -13,7 +13,6 @@
#include <QVariantList>
#include <QWidget>
class FrameBuffer;
class KRFBPRIVATE_EXPORT FrameBufferPlugin : public QObject
@@ -27,5 +26,4 @@ public:
virtual FrameBuffer *frameBuffer(const QVariantMap &args) = 0;
};
#endif // Header guard
#endif // Header guard

View File

@@ -7,38 +7,42 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "rfb.h"
#include "invitationsrfbclient.h"
#include "connectiondialog.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "connectiondialog.h"
#include "krfbdebug.h"
#include "rfb.h"
#include "sockethelpers.h"
#include <KNotification>
#include <KLocalizedString>
#include <KNotification>
#include <KConfigGroup>
#include <QSocketNotifier>
#include <poll.h>
#include <KConfigGroup>
struct PendingInvitationsRfbClient::Private
{
Private(rfbClientPtr client) :
client(client),
askOnConnect(true)
{}
Private(rfbClientPtr client)
: client(client)
, askOnConnect(true)
{
}
rfbClientPtr client;
QSocketNotifier *notifier = nullptr;
bool askOnConnect;
};
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
static void clientGoneHookNoop(rfbClientPtr cl)
{
Q_UNUSED(cl);
}
PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent) :
PendingRfbClient(client, parent),
d(new Private(client))
PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent)
: PendingRfbClient(client, parent)
, d(new Private(client))
{
d->client->clientGoneHook = clientGoneHookNoop;
}
@@ -53,16 +57,14 @@ void PendingInvitationsRfbClient::processNewClient()
QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
if (d->askOnConnect == false) {
KNotification::event(QStringLiteral("NewConnectionAutoAccepted"),
i18n("Accepted connection from %1", host));
accept(new InvitationsRfbClient(m_rfbClient, parent()));
} else {
KNotification::event(QStringLiteral("NewConnectionOnHold"),
i18n("Received connection from %1, on hold (waiting for confirmation)",
host));
i18n("Received connection from %1, on hold (waiting for confirmation)",
host));
auto dialog = new InvitationsConnectionDialog(nullptr);
dialog->setRemoteHost(host);
@@ -75,20 +77,18 @@ void PendingInvitationsRfbClient::processNewClient()
}
}
bool PendingInvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
bool PendingInvitationsRfbClient::checkPassword(const QByteArray &encryptedPassword)
{
qCDebug(KRFB) << "about to start authentication";
if(InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword(
InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(),
encryptedPassword) ) {
if (InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword(InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(), encryptedPassword)) {
d->askOnConnect = false;
return true;
}
return vncAuthCheckPassword(
InvitationsRfbServer::instance->desktopPassword().toLocal8Bit(),
encryptedPassword);
InvitationsRfbServer::instance->desktopPassword().toLocal8Bit(),
encryptedPassword);
}
void PendingInvitationsRfbClient::dialogAccepted()

View File

@@ -12,28 +12,30 @@
class InvitationsRfbClient : public RfbClient
{
public:
explicit InvitationsRfbClient(rfbClientPtr client, QObject* parent = nullptr)
: RfbClient(client, parent) {}
explicit InvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr)
: RfbClient(client, parent)
{
}
};
class PendingInvitationsRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
explicit PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = nullptr);
~PendingInvitationsRfbClient() override;
protected Q_SLOTS:
void processNewClient() override;
bool checkPassword(const QByteArray & encryptedPassword) override;
bool checkPassword(const QByteArray &encryptedPassword) override;
private Q_SLOTS:
void dialogAccepted();
private:
struct Private;
Private* const d;
Private *const d;
};
#endif // INVITATIONSRFBCLIENT_H

View File

@@ -11,14 +11,14 @@
#include "invitationsrfbclient.h"
#include "krfbconfig.h"
#include "krfbdebug.h"
#include <QTimer>
#include <QApplication>
#include <QHostInfo>
#include <QRandomGenerator>
#include <QTimer>
#include <KLocalizedString>
#include <KUser>
#include <KStringHandler>
#include <KUser>
#include <KWallet>
#include <KDNSSD/PublicService>
@@ -28,19 +28,19 @@ using KWallet::Wallet;
// used for KWallet folder name
static const QString s_krfbFolderName(QStringLiteral("krfb"));
//static
// static
InvitationsRfbServer *InvitationsRfbServer::instance;
//static
// static
void InvitationsRfbServer::init()
{
instance = new InvitationsRfbServer;
instance->m_publicService = new KDNSSD::PublicService(
i18n("%1@%2 (shared desktop)",
KUser().loginName(),
QHostInfo::localHostName()),
QStringLiteral("_rfb._tcp"),
KrfbConfig::port());
i18n("%1@%2 (shared desktop)",
KUser().loginName(),
QHostInfo::localHostName()),
QStringLiteral("_rfb._tcp"),
KrfbConfig::port());
instance->setListeningAddress("0.0.0.0");
instance->setListeningPort(KrfbConfig::port());
instance->setPasswordRequired(true);
@@ -53,12 +53,12 @@ void InvitationsRfbServer::init()
}
}
const QString& InvitationsRfbServer::desktopPassword() const
const QString &InvitationsRfbServer::desktopPassword() const
{
return m_desktopPassword;
}
void InvitationsRfbServer::setDesktopPassword(const QString& password)
void InvitationsRfbServer::setDesktopPassword(const QString &password)
{
m_desktopPassword = password;
// this is called from GUI every time desktop password is edited.
@@ -66,12 +66,12 @@ void InvitationsRfbServer::setDesktopPassword(const QString& password)
saveSecuritySettings();
}
const QString& InvitationsRfbServer::unattendedPassword() const
const QString &InvitationsRfbServer::unattendedPassword() const
{
return m_unattendedPassword;
}
void InvitationsRfbServer::setUnattendedPassword(const QString& password)
void InvitationsRfbServer::setUnattendedPassword(const QString &password)
{
m_unattendedPassword = password;
// this is called from GUI every time unattended password is edited.
@@ -86,9 +86,10 @@ bool InvitationsRfbServer::allowUnattendedAccess() const
bool InvitationsRfbServer::start()
{
if(RfbServer::start()) {
if(KrfbConfig::publishService())
if (RfbServer::start()) {
if (KrfbConfig::publishService()) {
m_publicService->publishAsync();
}
return true;
}
return false;
@@ -96,8 +97,9 @@ bool InvitationsRfbServer::start()
void InvitationsRfbServer::stop()
{
if(m_publicService->isPublished())
if (m_publicService->isPublished()) {
m_publicService->stop();
}
RfbServer::stop();
}
@@ -113,14 +115,15 @@ InvitationsRfbServer::InvitationsRfbServer()
{
m_desktopPassword = 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(
"allowUnattendedAccess", QVariant(false)).toBool();
"allowUnattendedAccess", QVariant(false))
.toBool();
}
InvitationsRfbServer::~InvitationsRfbServer()
{
InvitationsRfbServer::stop(); // calling virtual funcs in destructor is bad
InvitationsRfbServer::stop(); // calling virtual funcs in destructor is bad
saveSecuritySettings();
// ^^ also saves passwords in kwallet,
// do it before closing kwallet
@@ -129,7 +132,7 @@ InvitationsRfbServer::~InvitationsRfbServer()
}
}
PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
PendingRfbClient *InvitationsRfbServer::newClient(rfbClientPtr client)
{
return new PendingInvitationsRfbClient(client, this);
}
@@ -157,15 +160,13 @@ void InvitationsRfbServer::walletOpened(bool opened)
QString unattendedPassword;
Q_ASSERT(m_wallet);
if (opened && m_wallet->hasFolder(s_krfbFolderName) && m_wallet->setFolder(s_krfbFolderName) ) {
if (m_wallet->readPassword(QStringLiteral("desktopSharingPassword"), desktopPassword) == 0 &&
!desktopPassword.isEmpty()) {
if (opened && m_wallet->hasFolder(s_krfbFolderName) && m_wallet->setFolder(s_krfbFolderName)) {
if (m_wallet->readPassword(QStringLiteral("desktopSharingPassword"), desktopPassword) == 0 && !desktopPassword.isEmpty()) {
m_desktopPassword = desktopPassword;
Q_EMIT passwordChanged(m_desktopPassword);
}
if(m_wallet->readPassword(QStringLiteral("unattendedAccessPassword"), unattendedPassword) == 0 &&
!unattendedPassword.isEmpty()) {
if (m_wallet->readPassword(QStringLiteral("unattendedAccessPassword"), unattendedPassword) == 0 && !unattendedPassword.isEmpty()) {
m_unattendedPassword = unattendedPassword;
}
@@ -190,13 +191,7 @@ QString InvitationsRfbServer::readableRandomString(int length)
r += 6;
}
char c = char(r);
if ((c == 'i') ||
(c == 'I') ||
(c == '1') ||
(c == 'l') ||
(c == 'o') ||
(c == 'O') ||
(c == '0')) {
if ((c == 'i') || (c == 'I') || (c == '1') || (c == 'l') || (c == 'o') || (c == 'O') || (c == '0')) {
continue;
}
str += QLatin1Char(c);
@@ -237,18 +232,18 @@ void InvitationsRfbServer::readPasswordFromConfig()
{
QString desktopPassword;
QString unattendedPassword;
KConfigGroup krfbConfig(KSharedConfig::openConfig(),QStringLiteral("Security"));
KConfigGroup krfbConfig(KSharedConfig::openConfig(), QStringLiteral("Security"));
desktopPassword = KStringHandler::obscure(krfbConfig.readEntry(
"desktopPassword", QString()));
if(!desktopPassword.isEmpty()) {
"desktopPassword", QString()));
if (!desktopPassword.isEmpty()) {
m_desktopPassword = desktopPassword;
Q_EMIT passwordChanged(m_desktopPassword);
}
unattendedPassword = KStringHandler::obscure(krfbConfig.readEntry(
"unattendedPassword", QString()));
if(!unattendedPassword.isEmpty()) {
"unattendedPassword", QString()));
if (!unattendedPassword.isEmpty()) {
m_unattendedPassword = unattendedPassword;
}
}

View File

@@ -11,29 +11,36 @@
#include "rfbserver.h"
namespace KWallet {
class Wallet;
namespace KWallet
{
class Wallet;
}
namespace KDNSSD {
class PublicService;
namespace KDNSSD
{
class PublicService;
}
class InvitationsRfbServer : public RfbServer
{
Q_OBJECT
public:
static InvitationsRfbServer *instance;
static void init();
const QString& desktopPassword() const;
void setDesktopPassword(const QString&);
const QString& unattendedPassword() const;
void setUnattendedPassword(const QString&);
const QString &desktopPassword() const;
void setDesktopPassword(const QString &);
const QString &unattendedPassword() const;
void setUnattendedPassword(const QString &);
bool allowUnattendedAccess() const;
Q_SIGNALS:
void passwordChanged(const QString&);
void passwordChanged(const QString &);
public Q_SLOTS:
bool start() override;
@@ -46,7 +53,7 @@ public Q_SLOTS:
protected:
InvitationsRfbServer();
~InvitationsRfbServer() override;
PendingRfbClient* newClient(rfbClientPtr client) override;
PendingRfbClient *newClient(rfbClientPtr client) override;
private Q_SLOTS:
void walletOpened(bool);

View File

@@ -4,28 +4,29 @@
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 "rfbserver.h"
#include <signal.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
{
public:
explicit VirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
: RfbClient(client, parent)
{}
{
}
};
class PendingVirtualMonitorRfbClient : public PendingRfbClient
@@ -33,20 +34,25 @@ class PendingVirtualMonitorRfbClient : public PendingRfbClient
public:
explicit PendingVirtualMonitorRfbClient(rfbClientPtr client, QObject *parent = nullptr)
: PendingRfbClient(client, parent)
{}
~PendingVirtualMonitorRfbClient() override {}
{
}
~PendingVirtualMonitorRfbClient() override
{
}
static QByteArray password;
protected:
void processNewClient() override {
void processNewClient() override
{
qDebug() << "new client!";
const QString host = peerAddress(m_rfbClient->sock) + QLatin1Char(':') + QString::number(peerPort(m_rfbClient->sock));
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);
if (b) {
QTimer::singleShot(0, this, [this] {
@@ -62,7 +68,8 @@ QByteArray PendingVirtualMonitorRfbClient::password;
class VirtualMonitorRfbServer : public RfbServer
{
public:
PendingRfbClient *newClient(rfbClientPtr client) override {
PendingRfbClient *newClient(rfbClientPtr client) override
{
qDebug() << "new client request";
return new PendingVirtualMonitorRfbClient(client, this);
}
@@ -80,12 +87,12 @@ int main(int argc, char *argv[])
i18n("Offer a Virtual Monitor that can be accessed remotely"),
KAboutLicense::GPL,
i18n("(c) 2009-2010, Collabora Ltd.\n"
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
aboutData.addAuthor(QStringLiteral("Aleix Pol i Gonzalez"), i18n("Virtual Monitor implementation"), QStringLiteral("aleixpol@kde.org"));
aboutData.addAuthor(i18n("George Kiagiadakis"), QString(), QStringLiteral("george.kiagiadakis@collabora.co.uk"));
aboutData.addAuthor(i18n("Alessandro Praduroux"), i18n("KDE4 porting"), QStringLiteral("pradu@pradu.it"));
@@ -98,7 +105,7 @@ int main(int argc, char *argv[])
i18n("ZLib encoder"));
aboutData.addCredit(i18n("AT&T Laboratories Boston"),
i18n("original VNC encoders and "
"protocol design"));
"protocol design"));
KAboutData::setApplicationData(aboutData);
KCrash::initialize();
@@ -107,34 +114,34 @@ int main(int argc, char *argv[])
aboutData.setupCommandLine(&parser);
const QCommandLineOption resolutionOption(
{ QStringLiteral("resolution") },
{QStringLiteral("resolution")},
i18n("Logical resolution of the new monitor"),
i18n("resolution"),
QStringLiteral("1920x1080"));
parser.addOption(resolutionOption);
const QCommandLineOption nameOption(
{ QStringLiteral("name") },
{QStringLiteral("name")},
i18n("Name of the monitor"),
i18n("name"),
QStringLiteral("Monitor"));
parser.addOption(nameOption);
const QCommandLineOption passwordOption(
{ QStringLiteral("password") },
{QStringLiteral("password")},
i18n("Password for the client to connect to it"),
i18n("password"));
parser.addOption(passwordOption);
const QCommandLineOption scaleOption(
{ QStringLiteral("scale") },
{QStringLiteral("scale")},
i18n("The device-pixel-ratio of the device, the scaling factor"),
i18n("dpr"),
QStringLiteral("1"));
parser.addOption(scaleOption);
const QCommandLineOption portOption(
{ QStringLiteral("port") },
{QStringLiteral("port")},
i18n("The port we will be listening to"),
i18n("number"),
QStringLiteral("5900"));
@@ -151,16 +158,16 @@ int main(int argc, char *argv[])
}
const QString res = parser.value(resolutionOption);
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()) {
qCritical() << "The resolution should be formatted as WIDTHxHEIGHT (e.g. --resolution 1920x1080).";
return 2;
}
RfbServerManager::s_pluginArgs = {
{ QStringLiteral("name"), parser.value(nameOption) },
{ QStringLiteral("resolution"), size },
{ QStringLiteral("scale"), parser.value(scaleOption).toDouble() },
{QStringLiteral("name"), parser.value(nameOption)},
{QStringLiteral("resolution"), size},
{QStringLiteral("scale"), parser.value(scaleOption).toDouble()},
};
VirtualMonitorRfbServer server;

View File

@@ -3,12 +3,12 @@
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 "trayicon.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "krfb_version.h"
#include "krfbdebug.h"
#include <KAboutData>
#include <KCrash>
@@ -18,14 +18,13 @@
#include <KWindowSystem>
#include <QPixmap>
#include <qwindowdefs.h>
#include <QtGui/private/qtx11extras_p.h>
#include <qwindowdefs.h>
#include <csignal>
#include <X11/extensions/XTest.h>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <X11/extensions/XTest.h>
#include <csignal>
static bool checkX11Capabilities()
{
@@ -44,11 +43,12 @@ static bool checkX11Capabilities()
return true;
}
static void checkOldX11PluginConfig() {
static void checkOldX11PluginConfig()
{
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
qCDebug(KRFB) << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
QStringLiteral("preferredFrameBufferPlugin"));
QStringLiteral("preferredFrameBufferPlugin"));
if (config_item) {
config_item->setProperty(QStringLiteral("xcb"));
KrfbConfig::self()->save();
@@ -61,10 +61,10 @@ static void checkWaylandPluginConfig()
{
if (KrfbConfig::preferredFrameBufferPlugin() != QStringLiteral("pw")) {
qWarning() << "Wayland: Detected invalid configuration: "
"preferredFrameBufferPlugin is not pipewire: "
"preferredFrameBufferPlugin is not pipewire: "
<< KrfbConfig::preferredFrameBufferPlugin();
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
QStringLiteral("preferredFrameBufferPlugin"));
QStringLiteral("preferredFrameBufferPlugin"));
if (config_item) {
config_item->setProperty(QStringLiteral("pw"));
KrfbConfig::self()->save();
@@ -85,12 +85,12 @@ int main(int argc, char *argv[])
i18n("VNC-compatible server to share desktops"),
KAboutLicense::GPL,
i18n("(c) 2009-2010, Collabora Ltd.\n"
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
aboutData.addAuthor(i18n("George Goldberg"),
i18n("Telepathy tubes support"),
QStringLiteral("george.goldberg@collabora.co.uk"));
@@ -107,7 +107,7 @@ int main(int argc, char *argv[])
i18n("ZLib encoder"));
aboutData.addCredit(i18n("AT&T Laboratories Boston"),
i18n("original VNC encoders and "
"protocol design"));
"protocol design"));
KAboutData::setApplicationData(aboutData);
QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("krfb")));
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
QCommandLineParser 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.process(app);
@@ -144,10 +144,10 @@ int main(int argc, char *argv[])
return 1;
}
//init the core
// init the core
InvitationsRfbServer::init();
//init the GUI
// init the GUI
MainWindow mainWindow;
TrayIcon trayicon(&mainWindow);
@@ -161,7 +161,7 @@ int main(int argc, char *argv[])
});
if (KrfbConfig::startMinimized()) {
mainWindow.hide();
mainWindow.hide();
} else if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
mainWindow.restore(1, false);
} else if (!parser.isSet(nodialogOption)) {

View File

@@ -8,42 +8,46 @@
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "ui_configtcp.h"
#include "ui_configsecurity.h"
#include "ui_configframebuffer.h"
#include "ui_configsecurity.h"
#include "ui_configtcp.h"
#include <KActionCollection>
#include <KConfigDialog>
#include <KLocalizedString>
#include <KMessageBox>
#include <KMessageWidget>
#include <KStandardAction>
#include <KActionCollection>
#include <KNewPasswordDialog>
#include <KPluginMetaData>
#include <KStandardAction>
#include <QIcon>
#include <QWidget>
#include <QLineEdit>
#include <QComboBox>
#include <QSizePolicy>
#include <QList>
#include <QSet>
#include <QNetworkInterface>
#include <QHostInfo>
#include <QIcon>
#include <QLineEdit>
#include <QList>
#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:
explicit TCP(QWidget *parent = nullptr) : QWidget(parent) {
explicit TCP(QWidget *parent = nullptr)
: QWidget(parent)
{
setupUi(this);
}
};
class Security: public QWidget, public Ui::Security
class Security : public QWidget, public Ui::Security
{
public:
explicit Security(QWidget *parent = nullptr) : QWidget(parent) {
explicit Security(QWidget *parent = nullptr)
: QWidget(parent)
{
setupUi(this);
walletWarning = new KMessageWidget(this);
walletWarning->setText(i18n("Storing passwords in config file is insecure!"));
@@ -53,7 +57,7 @@ public:
vboxLayout->addWidget(walletWarning);
// 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);
});
}
@@ -61,10 +65,12 @@ public:
KMessageWidget *walletWarning = nullptr;
};
class ConfigFramebuffer: public QWidget, public Ui::Framebuffer
class ConfigFramebuffer : public QWidget, public Ui::Framebuffer
{
public:
ConfigFramebuffer(QWidget *parent = nullptr) : QWidget(parent) {
ConfigFramebuffer(QWidget *parent = nullptr)
: QWidget(parent)
{
setupUi(this);
// hide the line edit with framebuffer string
kcfg_preferredFrameBufferPlugin->hide();
@@ -78,7 +84,8 @@ public:
kcfg_preferredFrameBufferPlugin, &QLineEdit::setText);
}
void fillFrameBuffersCombo() {
void fillFrameBuffersCombo()
{
const QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(QStringLiteral("krfb/framebuffer"), {}, KPluginMetaData::AllowEmptyMetaData);
for (const KPluginMetaData &metadata : plugins) {
cb_preferredFrameBufferPlugin->addItem(metadata.pluginId());
@@ -86,7 +93,6 @@ public:
}
};
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent)
{
@@ -101,7 +107,7 @@ MainWindow::MainWindow(QWidget *parent)
m_ui.setupUi(mainWidget);
m_ui.krfbIconLabel->setPixmap(QIcon::fromTheme(QStringLiteral("krfb")).pixmap(128));
m_ui.enableUnattendedCheckBox->setChecked(
InvitationsRfbServer::instance->allowUnattendedAccess());
InvitationsRfbServer::instance->allowUnattendedAccess());
setCentralWidget(mainWidget);
@@ -123,12 +129,12 @@ MainWindow::MainWindow(QWidget *parent)
// Figure out the address
int port = KrfbConfig::port();
const QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
for (const QNetworkInterface& interface : interfaceList) {
if(interface.flags() & QNetworkInterface::IsLoopBack)
for (const QNetworkInterface &interface : interfaceList) {
if (interface.flags() & QNetworkInterface::IsLoopBack) {
continue;
}
if(interface.flags() & QNetworkInterface::IsRunning &&
!interface.addressEntries().isEmpty()) {
if (interface.flags() & QNetworkInterface::IsRunning && !interface.addressEntries().isEmpty()) {
const QString hostName = QHostInfo::localHostName();
const QString ipAddress = interface.addressEntries().constFirst().ip().toString();
const QString addressLabelText = hostName.isEmpty()
@@ -138,9 +144,9 @@ MainWindow::MainWindow(QWidget *parent)
}
}
//Figure out the password
// Figure out the password
m_ui.passwordDisplayLabel->setText(
InvitationsRfbServer::instance->desktopPassword());
InvitationsRfbServer::instance->desktopPassword());
KStandardAction::quit(QCoreApplication::instance(), &QCoreApplication::quit, actionCollection());
KStandardAction::preferences(this, &MainWindow::showConfiguration, actionCollection());
@@ -148,7 +154,7 @@ MainWindow::MainWindow(QWidget *parent)
setupGUI();
if (KrfbConfig::allowDesktopControl()) {
m_ui.enableSharingCheckBox->setChecked(true);
m_ui.enableSharingCheckBox->setChecked(true);
}
setAutoSaveSettings();
@@ -160,21 +166,21 @@ MainWindow::~MainWindow()
void MainWindow::editPassword()
{
if(m_passwordEditable) {
if (m_passwordEditable) {
m_passwordEditable = false;
m_ui.passwordEditButton->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
m_ui.passwordGridLayout->removeWidget(m_passwordLineEdit);
InvitationsRfbServer::instance->setDesktopPassword(
m_passwordLineEdit->text());
m_passwordLineEdit->text());
m_ui.passwordDisplayLabel->setText(
InvitationsRfbServer::instance->desktopPassword());
InvitationsRfbServer::instance->desktopPassword());
m_passwordLineEdit->setVisible(false);
} else {
m_passwordEditable = true;
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(
InvitationsRfbServer::instance->desktopPassword());
InvitationsRfbServer::instance->desktopPassword());
m_passwordLineEdit->setVisible(true);
m_passwordLineEdit->setFocus(Qt::MouseFocusReason);
}
@@ -184,23 +190,23 @@ void MainWindow::editUnattendedPassword()
{
KNewPasswordDialog dialog(this);
dialog.setPrompt(i18n("Enter a new password for Unattended Access"));
if(dialog.exec()) {
if (dialog.exec()) {
InvitationsRfbServer::instance->setUnattendedPassword(dialog.password());
}
}
void MainWindow::toggleDesktopSharing(bool enable)
{
if(enable) {
if(!InvitationsRfbServer::instance->start()) {
if (enable) {
if (!InvitationsRfbServer::instance->start()) {
KMessageBox::error(this,
i18n("Failed to start the krfb server. Desktop sharing "
"will not work. Try setting another port in the settings "
"and restart krfb."));
i18n("Failed to start the krfb server. Desktop sharing "
"will not work. Try setting another port in the settings "
"and restart krfb."));
}
} else {
InvitationsRfbServer::instance->stop();
if(m_passwordEditable) {
if (m_passwordEditable) {
m_passwordEditable = false;
m_passwordLineEdit->setVisible(false);
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_ui.passwordDisplayLabel->setText(password);
@@ -217,15 +223,15 @@ void MainWindow::passwordChanged(const QString& password)
void MainWindow::aboutConnectionAddress()
{
QMessageBox::about(this,
i18n("KDE Desktop Sharing"),
i18n("This field contains the address of your computer and the port number, separated by a colon.\n\nThe address is just a hint - you can use any address that can reach your computer.\n\nDesktop Sharing tries to guess your address from your network configuration, but does not always succeed in doing so.\n\nIf your computer is behind a firewall it may have a different address or be unreachable for other computers."));
i18n("KDE Desktop Sharing"),
i18n("This field contains the address of your computer and the port number, separated by a colon.\n\nThe address is just a hint - you can use any address that can reach your computer.\n\nDesktop Sharing tries to guess your address from your network configuration, but does not always succeed in doing so.\n\nIf your computer is behind a firewall it may have a different address or be unreachable for other computers."));
}
void MainWindow::aboutUnattendedMode()
{
QMessageBox::about(this,
i18n("KDE Desktop Sharing"),
i18n("Any remote user with normal desktop sharing password will have to be authenticated.\n\nIf unattended access is on, and the remote user provides unattended mode password, desktop sharing access will be granted without explicit confirmation."));
i18n("KDE Desktop Sharing"),
i18n("Any remote user with normal desktop sharing password will have to be authenticated.\n\nIf unattended access is on, and the remote user provides unattended mode password, desktop sharing access will be granted without explicit confirmation."));
}
void MainWindow::showConfiguration()
@@ -247,7 +253,7 @@ void MainWindow::showConfiguration()
dialog->addPage(new Security, i18n("Security"), QStringLiteral("security-high"));
dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), QStringLiteral("video-display"));
dialog->show();
connect(dialog, &KConfigDialog::settingsChanged, this, [this] () {
connect(dialog, &KConfigDialog::settingsChanged, this, [this]() {
// check if framebuffer plugin config has changed
if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) {
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)) {
show();
@@ -277,7 +283,7 @@ void MainWindow::readProperties(const KConfigGroup& group)
KMainWindow::readProperties(group);
}
void MainWindow::saveProperties(KConfigGroup& group)
void MainWindow::saveProperties(KConfigGroup &group)
{
group.writeEntry("Visible", isVisible());
KMainWindow::saveProperties(group);

View File

@@ -18,29 +18,29 @@ class MainWindow : public KXmlGuiWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
public Q_SLOTS:
void showConfiguration();
public Q_SLOTS:
void showConfiguration();
protected:
void readProperties(const KConfigGroup & group) override;
void saveProperties(KConfigGroup & group) override;
protected:
void readProperties(const KConfigGroup &group) override;
void saveProperties(KConfigGroup &group) override;
private Q_SLOTS:
void editPassword();
void editUnattendedPassword();
void toggleDesktopSharing(bool enable);
void passwordChanged(const QString&);
void aboutConnectionAddress();
void aboutUnattendedMode();
private Q_SLOTS:
void editPassword();
void editUnattendedPassword();
void toggleDesktopSharing(bool enable);
void passwordChanged(const QString &);
void aboutConnectionAddress();
void aboutUnattendedMode();
private:
Ui::MainWidget m_ui;
bool m_passwordEditable;
QLineEdit *m_passwordLineEdit = nullptr;
private:
Ui::MainWidget m_ui;
bool m_passwordEditable;
QLineEdit *m_passwordLineEdit = nullptr;
};
#endif

View File

@@ -16,4 +16,3 @@
#undef FALSE
#endif // Header guard

View File

@@ -8,20 +8,21 @@
*/
#include "rfbclient.h"
#include "connectiondialog.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "eventsmanager.h"
#include "krfbconfig.h"
#include "krfbdebug.h"
#include "sockethelpers.h"
#include <QSocketNotifier>
#include <poll.h>
#include <strings.h> //for bzero()
#include "krfbdebug.h"
struct RfbClient::Private
{
Private(rfbClientPtr client) :
controlEnabled(KrfbConfig::allowDesktopControl()),
client(client)
{}
Private(rfbClientPtr client)
: controlEnabled(KrfbConfig::allowDesktopControl())
, client(client)
{
}
bool controlEnabled;
rfbClientPtr client;
@@ -30,11 +31,11 @@ struct RfbClient::Private
QString remoteAddressString;
};
RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
: QObject(parent), d(new Private(client))
RfbClient::RfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent)
, d(new Private(client))
{
d->remoteAddressString = peerAddress(d->client->sock) + QLatin1Char(':') +
QString::number(peerPort(d->client->sock));
d->remoteAddressString = peerAddress(d->client->sock) + QLatin1Char(':') + QString::number(peerPort(d->client->sock));
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
d->notifier->setEnabled(false);
@@ -45,7 +46,7 @@ RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
RfbClient::~RfbClient()
{
//qDebug();
// qDebug();
delete d;
}
@@ -54,7 +55,7 @@ QString RfbClient::name() const
return d->remoteAddressString;
}
//static
// static
bool RfbClient::controlCanBeEnabled()
{
return KrfbConfig::allowDesktopControl();
@@ -115,23 +116,23 @@ void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
void RfbClient::onSocketActivated()
{
//Process not only one, but all pending messages.
//poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = { d->client->sock, POLLIN|POLLPRI, 0 };
// Process not only one, but all pending messages.
// poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = {d->client->sock, POLLIN | POLLPRI, 0};
while(poll(&pollfd, 1, 0) == 1) {
while (poll(&pollfd, 1, 0) == 1) {
rfbProcessClientMessage(d->client);
//This is how we handle disconnection.
//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
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
// This is how we handle disconnection.
// 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
// and call rfbClientConnectionGone() if necessary. This will call
// the clientGoneHook which in turn will remove this RfbClient instance
// from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
//qDebug() << "disconnected from socket signal";
// qDebug() << "disconnected from socket signal";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
break;
@@ -143,14 +144,14 @@ void RfbClient::update()
{
rfbUpdateClient(d->client);
//This is how we handle disconnection.
//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
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
// This is how we handle disconnection.
// 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
// and call rfbClientConnectionGone() if necessary. This will call
// the clientGoneHook which in turn will remove this RfbClient instance
// from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
//qDebug() << "disconnected during update";
// qDebug() << "disconnected during update";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
}
@@ -159,7 +160,8 @@ void RfbClient::update()
//*************
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_rfbClient->clientData = this;
@@ -170,11 +172,12 @@ PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
}
PendingRfbClient::~PendingRfbClient()
{}
{
}
void PendingRfbClient::accept(RfbClient *newClient)
{
//qDebug() << "accepted connection";
// qDebug() << "accepted connection";
m_rfbClient->clientData = newClient;
newClient->setOnHold(false);
@@ -183,13 +186,16 @@ void PendingRfbClient::accept(RfbClient *newClient)
deleteLater();
}
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
static void clientGoneHookNoop(rfbClientPtr cl)
{
Q_UNUSED(cl);
}
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;
rfbCloseClient(m_rfbClient);
rfbClientConnectionGone(m_rfbClient);
@@ -198,20 +204,20 @@ void PendingRfbClient::reject()
deleteLater();
}
bool PendingRfbClient::checkPassword(const QByteArray & encryptedPassword)
bool PendingRfbClient::checkPassword(const QByteArray &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()) {
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];
memcpy(challenge, m_rfbClient->authChallenge, CHALLENGESIZE);
@@ -228,27 +234,27 @@ bool PendingRfbClient::vncAuthCheckPassword(const QByteArray& password, const QB
void PendingRfbClient::onSocketActivated()
{
//Process not only one, but all pending messages.
//poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = { m_rfbClient->sock, POLLIN|POLLPRI, 0 };
// Process not only one, but all pending messages.
// poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = {m_rfbClient->sock, POLLIN | POLLPRI, 0};
while(poll(&pollfd, 1, 0) == 1) {
if(m_rfbClient->state == rfbClientRec::RFB_INITIALISATION) {
while (poll(&pollfd, 1, 0) == 1) {
if (m_rfbClient->state == rfbClientRec::RFB_INITIALISATION) {
m_notifier->setEnabled(false);
//Client is Authenticated
// Client is Authenticated
processNewClient();
break;
}
rfbProcessClientMessage(m_rfbClient);
//This is how we handle disconnection.
//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
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
// This is how we handle disconnection.
// 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
// and call rfbClientConnectionGone() if necessary. This will call
// the clientGoneHook which in turn will remove this RfbClient instance
// from the server manager and will call deleteLater() to delete it
if (m_rfbClient->sock == -1) {
qCDebug(KRFB) << "disconnected from socket signal";
m_notifier->setEnabled(false);

View File

@@ -19,6 +19,7 @@ class RfbClient : public QObject
Q_OBJECT
Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled NOTIFY controlEnabledChanged)
Q_PROPERTY(bool onHold READ isOnHold WRITE setOnHold NOTIFY holdStatusChanged)
public:
explicit RfbClient(rfbClientPtr client, QObject *parent = nullptr);
~RfbClient() override;
@@ -40,7 +41,7 @@ Q_SIGNALS:
void holdStatusChanged(bool onHold);
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();
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
@@ -50,8 +51,8 @@ private Q_SLOTS:
void onSocketActivated();
private:
///called by RfbServerManager to send framebuffer updates
///and check for possible disconnection
/// called by RfbServerManager to send framebuffer updates
/// and check for possible disconnection
void update();
friend class RfbServerManager;
@@ -59,10 +60,10 @@ private:
Private *const d;
};
class PendingRfbClient : public QObject
{
Q_OBJECT
public:
explicit PendingRfbClient(rfbClientPtr client, QObject *parent = nullptr);
~PendingRfbClient() override;
@@ -77,22 +78,21 @@ protected Q_SLOTS:
void reject();
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
* matches the criteria for authenticating the client.
* The default implementation returns false if a password is required.
* 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
* 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
* 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;

View File

@@ -7,12 +7,12 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "rfbserver.h"
#include "rfbservermanager.h"
#include "krfbdebug.h"
#include <QSocketNotifier>
#include "rfbservermanager.h"
#include <QApplication>
#include <QClipboard>
#include <QPointer>
#include <QSocketNotifier>
#include <QtGui/private/qtx11extras_p.h>
struct RfbServer::Private
@@ -27,7 +27,8 @@ struct RfbServer::Private
};
RfbServer::RfbServer(QObject *parent)
: QObject(parent), d(new Private)
: QObject(parent)
, d(new Private)
{
d->listeningAddress = "0.0.0.0";
d->listeningPort = 0;
@@ -68,7 +69,7 @@ bool RfbServer::passwordSet() const
return d->passwordSet;
}
void RfbServer::setListeningAddress(const QByteArray& address)
void RfbServer::setListeningAddress(const QByteArray &address)
{
d->listeningAddress = address;
}
@@ -106,7 +107,7 @@ bool RfbServer::start()
d->screen->setXCutText = clipboardHook;
d->screen->setXCutTextUTF8 = clipboardHookUtf8;
} else {
//if we already have a screen, stop listening first
// if we already have a screen, stop listening first
rfbShutdownServer(d->screen, false);
}
@@ -130,8 +131,8 @@ bool RfbServer::start()
}
qCDebug(KRFB) << "Starting server. Listen port:" << listeningPort()
<< "Listen Address:" << listeningAddress()
<< "Password enabled:" << passwordRequired();
<< "Listen Address:" << listeningAddress()
<< "Password enabled:" << passwordRequired();
rfbInitServer(d->screen);
@@ -182,11 +183,11 @@ void RfbServer::updateFrameBuffer(char *fb, int width, int height, int depth)
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) {
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());
}
}
@@ -203,8 +204,9 @@ void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
if (x == screen->cursorX || y == screen->cursorY)
if (x == screen->cursorX || y == screen->cursorY) {
return;
}
LOCK(screen->cursorMutex);
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) {
krfb_rfbSetCursorPosition(d->screen, nullptr, position.x(), position.y());
@@ -249,18 +251,18 @@ void RfbServer::onListenSocketActivated()
void RfbServer::pendingClientFinished(RfbClient *client)
{
//qDebug();
// qDebug();
if (client) {
RfbServerManager::instance()->addClient(client);
client->getRfbClientPtr()->clientGoneHook = clientGoneHook;
}
}
//static
// static
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
{
//qDebug() << "New client";
auto server = static_cast<RfbServer*>(cl->screen->screenData);
// qDebug() << "New client";
auto server = static_cast<RfbServer *>(cl->screen->screenData);
PendingRfbClient *pendingClient = server->newClient(cl);
connect(pendingClient, &PendingRfbClient::finished,
@@ -269,39 +271,39 @@ rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
return RFB_CLIENT_ON_HOLD;
}
//static
// static
void RfbServer::clientGoneHook(rfbClientPtr cl)
{
//qDebug() << "client gone";
auto client = static_cast<RfbClient*>(cl->clientData);
// qDebug() << "client gone";
auto client = static_cast<RfbClient *>(cl->clientData);
RfbServerManager::instance()->removeClient(client);
client->deleteLater();
}
//static
// static
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);
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
}
//static
// static
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);
}
//static
// static
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);
}
//static
// static
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr /*cl*/)
{
QString text = QString::fromLatin1(str, len);

View File

@@ -16,6 +16,7 @@
class RfbServer : public QObject
{
Q_OBJECT
public:
explicit RfbServer(QObject *parent = nullptr);
~RfbServer() override;
@@ -25,7 +26,7 @@ public:
bool passwordRequired() const;
bool passwordSet() const;
void setListeningAddress(const QByteArray & address);
void setListeningAddress(const QByteArray &address);
void setListeningPort(int port);
void setPasswordRequired(bool passwordRequired);
void setPasswordSet(bool passwordSet);
@@ -35,8 +36,8 @@ public Q_SLOTS:
virtual void stop();
void updateFrameBuffer(char *fb, int width, int height, int depth);
void updateScreen(const QList<QRect> & modifiedTiles);
void updateCursorPosition(const QPoint & position);
void updateScreen(const QList<QRect> &modifiedTiles);
void updateCursorPosition(const QPoint &position);
private Q_SLOTS:
void krfbSendServerCutText();

View File

@@ -8,20 +8,20 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "rfbservermanager.h"
#include "rfbserver.h"
#include "framebuffermanager.h"
#include "sockethelpers.h"
#include "krfbconfig.h"
#include "krfbdebug.h"
#include <QTimer>
#include "rfbserver.h"
#include "sockethelpers.h"
#include <QApplication>
#include <QGlobalStatic>
#include <QHostInfo>
#include <QTimer>
#include <qpa/qplatformnativeinterface.h>
#include <KLocalizedString>
#include <KUser>
#include <KNotification>
#include <KUser>
#include <KWindowSystem>
#include <chrono>
@@ -69,7 +69,6 @@ static const char *mask =
" xxxxx "
" xxx ";
struct RfbServerManagerStatic
{
RfbServerManager server;
@@ -77,7 +76,7 @@ struct RfbServerManagerStatic
Q_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
RfbServerManager* RfbServerManager::instance()
RfbServerManager *RfbServerManager::instance()
{
return &s_instance->server;
}
@@ -88,13 +87,13 @@ struct RfbServerManager::Private
rfbCursorPtr myCursor;
QByteArray desktopName;
QTimer rfbUpdateTimer;
QSet<RfbServer*> servers;
QSet<RfbClient*> clients;
QSet<RfbServer *> servers;
QSet<RfbClient *> clients;
};
RfbServerManager::RfbServerManager()
: QObject(), d(new Private)
: QObject()
, d(new Private)
{
init();
}
@@ -113,19 +112,20 @@ QVariantMap RfbServerManager::s_pluginArgs;
void RfbServerManager::init()
{
//qDebug();
// qDebug();
WId rootWindow = 0;
if (KWindowSystem::isPlatformX11()) {
QPlatformNativeInterface* native = qApp->platformNativeInterface();
QPlatformNativeInterface *native = qApp->platformNativeInterface();
rootWindow = reinterpret_cast<WId>(native->nativeResourceForScreen(QByteArrayLiteral("rootwindow"), QGuiApplication::primaryScreen()));
}
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->desktopName = QStringLiteral("%1@%2 (shared desktop)") //FIXME check if we can use utf8
.arg(KUser().loginName(),QHostInfo::localHostName()).toLatin1();
d->desktopName = QStringLiteral("%1@%2 (shared desktop)") // FIXME check if we can use utf8
.arg(KUser().loginName(), QHostInfo::localHostName())
.toLatin1();
connect(d->fb.data(), &FrameBuffer::frameBufferChanged, this, &RfbServerManager::updateFrameBuffer);
connect(&d->rfbUpdateTimer, &QTimer::timeout, this, &RfbServerManager::updateScreens);
@@ -144,26 +144,26 @@ void RfbServerManager::updateScreens()
QList<QRect> rects = d->fb->modifiedTiles();
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->updateCursorPosition(currentCursorPos);
}
//update() might disconnect some of the clients, which will synchronously
//call the removeClient() method and will change d->clients, so we need
//to copy the set here to avoid problems.
const QSet<RfbClient*> clients = d->clients;
for (RfbClient* client : clients) {
// update() might disconnect some of the clients, which will synchronously
// call the removeClient() method and will change d->clients, so we need
// to copy the set here to avoid problems.
const QSet<RfbClient *> clients = d->clients;
for (RfbClient *client : clients) {
client->update();
}
}
void RfbServerManager::cleanup()
{
//qDebug();
// qDebug();
//copy because d->servers is going to be modified while we delete the servers
const QSet<RfbServer*> servers = d->servers;
// copy because d->servers is going to be modified while we delete the servers
const QSet<RfbServer *> servers = d->servers;
qDeleteAll(servers);
Q_ASSERT(d->servers.isEmpty());
@@ -174,12 +174,12 @@ void RfbServerManager::cleanup()
d->fb.clear();
}
void RfbServerManager::registerServer(RfbServer* server)
void RfbServerManager::registerServer(RfbServer *server)
{
d->servers.insert(server);
}
void RfbServerManager::unregisterServer(RfbServer* server)
void RfbServerManager::unregisterServer(RfbServer *server)
{
d->servers.remove(server);
}
@@ -198,7 +198,7 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
bpp = 4;
}
//qDebug() << "bpp: " << bpp;
// qDebug() << "bpp: " << bpp;
rfbLogEnable(KRFB().isDebugEnabled());
@@ -213,10 +213,10 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
return screen;
}
void RfbServerManager::addClient(RfbClient* cc)
void RfbServerManager::addClient(RfbClient *cc)
{
if (d->clients.size() == 0) {
//qDebug() << "Starting framebuffer monitor";
// qDebug() << "Starting framebuffer monitor";
d->fb->startMonitor();
d->rfbUpdateTimer.start(50ms);
}
@@ -228,11 +228,11 @@ void RfbServerManager::addClient(RfbClient* cc)
Q_EMIT clientConnected(cc);
}
void RfbServerManager::removeClient(RfbClient* cc)
void RfbServerManager::removeClient(RfbClient *cc)
{
d->clients.remove(cc);
if (d->clients.size() == 0) {
//qDebug() << "Stopping framebuffer monitor";
// qDebug() << "Stopping framebuffer monitor";
d->fb->stopMonitor();
d->rfbUpdateTimer.stop();
}

View File

@@ -9,8 +9,8 @@
#ifndef RFBSERVERMANAGER_H
#define RFBSERVERMANAGER_H
#include "rfb.h"
#include "framebuffer.h"
#include "rfb.h"
#include <QObject>
#include <QVariantMap>
@@ -21,6 +21,7 @@ class RfbServer;
class RfbServerManager : public QObject
{
Q_OBJECT
public:
static RfbServerManager *instance();

View File

@@ -9,9 +9,9 @@
#include "sockethelpers.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
QString peerAddress(int sock)
{
@@ -86,4 +86,3 @@ unsigned short localPort(int sock)
return 0;
}

View File

@@ -8,8 +8,8 @@
#include "trayicon.h"
#include "mainwindow.h"
#include "rfbservermanager.h"
#include "rfbclient.h"
#include "rfbservermanager.h"
#include <QIcon>
#include <QMenu>
@@ -17,11 +17,11 @@
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KActionCollection>
#include <QDialog>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KStandardAction>
#include <KToggleAction>
#include <KConfigGroup>
#include <QDialog>
class ClientActions
{
@@ -37,7 +37,7 @@ private:
QAction *m_separator = nullptr;
};
ClientActions::ClientActions(RfbClient* client, QMenu* menu, QAction* before)
ClientActions::ClientActions(RfbClient *client, QMenu *menu, QAction *before)
: m_menu(menu)
{
m_title = m_menu->insertSection(before, client->name());
@@ -99,20 +99,20 @@ TrayIcon::TrayIcon(QWidget *mainWindow)
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"));
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
setStatus(KStatusNotifierItem::Active);
} else { //Nth client connected, N != 1
} else { // Nth client connected, N != 1
setToolTipTitle(i18n("Desktop Sharing - connected"));
}
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);
delete actions;
@@ -121,7 +121,7 @@ void TrayIcon::onClientDisconnected(RfbClient* client)
setIconByPixmap(QIcon::fromTheme(QStringLiteral("krfb-symbolic")).pixmap(22, 22, QIcon::Disabled));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
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();
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
}

View File

@@ -14,13 +14,14 @@ class RfbClient;
class ClientActions;
/**
* Implements the trayicon.
* @author Tim Jansen
*/
* Implements the trayicon.
* @author Tim Jansen
*/
class TrayIcon : public KStatusNotifierItem
{
Q_OBJECT
public:
explicit TrayIcon(QWidget *mainWindow);
@@ -31,7 +32,7 @@ public Q_SLOTS:
private:
QAction *m_aboutAction;
QHash<RfbClient*, ClientActions*> m_clientActions;
QHash<RfbClient *, ClientActions *> m_clientActions;
};
#endif