Compare commits

...

54 Commits

Author SHA1 Message Date
l10n daemon script
c1081d0d49 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-10-07 08:00:43 +02:00
Christoph Feck
e6e9399748 GIT_SILENT Upgrade KDE Applications version to 18.08.2. 2018-10-03 19:06:13 +02:00
Christoph Feck
ebc8b8d0d7 GIT_SILENT Upgrade KDE Applications version to 18.08.1. 2018-08-31 18:45:46 +02:00
Christoph Feck
76df98864e GIT_SILENT Upgrade KDE Applications version to 18.08.0. 2018-08-06 22:46:44 +02:00
Christoph Feck
609f1402b2 GIT_SILENT Upgrade KDE Applications version to 18.07.90. 2018-07-30 23:49:47 +02:00
l10n daemon script
dde6e92d7c GIT_SILENT made messages (after extraction) 2018-07-29 06:14:33 +02:00
Albert Astals Cid
bdd9fef19f GIT_SILENT Upgrade KDE Applications version to 18.07.80. 2018-07-16 19:34:28 +02:00
l10n daemon script
39a99107ce SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-06-03 05:24:30 +02:00
Oleg Chernovskiy
fc3e3951a4 Fix IPv6 connectivity
Summary:
IPv6 is supported by LibVNCServer but for compatibility reasons its
socket is backed by another file descriptor.

This commit adds tracking IPv6 listen socket in the same way we now
track IPv4 one.

Test Plan: Tested by connecting through ::1 and fe80:: addresses

Reviewers: #plasma, #kde_applications, alexeymin

Reviewed By: alexeymin

Subscribers: ltoscano, alexeymin, apol, aacid

Differential Revision: https://phabricator.kde.org/D13209
2018-05-30 20:59:21 +03:00
l10n daemon script
6fc934b0ef SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-04-29 05:24:29 +02:00
l10n daemon script
788d64927d GIT_SILENT made messages (after extraction) 2018-04-19 03:34:43 +02:00
Albert Astals Cid
d0b0740066 GIT_SILENT Upgrade KDE Applications version to 18.07.70. 2018-03-19 23:57:11 +01:00
l10n daemon script
438fc15a64 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-03-11 05:23:56 +01:00
l10n daemon script
8167a114da SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-03-03 05:29:30 +01:00
l10n daemon script
736c598c43 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2018-01-29 05:04:43 +01:00
Laurent Montel
822b8c41b9 Remove obsolete reviewboardrc file 2018-01-05 13:55:37 +01:00
l10n daemon script
2fee3471f5 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-12-20 07:05:07 +01:00
l10n daemon script
4ff990b6ea GIT_SILENT made messages (after extraction) 2017-12-20 05:22:26 +01:00
l10n daemon script
9c65f423b5 GIT_SILENT made messages (after extraction) 2017-12-13 05:12:50 +01:00
l10n daemon script
bd26204f96 GIT_SILENT made messages (after extraction) 2017-12-09 03:01:49 +01:00
l10n daemon script
0b9f16cfc7 GIT_SILENT made messages (after extraction) 2017-11-23 02:59:37 +01:00
l10n daemon script
8397b41027 GIT_SILENT made messages (after extraction) 2017-11-20 03:02:38 +01:00
Albert Astals Cid
709c207af8 GIT_SILENT Upgrade KDE Applications version to 18.03.70. 2017-11-13 09:11:59 +01:00
Aleix Pol
2f34058010 Include a png of the icon for compatibility 2017-11-03 00:49:35 +01:00
Aleix Pol
9b2cbaec6f Include the icon in krfb together with the application 2017-11-03 00:39:40 +01:00
l10n daemon script
25a0e089ef GIT_SILENT made messages (after extraction) 2017-10-27 03:11:47 +02:00
l10n daemon script
004c84a849 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-10-12 04:56:47 +02:00
l10n daemon script
4473e12434 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-10-11 08:47:07 +02:00
Alexey Min
bcec53db13 Merge branch 'arcpatch-D7658' 2017-09-10 13:55:31 +05:00
Alexey Min
dab8b421eb Change version to match KDE Applications (17.11.70)
Summary:
Previously krfb had version set to 5.0. This is misleading.
Now, do the same as other standard KDE apps, like ark or dolphin: use
KDE_APPLICATIONS_VERSION_MAJOR, KDE_APPLICATIONS_VERSION_MINOR, etc.
This page: https://www.kde.org/applications/system/krfb has a link to report a bug: https://bugs.kde.org/enter_bug.cgi?format=guided&product=krfb
Versions in bugzilla have 17.xx.xx, so "About..." window should match.

cmake: Set version in project(); use ecm_setup_version() call

Inspired by commit in Ark: cffecfbfffd22bc0bbe451ed8d74f3b6da113c6f

Test Plan: Compile, run. Make sure that Help -> About Desktop Sharing displays the correct version.

Reviewers: aacid, ltoscano

Tags: #kde_applications

Differential Revision: https://phabricator.kde.org/D7658
2017-09-10 13:51:39 +05:00
l10n daemon script
69d278caa8 GIT_SILENT made messages (after extraction) 2017-09-05 03:04:44 +02:00
l10n daemon script
0ac20f797c SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-09-04 04:42:31 +02:00
l10n daemon script
a66fc2d2b8 GIT_SILENT made messages (after extraction) 2017-09-04 03:05:52 +02:00
l10n daemon script
011ac5633f SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-08-14 04:58:49 +02:00
l10n daemon script
90c332ddcf GIT_SILENT made messages (after extraction) 2017-08-10 03:28:32 +02:00
Alexey Min
52fb6655a1 Merge branch 'Applications/17.08' 2017-08-08 06:50:48 +05:00
Alexey Min
44ae70244d Add .arcconfig 2017-08-08 06:49:42 +05:00
Alexey Min
69aa649d9c Add settings page allowing user to change framebuffer plugin
Added a new page to config dialog: "Screen capture", allowing to choose a framebuffer plugin.
Added a brief description about xcb and qt plugins.
Changed an icon for first tab "Network" to more appropriate one.
Code is prepared to expect "x11" as preferredFramebufferPlugin and automatically change this setting to "xcb".
Do not hardcode possible list of framebuffer plugins in combobox, but instead find actual available plugins at runtime.
If preferred plugin has changed in settings, inform user that krfb needs to be restarted to apply changes.

Differential Revision: https://phabricator.kde.org/D6319
2017-08-08 05:34:56 +05:00
Luigi Toscano
1fb61059a7 Merge remote-tracking branch 'origin/Applications/17.04' 2017-07-15 15:28:38 +02:00
l10n daemon script
4564c91b64 GIT_SILENT made messages (after extraction) 2017-07-04 03:06:55 +02:00
l10n daemon script
01ec550abf GIT_SILENT made messages (after extraction) 2017-07-01 03:13:36 +02:00
Albert Astals Cid
f131f7ddba Remove old X11 plugin
It wasn't being compiled anyway
2017-06-15 23:24:45 +02:00
Alexey Min
b2cb3e8204 Implement XCB framebuffer plugin (port from x11)
Previously used x11 plugin does not compile with Qt5, because Qt5 does
not use Xlib, it uses xcb. Rewrite screen capture plugin from Xlib to
xcb.

I made xcb libs compile required dependency, but availability of X
shared memory extension is checked at runtime. It is used to effectively
get image pixels data, instead of transfering 8Mb over the wire. Xdamage
is used to limit image getting operations only within actually changed
rectangles of screen.

BUG: 377998

Tested on single-monitor system and dual-monitor, where primary monitor
does not start at (0,0) coordinate. Image transfer works fine.
Dual-monitor only has problems with receiving mouse cursor position and
clicks, but this should be fixed outside of framebuffer plugin.

Differential Revision: https://phabricator.kde.org/D5211
2017-06-15 23:21:58 +02:00
l10n daemon script
c92ef2f230 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-06-11 04:37:36 +02:00
l10n daemon script
b2fe612ec4 GIT_SILENT made messages (after extraction) 2017-06-11 03:09:33 +02:00
Christoph Feck
831ec6c9be Fix SPDX license ID 2017-06-09 03:57:04 +02:00
l10n daemon script
4b01a1cac7 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-23 04:05:02 +02:00
l10n daemon script
09b643f5cb GIT_SILENT made messages (after extraction) 2017-04-23 02:49:04 +02:00
l10n daemon script
77ef270323 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-14 03:58:43 +02:00
l10n daemon script
e487c45f34 GIT_SILENT made messages (after extraction) 2017-04-12 02:47:34 +02:00
l10n daemon script
8eecd9097e SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-09 04:03:05 +02:00
Albert Astals Cid
6561a9db15 Merge remote-tracking branch 'origin/Applications/17.04' 2017-03-24 00:21:50 +01:00
Albert Astals Cid
f107a73d28 Merge remote-tracking branch 'origin/Applications/17.04' 2017-03-24 00:12:20 +01:00
l10n daemon script
b960bb4ba4 GIT_SILENT made messages (after extraction) 2017-03-20 02:42:32 +01:00
33 changed files with 1177 additions and 633 deletions

3
.arcconfig Normal file
View File

@@ -0,0 +1,3 @@
{
"phabricator.uri" : "https://phabricator.kde.org/"
}

View File

@@ -1,4 +0,0 @@
REPOSITORY = "git://anongit.kde.org/krfb"
REVIEWBOARD_URL = "https://git.reviewboard.kde.org"
TARGET_PEOPLE = "whiting"

View File

@@ -1,11 +1,19 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_minimum_required(VERSION 3.0)
project(krfb)
# KDE Application Version, managed by release script
set (KDE_APPLICATIONS_VERSION_MAJOR "18")
set (KDE_APPLICATIONS_VERSION_MINOR "08")
set (KDE_APPLICATIONS_VERSION_MICRO "2")
set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}")
project(krfb VERSION ${KDE_APPLICATIONS_VERSION})
set(QT_MIN_VERSION 5.6.0)
set(KF5_MIN_VERSION 5.31.0)
include(FeatureSummary)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets X11Extras)
find_package(ECM 1.7.0 NO_MODULE REQUIRED)
find_package(ECM ${KF5_MIN_VERSION} NO_MODULE REQUIRED)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include(KDEInstallDirs)
@@ -13,6 +21,12 @@ include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMInstallIcons)
include(ECMAddAppIcon)
include(ECMSetupVersion)
include(FeatureSummary)
ecm_setup_version(PROJECT
VARIABLE_PREFIX KRFB
VERSION_HEADER "krfb_version.h")
find_package(KF5 REQUIRED COMPONENTS
I18n
@@ -31,10 +45,21 @@ find_package(KF5 REQUIRED COMPONENTS
find_package(X11 REQUIRED)
find_package(XCB REQUIRED COMPONENTS
XCB
RENDER
SHAPE
XFIXES
DAMAGE
SHM
IMAGE
)
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES ${KDEWIN32_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${KDEWIN32_INCLUDES})
endif(WIN32)
add_definitions(${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} )
@@ -46,16 +71,6 @@ set(CMAKE_MODULE_PATH
find_package(LibVNCServer REQUIRED)
if (HAVE_XDAMAGE)
set(X11_Xdamage_FOUND 1)
else()
set(X11_Xdamage_FOUND 0)
endif()
if (HAVE_XSHM)
set(X11_XShm_FOUND 1)
else()
set(X11_XShm_FOUND 0)
endif()
include_directories ("${CMAKE_CURRENT_BINARY_DIR}/krfb"
"${CMAKE_CURRENT_SOURCE_DIR}/krfb"
@@ -71,5 +86,6 @@ endif(Q_WS_X11)
add_subdirectory(krfb)
add_subdirectory(framebuffers)
add_subdirectory(doc)
add_subdirectory(icons)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

View File

@@ -1,3 +1,5 @@
add_subdirectory (qt)
add_subdirectory (x11)
if (${XCB_DAMAGE_FOUND} AND ${XCB_SHM_FOUND} AND ${XCB_IMAGE_FOUND})
add_subdirectory (xcb)
endif()

View File

@@ -21,6 +21,7 @@ Comment[gl]=Framebuffer baseado en Qt para KRfb.
Comment[hr]=Međuspremnik okvira baziran na Qt-u za KRfb.
Comment[hu]=Qt-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur Qt per KRfb
Comment[id]=Framebuffer berbasiskan Qt untuk KRfb.
Comment[it]=Framebuffer basato su Qt per KRfb.
Comment[kk]=Qt негіздеген KRfb-нің кадр буфері.
Comment[km]=Framebuffer មាន​មូលដ្ឋាន​លើ Qt សម្រាប់ KRfb 
@@ -69,6 +70,7 @@ Name[gl]=Framebuffer de Qt para KRfb
Name[hr]=Qt Framebuffer za KRfb
Name[hu]=Qt framebuffer a Krfb-hez
Name[ia]=Framebuffer Qt per KRfb
Name[id]=Qt Framebuffer untuk KRfb
Name[it]=Framebuffer Qt per KRfb
Name[kk]=Qt KRfb кадр буфері
Name[km]=Qt Framebuffer សម្រាប់for KRfb

View File

@@ -8,12 +8,14 @@
"Description[cs]": "Framebuffer založený na Qt pro KRfb.",
"Description[da]": "Qt-baseret framebuffer til KRfb.",
"Description[de]": "Qt-basierter Framebuffer für KRfb",
"Description[el]": "Μνήμη ανανέωσης βίντεο με βάση τhn Qt για το KRfb.",
"Description[es]": "Framebuffer basado en Qt para KRfb.",
"Description[et]": "KRfb Qt põhine kaadripuhver",
"Description[fi]": "QT-perustainen Kehyspuskuri KRfb:lle",
"Description[fr]": "Tampon d'images utilisant Qt pour KRfb.",
"Description[gl]": "Framebuffer baseado en Qt para KRfb.",
"Description[ia]": "Framebuffer basate sur Qt per KRfb",
"Description[id]": "Framebuffer berbasiskan Qt untuk KRfb.",
"Description[it]": "Framebuffer basato su Qt per KRfb.",
"Description[ko]": "KRfb용 Qt 기반 프레임버퍼입니다.",
"Description[nl]": "Op Qt gebaseerd framebuffer voor KRfb.",
@@ -44,12 +46,14 @@
"Name[cs]": "Qt Framebuffer pro KRfb",
"Name[da]": "Qt-framebuffer til KRfb",
"Name[de]": "Qt-Framebuffer für KRfb",
"Name[el]": "Μνήμη ανανέωσης βίντεο Qt για το KRfb",
"Name[es]": "Framebuffer de Qt para KRfb",
"Name[et]": "KRfb Qt kaadripuhver",
"Name[fi]": "QT-kehyspuskuri KRfb:lle",
"Name[fr]": "Tampon d'images Qt pour KRfb",
"Name[gl]": "Framebuffer de Qt para KRfb",
"Name[ia]": "Framebuffer Qt per KRfb",
"Name[id]": "Qt Framebuffer untuk KRfb",
"Name[it]": "Framebuffer Qt per KRfb",
"Name[ko]": "KRfb용 Qt 프레임버퍼",
"Name[nl]": "Qt-framebuffer voor KRfb",

View File

@@ -1,27 +0,0 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set (krfb_framebuffer_x11_SRCS
x11framebuffer.cpp
x11framebufferplugin.cpp
)
add_library(krfb_framebuffer_x11
MODULE
${krfb_framebuffer_x11_SRCS}
)
target_link_libraries (krfb_framebuffer_x11
Qt5::Core
Qt5::Gui
${X11_X11_LIB}
${X11_Xdamage_LIB}
${X11_Xext_LIB}
KF5::CoreAddons
krfbprivate
)
install (TARGETS krfb_framebuffer_x11
DESTINATION ${PLUGIN_INSTALL_DIR}/krfb
)

View File

@@ -1,389 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "x11framebuffer.h"
#include "x11framebuffer.moc"
#include <config-krfb.h>
#include <QX11Info>
#include <QApplication>
#include <QDesktopWidget>
#include <QDebug>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef HAVE_XDAMAGE
#include <X11/extensions/Xdamage.h>
#endif
#ifdef HAVE_XSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
class X11FrameBuffer::P
{
public:
#ifdef HAVE_XDAMAGE
Damage damage;
#endif
#ifdef HAVE_XSHM
XShmSegmentInfo shminfo;
#endif
XImage *framebufferImage;
XImage *updateTile;
EvWidget *ev;
bool useShm;
int xdamageBaseEvent;
bool running;
};
X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent), d(new X11FrameBuffer::P)
{
#ifdef HAVE_XSHM
d->useShm = XShmQueryExtension(QX11Info::display());
//qDebug() << "shm: " << d->useShm;
#else
d->useShm = false;
#endif
d->running = false;
d->framebufferImage = XGetImage(QX11Info::display(),
id,
0,
0,
QApplication::desktop()->width(), //arg, must get a widget ???
QApplication::desktop()->height(),
AllPlanes,
ZPixmap);
if (d->useShm) {
#ifdef HAVE_XSHM
d->updateTile = XShmCreateImage(QX11Info::display(),
DefaultVisual(QX11Info::display(), 0),
d->framebufferImage->bits_per_pixel,
ZPixmap,
NULL,
&d->shminfo,
32,
32);
d->shminfo.shmid = shmget(IPC_PRIVATE,
d->updateTile->bytes_per_line * d->updateTile->height,
IPC_CREAT | 0777);
d->shminfo.shmaddr = d->updateTile->data = (char *)
shmat(d->shminfo.shmid, 0, 0);
d->shminfo.readOnly = False;
XShmAttach(QX11Info::display(), &d->shminfo);
#endif
} else {
;
}
qDebug() << "Got image. bpp: " << d->framebufferImage->bits_per_pixel
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->bytes_per_line
<< " (sent: " << d->framebufferImage->width * 4 << ")"
<< endl;
fb = d->framebufferImage->data;
#ifdef HAVE_XDAMAGE
d->ev = new EvWidget(this);
qApp->installX11EventFilter(d->ev);
#endif
}
X11FrameBuffer::~X11FrameBuffer()
{
XDestroyImage(d->framebufferImage);
#ifdef HAVE_XDAMAGE
qApp->removeX11EventFilter(d->ev);
#endif
#ifdef HAVE_XSHM
XShmDetach(QX11Info::display(), &d->shminfo);
XDestroyImage(d->updateTile);
shmdt(d->shminfo.shmaddr);
shmctl(d->shminfo.shmid, IPC_RMID, 0);
#endif
delete d;
fb = 0; // already deleted by XDestroyImage
}
int X11FrameBuffer::depth()
{
return d->framebufferImage->depth;
}
int X11FrameBuffer::height()
{
return d->framebufferImage->height;
}
int X11FrameBuffer::width()
{
return d->framebufferImage->width;
}
int X11FrameBuffer::paddedWidth()
{
return d->framebufferImage->bytes_per_line;
}
void X11FrameBuffer::getServerFormat(rfbPixelFormat &format)
{
format.bitsPerPixel = d->framebufferImage->bits_per_pixel;
format.depth = d->framebufferImage->depth;
format.trueColour = true;
format.bigEndian = ((d->framebufferImage->bitmap_bit_order == MSBFirst) ? true : false);
if (format.bitsPerPixel == 8) {
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
format.redMax = 7;
format.greenMax = 7;
format.blueMax = 3;
} else {
format.redShift = 0;
if (d->framebufferImage->red_mask)
while (!(d->framebufferImage->red_mask & (1 << format.redShift))) {
format.redShift++;
}
format.greenShift = 0;
if (d->framebufferImage->green_mask)
while (!(d->framebufferImage->green_mask & (1 << format.greenShift))) {
format.greenShift++;
}
format.blueShift = 0;
if (d->framebufferImage->blue_mask)
while (!(d->framebufferImage->blue_mask & (1 << format.blueShift))) {
format.blueShift++;
}
format.redMax = d->framebufferImage->red_mask >> format.redShift;
format.greenMax = d->framebufferImage->green_mask >> format.greenShift;
format.blueMax = d->framebufferImage->blue_mask >> format.blueShift;
}
}
void X11FrameBuffer::handleXDamage(XEvent *event)
{
#ifdef HAVE_XDAMAGE
XDamageNotifyEvent *dev = (XDamageNotifyEvent *)event;
QRect r(dev->area.x, dev->area.y, dev->area.width, dev->area.height);
tiles.append(r);
/*if (!dev->more) {
XDamageSubtract(QX11Info::display(),d->damage, None, None);
}*/
#endif
}
void X11FrameBuffer::cleanupRects()
{
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
// //qDebug() << "before cleanup: " << cpy.size();
foreach(const QRect & r, cpy) {
if (tiles.size() > 0) {
for (int i = 0; i < tiles.size(); i++) {
// //qDebug() << r << tiles[i];
if (r.intersects(tiles[i])) {
tiles[i] |= r;
inserted = true;
break;
// //qDebug() << "merged into " << tiles[i];
}
}
if (!inserted) {
tiles.append(r);
// //qDebug() << "appended " << r;
}
} else {
// //qDebug() << "appended " << r;
tiles.append(r);
}
}
for (int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30, -30, 30, 30);
if (tiles[i].top() < 0) {
tiles[i].setTop(0);
}
if (tiles[i].left() < 0) {
tiles[i].setLeft(0);
}
if (tiles[i].bottom() > d->framebufferImage->height) {
tiles[i].setBottom(d->framebufferImage->height);
}
if (tiles[i].right() > d->framebufferImage->width) {
tiles[i].setRight(d->framebufferImage->width);
}
}
// //qDebug() << "after cleanup: " << tiles.size();
}
void X11FrameBuffer::acquireEvents()
{
XEvent ev;
#ifdef HAVE_XDAMAGE
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
handleXDamage(&ev);
}
XDamageSubtract(QX11Info::display(), d->damage, None, None);
#endif
}
QList< QRect > X11FrameBuffer::modifiedTiles()
{
QList<QRect> ret;
if (!d->running) {
return ret;
}
qApp->processEvents(); // try to make sure every damage event goes trough;
cleanupRects();
QRect gl;
//d->useShm = false;
if (tiles.size() > 0) {
if (d->useShm) {
#ifdef HAVE_XSHM
foreach(const QRect & r, tiles) {
// //qDebug() << r;
gl |= r;
int y = r.y();
int x = r.x();
while (x < r.right()) {
while (y < r.bottom()) {
if (y + d->updateTile->height > d->framebufferImage->height) {
y = d->framebufferImage->height - d->updateTile->height;
}
if (x + d->updateTile->width > d->framebufferImage->width) {
x = d->framebufferImage->width - d->updateTile->width;
}
// //qDebug() << "x: " << x << " (" << r.x() << ") y: " << y << " (" << r.y() << ") " << r;
XShmGetImage(QX11Info::display(), win, d->updateTile, x, y, AllPlanes);
int pxsize = d->framebufferImage->bits_per_pixel / 8;
char *dest = fb + ((d->framebufferImage->bytes_per_line * y) + (x * pxsize));
char *src = d->updateTile->data;
for (int i = 0; i < d->updateTile->height; i++) {
memcpy(dest, src, d->updateTile->bytes_per_line);
dest += d->framebufferImage->bytes_per_line;
src += d->updateTile->bytes_per_line;
}
y += d->updateTile->height;
}
x += d->updateTile->width;
y = r.y();
}
}
#endif
} else {
foreach(const QRect & r, tiles) {
XGetSubImage(QX11Info::display(),
win,
r.left(),
r.top(),
r.width(),
r.height(),
AllPlanes,
ZPixmap,
d->framebufferImage,
r.left(),
r.top()
);
}
}
}
// //qDebug() << "tot: " << gl;
// //qDebug() << tiles.size();
ret = tiles;
tiles.clear();
return ret;
}
void X11FrameBuffer::startMonitor()
{
d->running = true;
#ifdef HAVE_XDAMAGE
d->damage = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles);
XDamageSubtract(QX11Info::display(), d->damage, None, None);
#endif
}
void X11FrameBuffer::stopMonitor()
{
d->running = false;
#ifdef HAVE_XDAMAGE
XDamageDestroy(QX11Info::display(), d->damage);
#endif
}
EvWidget::EvWidget(X11FrameBuffer *x11fb)
: QWidget(0), fb(x11fb)
{
#ifdef HAVE_XDAMAGE
int er;
XDamageQueryExtension(QX11Info::display(), &xdamageBaseEvent, &er);
#endif
}
bool EvWidget::x11Event(XEvent *event)
{
#ifdef HAVE_XDAMAGE
if (event->type == xdamageBaseEvent + XDamageNotify) {
fb->handleXDamage(event);
return true;
}
#endif
return false;
}

View File

@@ -1,63 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFER_H
#define KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFER_H
#include <framebuffer.h>
#include <QWidget>
class X11FrameBuffer;
typedef union _XEvent XEvent;
class EvWidget: public QWidget
{
Q_OBJECT
public:
EvWidget(X11FrameBuffer *x11fb);
protected:
bool x11Event(XEvent *event);
private:
X11FrameBuffer *fb;
int xdamageBaseEvent;
};
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class X11FrameBuffer : public FrameBuffer
{
Q_OBJECT
public:
X11FrameBuffer(WId id, QObject *parent = 0);
~X11FrameBuffer();
QList<QRect> modifiedTiles() override;
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
void getServerFormat(rfbPixelFormat &format) override;
void startMonitor() override;
void stopMonitor() override;
void handleXDamage(XEvent *event);
private:
void cleanupRects();
void acquireEvents();
class P;
P *const d;
};
#endif

View File

@@ -1,45 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "x11framebufferplugin.h"
#include "x11framebuffer.h"
#include <KPluginFactory>
K_PLUGIN_FACTORY_WITH_JSON(X11FrameBufferPluginFactory, "krfb_framebuffer_x11.json",
registerPlugin<X11FrameBufferPlugin>();)
X11FrameBufferPlugin::X11FrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
{
}
X11FrameBufferPlugin::~X11FrameBufferPlugin()
{
}
FrameBuffer *X11FrameBufferPlugin::frameBuffer(WId id)
{
return new X11FrameBuffer(id);
}
#include "x11framebufferplugin.moc"

View File

@@ -1,46 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFERPLUGIN_H
#define KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFERPLUGIN_H
#include "framebufferplugin.h"
#include <QWidget>
class FrameBuffer;
class X11FrameBufferPlugin : public FrameBufferPlugin
{
Q_OBJECT
public:
X11FrameBufferPlugin(QObject *parent, const QVariantList &args);
virtual ~X11FrameBufferPlugin();
FrameBuffer *frameBuffer(WId id) override;
private:
Q_DISABLE_COPY(X11FrameBufferPlugin)
};
#endif // Header guard

View File

@@ -0,0 +1,28 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set (krfb_framebuffer_xcb_SRCS
xcb_framebufferplugin.cpp
xcb_framebuffer.cpp
)
add_library(krfb_framebuffer_xcb MODULE ${krfb_framebuffer_xcb_SRCS})
target_link_libraries (krfb_framebuffer_xcb
Qt5::Core
Qt5::Gui
XCB::XCB
XCB::RENDER
XCB::SHAPE
XCB::XFIXES
XCB::DAMAGE
XCB::SHM
XCB::IMAGE
KF5::CoreAddons
krfbprivate
)
install (TARGETS krfb_framebuffer_xcb
DESTINATION ${PLUGIN_INSTALL_DIR}/krfb
)

View File

@@ -17,10 +17,11 @@ Comment[eu]=X11 XDamage/XShm oinarritutako KRfb-ren irteerako bideoa.
Comment[fi]=X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.
Comment[fr]=Sortie vidéo fondée sur X11 « XDamage / XShm » pour Krfb.
Comment[ga]=Maolán fráma le haghaidh KRfb, bunaithe ar X11 XDamage/XShm
Comment[gl]=Framebuffer baseado en Xll XDamage/Xshm para XRfb.
Comment[gl]=Framebuffer baseado en X11 XDamage/Xshm para XRfb.
Comment[hr]=Međuspreminik okvira baziran na X11 XDamage/XShm za KRfb.
Comment[hu]=X11 XDamage/XShm-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur X11 XDamage/XShm per KRfb.
Comment[id]=Framebuffer berbasiskan X11 XDamage/XShm untuk KRfb.
Comment[it]=Framebuffer basato su XDamage/XShm di X11 per KRfb.
Comment[kk]=X11 XDamage/XShm негіздеген KRfb кадр буфері.
Comment[km]=X11 XDamage/XShm based Framebuffer KRfb 
@@ -69,6 +70,7 @@ Name[gl]=Framebuffer de X11 para KRfb
Name[hr]=Međuspremnik okvira X11 za KRfb
Name[hu]=X11 framebuffer a Krfb-hez
Name[ia]=Framebuffer X11 per KRfb
Name[id]=Framebuffer X11 untuk KRfb
Name[it]=Framebuffer X11 per KRfb
Name[kk]=X11 KRfb кадр буфері
Name[km]=X11 Framebuffer KRfb
@@ -99,8 +101,8 @@ Name[zh_TW]=KRfb 的 X11 Framebuffer
Type=Service
ServiceTypes=krfb/framebuffer
X-KDE-Library=krfb_framebuffer_x11
X-KDE-PluginInfo-Name=x11
X-KDE-Library=krfb_framebuffer_xcb
X-KDE-PluginInfo-Name=xcb
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://www.kde.org
X-KDE-PluginInfo-License=GPL

View File

@@ -8,12 +8,14 @@
"Description[cs]": "Framebuffer založený na X11 XDamage/XShm pro KRfb.",
"Description[da]": "X11 XDamage/XShm-baseret framebuffer til KRfb.",
"Description[de]": "X11 XDamage/XShm-basierter Framebuffer für KRfb.",
"Description[el]": "Μνήμη ανανέωσης βίντεο με βάση το X11 XDamage/XShm για το KRfb.",
"Description[es]": "Framebuffer basado en XDamage/XShm de X11 para KRfb.",
"Description[et]": "KRfb X11 XDamage/XShm põhine kaadripuhver",
"Description[fi]": "X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.",
"Description[fr]": "Tampon d'images utilisant XDamage/XShm de X11 pour KRfb.",
"Description[gl]": "Framebuffer baseado en Xll XDamage/Xshm para XRfb.",
"Description[gl]": "Framebuffer baseado en X11 XDamage/Xshm para XRfb.",
"Description[ia]": "Framebuffer basate sur X11 XDamage/XShm per KRfb.",
"Description[id]": "Framebuffer berbasiskan X11 XDamage/XShm untuk KRfb.",
"Description[it]": "Framebuffer basato su XDamage/XShm di X11 per KRfb.",
"Description[ko]": "KRfb용 X11 XDamage/XShm 기반 프레임버퍼입니다.",
"Description[nl]": "Op X11 XDamage/XShm gebaseerd framebuffer voor KRfb.",
@@ -35,7 +37,7 @@
"Description[zh_CN]": "KRfb 的基于 X11 XDamage/XShm 的帧缓冲。",
"Description[zh_TW]": "KRfb 的 X11 XDamage/XShm based Framebuffer",
"EnabledByDefault": true,
"Id": "x11",
"Id": "xcb",
"License": "GPL",
"Name": "X11 Framebuffer for KRfb",
"Name[ast]": "Búfer de cuadros de X11 pa KRfb",
@@ -44,12 +46,14 @@
"Name[cs]": "X11 Framebuffer pro KRfb",
"Name[da]": "X11-framebuffer til KRfb",
"Name[de]": "X11-Framebuffer für KRfb",
"Name[el]": "Μνήμη ανανέωσης βίντεο X11 για το KRfb.",
"Name[es]": "Framebuffer X11 para KRfb",
"Name[et]": "KRfb X11 kaadripuhver",
"Name[fi]": "X11-kehyspuskuri KRfb:lle",
"Name[fr]": "Tampon d'images X11 pour KRfb",
"Name[gl]": "Framebuffer de X11 para KRfb",
"Name[ia]": "Framebuffer X11 per KRfb",
"Name[id]": "Framebuffer X11 untuk KRfb",
"Name[it]": "Framebuffer X11 per KRfb",
"Name[ko]": "KRfb용 X11 프레임버퍼",
"Name[nl]": "X11 framebuffer voor KRfb",

View File

@@ -0,0 +1,685 @@
/* This file is part of the KDE project
Copyright (C) 2017 Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "xcb_framebuffer.h"
#include "xcb_framebuffer.moc"
#include <xcb/xcb.h>
#include <xcb/xproto.h>
#include <xcb/damage.h>
#include <xcb/shm.h>
#include <xcb/xcb_image.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <QX11Info>
#include <QCoreApplication>
#include <QGuiApplication>
#include <QScreen>
#include <QAbstractNativeEventFilter>
#include <QDebug>
class KrfbXCBEventFilter: public QAbstractNativeEventFilter
{
public:
KrfbXCBEventFilter(XCBFrameBuffer *owner);
public:
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
public:
int xdamageBaseEvent;
int xdamageBaseError;
int xshmBaseEvent;
int xshmBaseError;
bool xshmAvail;
XCBFrameBuffer *fb_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);
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),
NULL);
if (!xdamage_version) {
qWarning() << "xcb framebuffer: ERROR: Failed to get XDamage extension version!\n";
return;
}
#ifdef _DEBUG
qDebug() << "xcb framebuffer: XDamage extension version:" <<
xdamage_version->major_version << "." << xdamage_version->minor_version;
#endif
free(xdamage_version);
xdamageBaseEvent = xdamage_data->first_event;
xdamageBaseError = xdamage_data->first_error;
// 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);
if (xshm_data) {
xshmAvail = true;
xshmBaseEvent = xshm_data->first_event;
xshmBaseError = xshm_data->first_error;
} else {
xshmAvail = false;
qWarning() << "xcb framebuffer: WARNING: XSHM extension not available!";
}
} else {
// if there is no xdamage available, this plugin can be considered useless anyway.
// you can use just qt framebuffer plugin instead...
qWarning() << "xcb framebuffer: ERROR: no XDamage extension available. I am useless.";
qWarning() << "xcb framebuffer: use qt framebuffer plugin instead.";
}
}
bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
void *message, long *result) {
Q_UNUSED(result); // "result" is only used on windows
if (xdamageBaseEvent == 0) return false; // no xdamage extension
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t* 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
}
}
// continue event processing
return false;
}
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;
KrfbXCBEventFilter *x11EvtFilter;
bool running;
QRect area; // capture area, primary monitor coordinates
};
static xcb_screen_t *get_xcb_screen(xcb_connection_t *conn, int screen_num) {
xcb_screen_t *screen = NULL;
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)
screen = screens_iter.data;
return screen;
}
XCBFrameBuffer::XCBFrameBuffer(WId winid, QObject *parent):
FrameBuffer(winid, parent), d(new XCBFrameBuffer::P)
{
d->running = false;
d->damage = XCB_NONE;
d->framebufferImage = Q_NULLPTR;
d->shminfo.shmaddr = Q_NULLPTR;
d->shminfo.shmid = XCB_NONE;
d->shminfo.shmseg = XCB_NONE;
d->updateTile = Q_NULLPTR;
d->area.setRect(0, 0, 0, 0);
d->x11EvtFilter = new KrfbXCBEventFilter(this);
d->rootScreen = get_xcb_screen(QX11Info::connection(), QX11Info::appScreen());
this->fb = Q_NULLPTR;
QScreen *primaryScreen = QGuiApplication::primaryScreen();
if (primaryScreen) {
qDebug() << "xcb framebuffer: Primary screen: " << primaryScreen->name()
<< ", geometry: " << primaryScreen->geometry()
<< ", depth: " << primaryScreen->depth();
//
d->area = primaryScreen->geometry();
} else {
qWarning() << "xcb framebuffer: ERROR: Failed to get application's primary screen info!";
return;
}
d->framebufferImage = xcb_image_get(QX11Info::connection(),
this->win,
d->area.left(),
d->area.top(),
d->area.width(),
d->area.height(),
0xFFFFFFFF, // == Xlib: AllPlanes ((unsigned long)~0L)
XCB_IMAGE_FORMAT_Z_PIXMAP);
if (d->framebufferImage) {
#ifdef _DEBUG
qDebug() << "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;
#endif
this->fb = (char *)d->framebufferImage->data;
} else {
qWarning() << "xcb framebuffer: ERROR: Failed to get primary screen image!";
return;
}
// all XShm operations should take place only if Xshm extension was loaded
if (d->x11EvtFilter->xshmAvail) {
// Create xcb_image_t structure, but do not automatically allocate memory
// for image data storage - it will be allocated as shared memory.
// "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
NULL, // base address = 0
(uint32_t)~0, // bytes = 0xffffffff
NULL); // data = 0
if (d->updateTile) {
#ifdef _DEBUG
qDebug() << "xcb framebuffer: Successfully created new empty image in native format";
qDebug() << " size: " << d->updateTile->width << "x" << d->updateTile->height
<< "(stride: " << d->updateTile->stride << ")";
qDebug() << " bpp, depth: " << d->updateTile->bpp << d->updateTile->depth; // 32, 24
qDebug() << " addr of base, data: " << d->updateTile->base << (void *)d->updateTile->data;
qDebug() << " size: " << d->updateTile->size;
qDebug() << " image byte order = " << d->updateTile->byte_order; // == 0 .._LSB_FIRST
qDebug() << " image bit order = " << d->updateTile->bit_order; // == 1 .._MSB_FIRST
qDebug() << " image plane_mask = " << d->updateTile->plane_mask; // == 16777215 == 0x00FFFFFF
#endif
// allocate shared memory block only once, make its size large enough
// to fit whole capture area (d->area rect)
// so, we get as many bytes as needed for image (updateTile->size)
d->shminfo.shmid = shmget(IPC_PRIVATE, d->updateTile->size, IPC_CREAT | 0777);
// attached shared memory address is stored both in shminfo structure and in xcb_image_t->data
d->shminfo.shmaddr = (uint8_t *)shmat(d->shminfo.shmid, NULL, 0);
d->updateTile->data = d->shminfo.shmaddr;
// we keep updateTile->base == NULL here, so xcb_image_destroy() will not attempt
// to free this block, just in case.
// attach this shm segment also to X server
d->shminfo.shmseg = xcb_generate_id(QX11Info::connection());
xcb_shm_attach(QX11Info::connection(), d->shminfo.shmseg, d->shminfo.shmid, 0);
#ifdef _DEBUG
qDebug() << " shm id: " << d->shminfo.shmseg << ", addr: " << (void *)d->shminfo.shmaddr;
#endif
// will return 1 on success (yes!)
int shmget_res = xcb_image_shm_get(
QX11Info::connection(),
this->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?
// will not use shared mem! detach and cleanup
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg);
shmdt(d->shminfo.shmaddr);
shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed
d->x11EvtFilter->xshmAvail = false;
d->shminfo.shmaddr = Q_NULLPTR;
d->shminfo.shmid = XCB_NONE;
d->shminfo.shmseg = XCB_NONE;
qWarning() << "xcb framebuffer: ERROR: xcb_image_shm_get() result: " << shmget_res;
}
// image is freed, and recreated again for every new damage rectangle
// data was allocated manually and points to shared mem;
// tell xcb_image_destroy() do not free image data
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
d->updateTile = NULL;
}
}
#ifdef _DEBUG
qDebug() << "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;
#endif
QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter);
}
XCBFrameBuffer::~XCBFrameBuffer() {
// first - uninstall x11 event filter
QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter);
//
if (d->framebufferImage) {
xcb_image_destroy(d->framebufferImage);
fb = Q_NULLPTR; // image data was already destroyed by above call
}
if (d->x11EvtFilter->xshmAvail) {
// detach shared memory
if (d->shminfo.shmseg != XCB_NONE)
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); // detach from X server
if (d->shminfo.shmaddr)
shmdt(d->shminfo.shmaddr); // detach addr from our address space
if (d->shminfo.shmid != XCB_NONE)
shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed
}
// and delete image used for shared mem
if (d->updateTile) {
d->updateTile->base = NULL;
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
}
// we don't use d->x11EvtFilter anymore, can delete it now
if (d->x11EvtFilter) {
delete d->x11EvtFilter;
}
delete d;
}
int XCBFrameBuffer::depth() {
if (d->framebufferImage) {
return d->framebufferImage->depth;
}
return 0;
}
int XCBFrameBuffer::height() {
if (d->framebufferImage) {
return d->framebufferImage->height;
}
return 0;
}
int XCBFrameBuffer::width() {
if (d->framebufferImage) {
return d->framebufferImage->width;
}
return 0;
}
int XCBFrameBuffer::paddedWidth() {
if (d->framebufferImage) {
return d->framebufferImage->stride;
}
return 0;
}
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
if (!d->framebufferImage) return;
// get information about XCB visual params
xcb_visualtype_t *root_visualtype = NULL; // visual info
if (d->rootScreen) {
xcb_visualid_t root_visual = d->rootScreen->root_visual;
xcb_depth_iterator_t depth_iter;
// To get the xcb_visualtype_t structure, it's a bit less easy.
// You have to get the xcb_screen_t structure that you want, get its
// root_visual member, then iterate over the xcb_depth_t's and the
// xcb_visualtype_t's, and compare the xcb_visualid_t of these
// xcb_visualtype_ts: with root_visual
depth_iter = xcb_screen_allowed_depths_iterator(d->rootScreen);
for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
xcb_visualtype_iterator_t visual_iter;
visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
if (root_visual == visual_iter.data->visual_id) {
root_visualtype = visual_iter.data;
break;
}
}
}
}
// 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!
// information about pixels layout
if (root_visualtype) {
uint16_t pixelmaxValue = (1 << root_visualtype->bits_per_rgb_value) - 1;
#ifdef _DEBUG
qDebug("xcb framebuffer: Got info about root visual:\n"
" bits per rgb value: %d\n"
" red mask: %08x\n"
" green mask: %08x\n"
" blue mask: %08x\n"
" pixelMaxValue = %d\n",
(int)root_visualtype->bits_per_rgb_value,
root_visualtype->red_mask,
root_visualtype->green_mask,
root_visualtype->blue_mask,
(int)pixelmaxValue);
#endif
// calculate shifts
format.redShift = 0;
format.redMax = pixelmaxValue;
if (root_visualtype->red_mask) {
while (!(root_visualtype->red_mask & (1 << format.redShift))) {
format.redShift++;
}
}
format.greenShift = 0;
format.greenMax = pixelmaxValue;
if (root_visualtype->green_mask) {
while (!(root_visualtype->green_mask & (1 << format.greenShift))) {
format.greenShift++;
}
}
format.blueShift = 0;
format.blueMax = pixelmaxValue;
if (root_visualtype->blue_mask) {
while (!(root_visualtype->blue_mask & (1 << format.blueShift))) {
format.blueShift++;
}
}
#ifdef _DEBUG
qDebug() << " Calculated redShift =" << (int)format.redShift;
qDebug() << " Calculated greenShift =" << (int)format.greenShift;
qDebug() << " Calculated blueShift =" << (int)format.blueShift;
#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.greenShift = 3;
format.blueShift = 6;
format.redMax = 7;
format.greenMax = 7;
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.greenMax = 0xff;
format.blueMax = 0xff;
if (format.bigEndian) {
format.redShift = 0;
format.greenShift = 8;
format.blueShift = 16;
} else {
format.redShift = 16;
format.greenShift = 8;
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() {
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
QListIterator<QRect> iter(cpy);
while (iter.hasNext()) {
const QRect &r = iter.next();
// skip rects not intersecting with primary monitor
if (!r.intersects(d->area)) continue;
// only take intersection of this rect with primary monitor rect
QRect ri = r.intersected(d->area);
if (tiles.size() > 0) {
for (int i = 0; i < tiles.size(); i++) {
// if current rect has intersection with tiles[i], unite them
if (ri.intersects(tiles[i])) {
tiles[i] |= ri;
inserted = true;
break;
}
}
if (!inserted) {
// else, append to list as different rect
tiles.append(ri);
}
} else {
// tiles list is empty, append first item
tiles.append(ri);
}
}
// increase all rectangles size by 30 pixels each side.
// limit coordinates to primary monitor boundaries.
for (int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30, -30, 30, 30);
if (tiles[i].top() < d->area.top()) {
tiles[i].setTop(d->area.top());
}
if (tiles[i].bottom() > d->area.bottom()) {
tiles[i].setBottom(d->area.bottom());
}
//
if (tiles[i].left() < d->area.left()) {
tiles[i].setLeft(d->area.left());
}
if (tiles[i].right() > d->area.right()) {
tiles[i].setRight(d->area.right());
}
// move update rects so that they are positioned relative to
// framebuffer image, not whole screen
tiles[i].moveTo(tiles[i].left() - d->area.left(),
tiles[i].top() - d->area.top());
}
}
/**
* 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> ret;
if (!d->running) {
return ret;
}
cleanupRects();
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) {
while (iter.hasNext()) {
const QRect &r = iter.next();
// get image data into shared memory segment
// now rects are positioned relative to framebufferImage,
// but we need to get image from the whole screen, so
// translate whe coordinates
xcb_shm_get_image_cookie_t sgi_cookie = xcb_shm_get_image(
QX11Info::connection(),
this->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, NULL);
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,
NULL, // base == 0
(uint32_t)~0, // bytes == ~0
NULL);
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;
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
dest += d->framebufferImage->stride;
src += d->updateTile->stride;
}
// delete temporary image
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
d->updateTile = NULL;
}
free(sgi_reply);
}
} // foreach
} else {
// not using shared memory
// will use just xcb_image_get() and copy pixels
foreach(const QRect &r, 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(),
this->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;
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
}
//
xcb_image_destroy(damagedImage);
}
}
} // if (tiles.size() > 0)
ret = tiles;
tiles.clear();
// ^^ If we clear here all our known "damage areas", then we can also clear
// damaged area for xdamage? No, we don't need to in our case
// (XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES report mode)
//xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
return ret;
}
void XCBFrameBuffer::startMonitor() {
if (d->running) return;
d->running = true;
d->damage = xcb_generate_id(QX11Info::connection());
xcb_damage_create(QX11Info::connection(), d->damage, this->win,
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);
}
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:
//
// XEvent ev;
// while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
// handleXDamage(&ev);
// }
// XDamageSubtract(QX11Info::display(), d->damage, None, None);
//
// 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) {
xcb_damage_notify_event_t *xdevt = (xcb_damage_notify_event_t *)xevent;
QRect r((int)xdevt->area.x, (int)xdevt->area.y,
(int)xdevt->area.width, (int)xdevt->area.height);
this->tiles.append(r);
}

View File

@@ -0,0 +1,48 @@
/* This file is part of the KDE project
Copyright (C) 2017 Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
#define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
#include "framebuffer.h"
#include <QWidget>
#include <xcb/xcb.h>
/**
@author Alexey Min <alexey.min@gmail.com>
*/
class XCBFrameBuffer: public FrameBuffer
{
Q_OBJECT
public:
XCBFrameBuffer(WId winid, QObject *parent = 0);
~XCBFrameBuffer();
public:
QList<QRect> modifiedTiles() Q_DECL_OVERRIDE;
int depth() Q_DECL_OVERRIDE;
int height() Q_DECL_OVERRIDE;
int width() Q_DECL_OVERRIDE;
int paddedWidth() Q_DECL_OVERRIDE;
void getServerFormat(rfbPixelFormat &format) Q_DECL_OVERRIDE;
void startMonitor() Q_DECL_OVERRIDE;
void stopMonitor() Q_DECL_OVERRIDE;
public:
void handleXDamageNotify(xcb_generic_event_t *xevent);
private:
void cleanupRects();
class P;
P *const d;
};
#endif

View File

@@ -0,0 +1,46 @@
/* This file is part of the KDE project
@author Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "xcb_framebufferplugin.h"
#include "xcb_framebuffer.h"
#include <KPluginFactory>
K_PLUGIN_FACTORY_WITH_JSON(XCBFrameBufferPluginFactory, "krfb_framebuffer_xcb.json",
registerPlugin<XCBFrameBufferPlugin>();)
XCBFrameBufferPlugin::XCBFrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
{
}
XCBFrameBufferPlugin::~XCBFrameBufferPlugin()
{
}
FrameBuffer *XCBFrameBufferPlugin::frameBuffer(WId id)
{
return new XCBFrameBuffer(id);
}
#include "xcb_framebufferplugin.moc"

View File

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

BIN
icons/48-apps-krfb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

4
icons/CMakeLists.txt Normal file
View File

@@ -0,0 +1,4 @@
ecm_install_icons(ICONS
sc-apps-krfb.svgz
48-apps-krfb.png
DESTINATION ${KDE_INSTALL_ICONDIR} THEME hicolor )

BIN
icons/sc-apps-krfb.svgz Normal file

Binary file not shown.

View File

@@ -68,6 +68,7 @@ kconfig_add_kcfg_files (krfb_SRCS
ki18n_wrap_ui (krfb_SRCS
ui/configtcp.ui
ui/configsecurity.ui
ui/configframebuffer.ui
ui/connectionwidget.ui
ui/mainwidget.ui
)

View File

@@ -71,25 +71,25 @@ void FrameBufferManager::loadPlugins()
i.toBack();
QSet<QString> unique;
while (i.hasPrevious()) {
KPluginMetaData data = i.previous();
const KPluginMetaData &data = i.previous();
// only load plugins once, even if found multiple times!
if (unique.contains(data.name()))
continue;
KPluginFactory *factory = KPluginLoader(data.fileName()).factory();
if (!factory) {
qDebug() << "KPluginFactory could not load the plugin:" << data.fileName();
} else {
qDebug() << "found plugin at " << data.fileName();
}
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
if (plugin) {
m_plugins.insert(data.pluginId(), plugin);
qDebug() << "Loaded plugin with name " << data.pluginId();
} else {
qDebug() << "unable to load pluign for " << data.fileName();
}
KPluginFactory *factory = KPluginLoader(data.fileName()).factory();
if (!factory) {
qDebug() << "KPluginFactory could not load the plugin:" << data.fileName();
} else {
qDebug() << "found plugin at " << data.fileName();
}
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
if (plugin) {
m_plugins.insert(data.pluginId(), plugin);
qDebug() << "Loaded plugin with name " << data.pluginId();
} else {
qDebug() << "unable to load pluign for " << data.fileName();
}
unique.insert (data.name());
}
}

View File

@@ -19,10 +19,11 @@ Comment[eu]=Irteerako bideoaren pluginak KRfb-rentzako
Comment[fi]=Kehyspuskuriliitännäinen kohteelle KRfb
Comment[fr]=Modules externes de sortie vidéo pour Krfb
Comment[ga]=Breiseáin Mhaoláin Fráma le haghaidh KRfb
Comment[gl]=Engadido de frame buffer para KRfb
Comment[gl]=Complementos de búfer de fotograma para KRfb
Comment[hr]=Priključci za međuspremnike okvira za KRfb
Comment[hu]=Framebuffer bővítmények a Krfb-hez
Comment[ia]=Plug-ins de Frame Buffer per KRfb
Comment[id]=Plugin Frame Buffer untuk KRfb
Comment[it]=Estensioni del framebuffer per KRfb
Comment[ja]=KRfb の フレームバッファプラグイン
Comment[kk]=KRfb кадр буфер плагині

View File

@@ -7,12 +7,14 @@
"Description[cs]": "Moduly Frame bufferu pro KRfb",
"Description[da]": "Framebuffer-plugins til KRfb",
"Description[de]": "Framebuffer-Module für KRfb",
"Description[el]": "Πρόσθετα μνήμης ανανέωσης βίντεο καρέ για το KRfb",
"Description[es]": "Complementos de framebuffer para KRfb",
"Description[et]": "KRfb kaadripuhvri pluginad",
"Description[fi]": "Kehyspuskuriliitännäinen kohteelle KRfb",
"Description[fr]": "Modules de tampons d'image pour KRfb",
"Description[gl]": "Engadido de frame buffer para KRfb",
"Description[gl]": "Complemento de búfer de fotograma para KRfb",
"Description[ia]": "Plug-ins de Frame Buffer per KRfb",
"Description[id]": "Plugin Frame Buffer untuk KRfb",
"Description[it]": "Estensioni del framebuffer per KRfb",
"Description[ko]": "KRfb 프레임버퍼 플러그인",
"Description[nl]": "Framebuffer-plugins voor KRfb",

View File

@@ -46,7 +46,7 @@
<group name="FrameBuffer">
<entry name="preferredFrameBufferPlugin" type="String">
<label>Preferred Frame Buffer Plugin</label>
<default>qt</default>
<default>xcb</default>
</entry>
</group>
</kcfg>

View File

@@ -30,6 +30,7 @@ Comment[hne]=डेस्कटाप साझेदारी
Comment[hr]=Dijeljenje radne površine
Comment[hu]=Munkaasztal-megosztás
Comment[ia]=Compartir de scriptorio
Comment[id]=Desktop Sharing
Comment[is]=Skjáborðamiðlun
Comment[it]=Condivisione del desktop
Comment[ja]=デスクトップ共有
@@ -98,6 +99,7 @@ Name[hne]=कमइया हर कनेक्सन स्वीकारा
Name[hr]=Korisnik prihvaća vezu
Name[hu]=A felhasználó engedélyezi a csatlakozást
Name[ia]=Usator da acceptation a connexion
Name[id]=Pengguna Menyetujui Koneksi
Name[is]=Notandi samþykkir tengingar
Name[it]=L'utente accetta la connessione
Name[ja]=ユーザが接続を許可
@@ -162,6 +164,7 @@ Comment[hne]=कमइया हर कनेक्सन स्वीकार
Comment[hr]=Korisnik prihvaća vezu
Comment[hu]=A felhasználó engedélyezi a csatlakozást
Comment[ia]=Usator da acceptation a connexion
Comment[id]=Pengguna menyetujui koneksi
Comment[is]=Notandi samþykkir tengingu
Comment[it]=L'utente accetta la connessione
Comment[ja]=ユーザが接続を許可
@@ -231,6 +234,7 @@ Name[hne]=कमइया हर कनेक्सन अस्वीकार
Name[hr]=Korisnik odbija vezu
Name[hu]=A felhasználó elutasítja a csatlakozást
Name[ia]=Usator refuta connexion
Name[id]=Pengguna Menampik Koneksi
Name[is]=Notandi hafnar tengingum
Name[it]=L'utente rifiuta la connessione
Name[ja]=ユーザが接続を拒否
@@ -295,6 +299,7 @@ Comment[hne]=कमइया हर कनेक्सन अस्वीका
Comment[hr]=Korisnik odbija vezu
Comment[hu]=A felhasználó elutasítja a csatlakozást
Comment[ia]=Usator refuta connexion
Comment[id]=Pengguna menampik koneksi
Comment[is]=Notandi hafnar tengingu
Comment[it]=L'utente rifiuta la connessione
Comment[ja]=ユーザが接続を拒否
@@ -364,6 +369,7 @@ Name[hne]=कनेक्सन बन्द
Name[hr]=Veza prekinuta
Name[hu]=A kapcsolat megszűnt
Name[ia]=Connexion claudite
Name[id]=Koneksi Ditutup
Name[is]=Tengingu lokað
Name[it]=Connessione chiusa
Name[ja]=接続切断
@@ -431,6 +437,7 @@ Comment[hne]=कनेक्सन बन्द
Comment[hr]=Veza prekinuta
Comment[hu]=A kapcsolat megszűnt
Comment[ia]=Connexion claudite
Comment[id]=Koneksi ditutup
Comment[is]=Tengingu lokað
Comment[it]=Connessione chiusa
Comment[ja]=接続が閉じられました
@@ -497,12 +504,13 @@ Name[eu]=Baliogabeko pasahitza
Name[fi]=Virheellinen salasana
Name[fr]=Mot de passe non valable
Name[ga]=Focal Faire Neamhbhailí
Name[gl]=O contrasinal non é válido
Name[gl]=O contrasinal é incorrecto
Name[hi]=अवैध पासवर्ड
Name[hne]=अवैध पासवर्ड
Name[hr]=Nevažeća zaporka
Name[hu]=Érvénytelen jelszó
Name[ia]=Contrasigno invalide
Name[id]=Sandi Tidak Absah
Name[is]=Ógilt lykilorð
Name[it]=Password non valida
Name[ja]=無効なパスワード
@@ -563,13 +571,14 @@ Comment[eu]=Baliogabeko pasahitza
Comment[fi]=Virheellinen salasana
Comment[fr]=Mot de passe non valable
Comment[ga]=Focal faire neamhbhailí
Comment[gl]=Este contrasinal non é válido
Comment[gl]=Este contrasinal é incorrecto
Comment[he]=הסיסמה שגויה
Comment[hi]=अवैध पासवर्ड
Comment[hne]=अवैध पासवर्ड
Comment[hr]=Nevažeća šifra
Comment[hu]=Érvénytelen jelszó
Comment[ia]=Contrasigno invalide
Comment[id]=Sandi tidak absah
Comment[is]=Lykilorð ógilt
Comment[it]=Password non valida
Comment[ja]=無効なパスワード
@@ -638,12 +647,13 @@ Name[eu]=Gonbitearen pasahitza baliogabea
Name[fi]=Virheellinen salasana kutsuun
Name[fr]=Invitations de mots de passe non valables
Name[ga]=Cuirí Neamhbhailí Focal Faire
Name[gl]=O contrasinal de convidado non válido
Name[gl]=O contrasinal de convidado incorrecto
Name[hi]=अवैध पासवर्ड निमंत्रण
Name[hne]=अवैध पासवर्ड निमंत्रन
Name[hr]=Pozivnice s nevažećim zaporkama
Name[hu]=Érvénytelen jelszavas meghívó
Name[ia]=Invitationes de contrasigno invalide
Name[id]=Undangan Sandi Tidak Absah
Name[is]=Ógild lykilorðsboð
Name[it]=Password di invito non valida
Name[ja]=招待に対する無効なパスワード
@@ -701,13 +711,14 @@ Comment[eu]=Gonbidatutako parekoak baliogabeko pasahitza bidali du. Konexioa uka
Comment[fi]=Kutsuttu taho lähetti virheellisen salasanan. Yhteys hylättiin.
Comment[fr]=La partie invitée a envoyé un mot de passe non valable. Connexion refusée.
Comment[ga]=Sheol an duine le cuireadh focal faire neamhbhailí. Diúltaíodh an ceangal.
Comment[gl]=A parte convidada envioulle un contrasinal non válido. A conexión foi rexeitada.
Comment[gl]=A parte convidada envioulle un contrasinal incorrecto. Rexeitouse a conexión.
Comment[he]=הצד המוזמן שלח סיסמה שגויה. החיבור נדחה.
Comment[hi]=निमंत्रित पार्टी ने अवैध पासवर्ड भेजा. कनेक्शन अस्वीकृत.
Comment[hne]=निमंत्रित पार्टी हर अवैध पासवर्ड भेजिस. कनेक्सन अस्वीकृत.
Comment[hr]=Stranka koju ste pozvali je poslala nevažeću šifru. Veza odbijena.
Comment[hu]=A meghívott fél érvénytelen jelszót küldött. A csatlakozási kérés elutasítva.
Comment[ia]=Le partita invitate inviava un contrasigno invalide. Connexion refusate.
Comment[id]=Undangan mengirimkan sebuah sandi tidak absah. Koneksi ditampik.
Comment[is]=Boðinn aðili sendi ógilt lykilorð. Tengingu hafnað
Comment[it]=La parte invitata ha inviato una password non valida. Connessione rifiutata.
Comment[ja]=招待された人が無効なパスワードを送ってきました。接続を拒否しました。
@@ -775,6 +786,7 @@ Name[hne]=नवा कनेक्सन होल्ड मं रखा
Name[hr]=Nova veza na čekanju
Name[hu]=Új kapcsolat tartva
Name[ia]=Nove connexion in pausa
Name[id]=Koneksi Baru sedang Tertahan
Name[is]=Ný tenging á bið
Name[it]=Nuova connessione in attesa
Name[ja]=保留中の新しい接続
@@ -838,6 +850,7 @@ Comment[hne]=कनेक्सन निवेदित. कमइया ल
Comment[hr]=Veza je zatražena, korisnik mora prihvatiti
Comment[hu]=Csatlakozási kérés, a felhasználónak el kell fogadnia
Comment[ia]=Connexion requirite, usator debe dar acceptation
Comment[id]=Koneksi diminta, pengguna harus menyetujui
Comment[is]=Beiðni um tengingu, notandi verður að samþykkja
Comment[it]=Connessione richiesta, l'utente deve accettare
Comment[ja]=接続が要求されています。ユーザが許可しなければなりません。
@@ -906,6 +919,7 @@ Name[hne]=नय कनेक्सन अपने अपन स्वीका
Name[hr]=Nova veza automatski prihvaćena
Name[hu]=Új kapcsolat automatikusan engedélyezve
Name[ia]=Nove connexion con acceptation automatic
Name[id]=Koneksi Baru Tersetujui Otomatis
Name[is]=Ný tenging sjálfvirkt samþykkt
Name[it]=Nuova connessione accettata automaticamente
Name[ja]=新しい接続の自動受け入れ
@@ -969,6 +983,7 @@ Comment[hne]=नवा कनेक्सन अपने अपन स्था
Comment[hr]=Nova veza automatski prihvaćena
Comment[hu]=Automatikusan létrejött egy új kapcsolat
Comment[ia]=Nove connexion establite automaticamente
Comment[id]=Koneksi baru secara otomatis terpancang
Comment[is]=Nýjar tengingar sjálfkrafa samþykktar
Comment[it]=Nuova connessione stabilita automaticamente
Comment[ja]=新しい接続を自動的に確立しました
@@ -1037,6 +1052,7 @@ Name[hne]=बहुत अकन कनेक्सन
Name[hr]=Previše veza
Name[hu]=Túl sok kapcsolat
Name[ia]=Nimie connexiones
Name[id]=Terlalu Banyak Koneksi
Name[is]=Of margar tengingar
Name[it]=Troppe connessioni
Name[ja]=多すぎる接続
@@ -1094,13 +1110,14 @@ Comment[eu]=Lanpetuta, konexioa ukatu da
Comment[fi]=Varattu, yhteys hylättiin
Comment[fr]=Occupé. Connexion refusée
Comment[ga]=Gnóthach; ceangal diúltaithe
Comment[gl]=Ocupado; a conexión foi rexeitada
Comment[gl]=Ocupado, rexeitouse a conexión.
Comment[he]=תפוס, החיבור נדחה
Comment[hi]=व्यस्त, कनेक्शन अस्वीकृत
Comment[hne]=व्यस्त, कनेक्सन अस्वीकृत
Comment[hr]=Zauzeto, veza odbijena
Comment[hu]=A csatlakozási kérés elutasítva túlterhelés miatt
Comment[ia]=Occupate, connexion refusate
Comment[id]=Sibuk, koneksi ditampik
Comment[is]=Uptekinn, tengingu hafnað
Comment[it]=Occupato, connessione rifiutata
Comment[ja]=ビジーです、接続を拒否しました
@@ -1171,6 +1188,7 @@ Name[hne]=अप्रत्यासित कनेक्सन
Name[hr]=Neočekivana veza
Name[hu]=Nem várt kapcsolat
Name[ia]=Connexion impreviste
Name[id]=Koneksi Tak Terduga
Name[is]=Óvænt Tenging
Name[it]=Connessione inattesa
Name[ja]=予期しない接続
@@ -1235,6 +1253,7 @@ Comment[hne]=अप्रत्यासित कनेक्सन प्र
Comment[hr]=Primio sam neočekivanu vezu, prekid
Comment[hu]=Nem várt csatlakozási kérés érkezett, megszakítás
Comment[ia]=On recipeva connexion impreviste, aborta
Comment[id]=Diperoleh koneksi tak terduga, gugurkan
Comment[is]=Tók á móti óvæntri tengingu, hætti
Comment[it]=Ricevuta connessione inattesa, terminata
Comment[ja]=予期しない接続を受信しました。廃棄します。

View File

@@ -19,6 +19,7 @@
#include "trayicon.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "krfb_version.h"
#include <KAboutData>
#include <KDBusService>
@@ -35,7 +36,7 @@
#include <QCommandLineParser>
#include <QCommandLineOption>
static const char KRFB_VERSION[] = "5.0";
static const char description[] = I18N_NOOP("VNC-compatible server to share "
"desktops");
@@ -56,6 +57,21 @@ static bool checkX11Capabilities()
return true;
}
static void checkOldX11PluginConfig() {
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
qDebug() << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
QStringLiteral("preferredFrameBufferPlugin"));
if (config_item) {
config_item->setProperty(QStringLiteral("xcb"));
KrfbConfig::self()->save();
qDebug() << " Fixed preferredFrameBufferPlugin from x11 to xcb.";
}
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
@@ -63,10 +79,10 @@ int main(int argc, char *argv[])
KLocalizedString::setApplicationDomain("krfb");
KAboutData aboutData("krfb",
i18n("Desktop Sharing"),
KRFB_VERSION,
i18n("Desktop Sharing"),
QStringLiteral(KRFB_VERSION_STRING),
i18n(description),
KAboutLicense::GPL,
KAboutLicense::GPL,
i18n("(c) 2009-2010, Collabora Ltd.\n"
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
@@ -109,6 +125,9 @@ int main(int argc, char *argv[])
return 1;
}
// upgrade the configuration
checkOldX11PluginConfig();
//init the core
InvitationsRfbServer::init();

View File

@@ -13,6 +13,7 @@
#include "krfbconfig.h"
#include "ui_configtcp.h"
#include "ui_configsecurity.h"
#include "ui_configframebuffer.h"
#include <KConfigDialog>
#include <KLocalizedString>
@@ -21,12 +22,19 @@
#include <KActionCollection>
#include <KLineEdit>
#include <KNewPasswordDialog>
#include <KPluginLoader>
#include <KPluginMetaData>
#include <QIcon>
#include <QWidget>
#include <QLineEdit>
#include <QComboBox>
#include <QSizePolicy>
#include <QVector>
#include <QSet>
#include <QtNetwork/QNetworkInterface>
class TCP: public QWidget, public Ui::TCP
{
public:
@@ -43,6 +51,40 @@ public:
}
};
class ConfigFramebuffer: public QWidget, public Ui::Framebuffer
{
public:
ConfigFramebuffer(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
// hide the line edit with framebuffer string
kcfg_preferredFrameBufferPlugin->hide();
// fill drop-down combo with a list of real existing plugins
this->fillFrameBuffersCombo();
// initialize combo with currently configured framebuffer plugin
cb_preferredFrameBufferPlugin->setCurrentText(KrfbConfig::preferredFrameBufferPlugin());
// connect signals between combo<->lineedit
// if we change selection in combo, lineedit is updated
QObject::connect(cb_preferredFrameBufferPlugin, &QComboBox::currentTextChanged,
kcfg_preferredFrameBufferPlugin, &QLineEdit::setText);
}
void fillFrameBuffersCombo() {
const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(
QStringLiteral("krfb"), [](const KPluginMetaData & md) {
return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer"));
});
QSet<QString> unique;
QVectorIterator<KPluginMetaData> i(plugins);
i.toBack();
while (i.hasPrevious()) {
const KPluginMetaData &metadata = i.previous();
if (unique.contains(metadata.pluginId())) continue;
cb_preferredFrameBufferPlugin->addItem(metadata.pluginId());
unique.insert(metadata.pluginId());
}
}
};
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent)
@@ -183,14 +225,28 @@ void MainWindow::aboutUnattendedMode()
void MainWindow::showConfiguration()
{
static QString s_prevFramebufferPlugin;
// ^^ needs to be static, because lambda will be called long time
// after showConfiguration() ends, so auto variable would go out of scope
// save previously selected framebuffer plugin config
s_prevFramebufferPlugin = KrfbConfig::preferredFrameBufferPlugin();
if (KConfigDialog::showDialog("settings")) {
return;
}
KConfigDialog *dialog = new KConfigDialog(this, "settings", KrfbConfig::self());
dialog->addPage(new TCP, i18n("Network"), "network-workgroup");
dialog->addPage(new TCP, i18n("Network"), "network-wired");
dialog->addPage(new Security, i18n("Security"), "security-high");
dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), "video-display");
dialog->show();
connect(dialog, &KConfigDialog::settingsChanged, [this] () {
// check if framebuffer plugin config has changed
if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) {
KMessageBox::information(this, i18n("To apply framebuffer plugin setting, "
"you need to restart the program."));
}
});
}
void MainWindow::readProperties(const KConfigGroup& group)

View File

@@ -2,18 +2,29 @@
<component type="desktop">
<id>org.kde.krfb.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2+</project_license>
<project_license>GPL-2.0+</project_license>
<name>Krfb</name>
<name xml:lang="ast">Krfb</name>
<name xml:lang="ca">Krfb</name>
<name xml:lang="ca-valencia">Krfb</name>
<name xml:lang="cs">Krfb</name>
<name xml:lang="da">Krfb</name>
<name xml:lang="de">Krfb</name>
<name xml:lang="el">Krfb</name>
<name xml:lang="en-GB">Krfb</name>
<name xml:lang="es">Krfb</name>
<name xml:lang="fi">Krfb</name>
<name xml:lang="fr">Krfb</name>
<name xml:lang="gl">Krfb</name>
<name xml:lang="ia">Krfb</name>
<name xml:lang="id">Krfb</name>
<name xml:lang="it">Krfb</name>
<name xml:lang="ko">Krfb</name>
<name xml:lang="nl">Krfb</name>
<name xml:lang="pl">Krfb</name>
<name xml:lang="pt">Krfb</name>
<name xml:lang="pt-BR">Krfb</name>
<name xml:lang="ru">Krfb</name>
<name xml:lang="sk">Krfb</name>
<name xml:lang="sl">Krfb</name>
<name xml:lang="sr">КРФБ</name>
@@ -26,16 +37,27 @@
<name xml:lang="x-test">xxKrfbxx</name>
<name xml:lang="zh-CN">Krfb</name>
<summary>Desktop sharing</summary>
<summary xml:lang="ast">Compartición d'escritoriu</summary>
<summary xml:lang="ca">Compartició de l'escriptori</summary>
<summary xml:lang="ca-valencia">Compartició de l'escriptori</summary>
<summary xml:lang="cs">Sdílení pracovní plochy</summary>
<summary xml:lang="da">Skrivebordsdeling</summary>
<summary xml:lang="de">Freigabe der Arbeitsfläche</summary>
<summary xml:lang="el">Κοινή χρήση επιφάνειας εργασίας</summary>
<summary xml:lang="en-GB">Desktop sharing</summary>
<summary xml:lang="es">Compartir el escritorio</summary>
<summary xml:lang="fi">Työpöydän jako</summary>
<summary xml:lang="fr">Partage de bureau</summary>
<summary xml:lang="gl">Compartición do escritorio</summary>
<summary xml:lang="ia">Compartir de scriptorio</summary>
<summary xml:lang="id">Desktop sharing</summary>
<summary xml:lang="it">Condivisione del desktop</summary>
<summary xml:lang="ko">데스크톱 공유</summary>
<summary xml:lang="nl">Bureaublad delen</summary>
<summary xml:lang="pl">Współdzielenie pulpitu</summary>
<summary xml:lang="pt">Partilha do ecrã</summary>
<summary xml:lang="pt-BR">Compartilhamento de tela</summary>
<summary xml:lang="ru">Общий рабочий стол</summary>
<summary xml:lang="sk">Zdieľanie pracovnej plochy</summary>
<summary xml:lang="sl">Souporaba namizja</summary>
<summary xml:lang="sr">Дељење површи</summary>
@@ -49,15 +71,25 @@
<summary xml:lang="zh-CN">桌面共享</summary>
<description>
<p>Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.</p>
<p xml:lang="ast">Krfb ye una aplicación sirvidora que te permite compartir la to sesión actual con un usuariu n'otra máquina que puea usar un veceru VNC pa ver o controlar l'escritoriu.</p>
<p xml:lang="ca">El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.</p>
<p xml:lang="ca-valencia">El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.</p>
<p xml:lang="da">Krfb-skrivebordsdeling er et serverprogram der giver dig mulighed for at dele din nuværende session med en bruger på en anden maskine som kan bruge en VNC-klient til at vise eller endda styrer skrivebordet.</p>
<p xml:lang="de">Krfb ist eine Serveranwendung, welche die gemeinsame Benutzung der aktuellen Sitzung mit einem Benutzer auf einem anderen Rechner ermöglicht, der mit Hilfe eines VNC-Programms den Bildschirminhalt sehen oder sogar die Arbeitsfläche bedienen kann.</p>
<p xml:lang="el">Η κοινή χρήση επιφάνειας εργασίας Krfb είναι μια εφαρμογή εξυπηρετητή που σας επιτρέπει να μοιράζεστε την τρέχουσα συνεδρία σας με έναν χρήστη σε άλλο μηχάνημα, ο οποίος μπορεί να χρησιμοποιεί έναν πελάτη VNC για να παρακολουθεί ή και να ελέγχει την επιφάνεια εργασίας σας.</p>
<p xml:lang="en-GB">Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.</p>
<p xml:lang="es">Krfb para compartir el escritorio es una aplicación de servidor que le permite compartir su sesión actual con un usuario de otra máquina, que puede usar un cliente VNC para ver e incluso controlar su escritorio.</p>
<p xml:lang="fi">Krfb-työpöytäjako on palvelinsovellus, jolla voit jakaa nykyisen istuntosi toisen koneen käyttäjälle, joka voi VNC-asiakkaalla nähdä tai jopa hallita työpöytääsi.</p>
<p xml:lang="fr">Le partage de bureau Krfb est une application de serveur qui vous permet de partager votre session courante avec un utilisateur sur une autre machine, qui peut utiliser un client VNC pour afficher et même contrôler le bureau.</p>
<p xml:lang="gl">Krfb é un aplicativo de servidor que permite compartir a sesión actual cun usuario que está noutro equipo, que pode usar un cliente VNC para ver ou mesmo controlar o escritorio.</p>
<p xml:lang="id">Krfb Desktop Sharing adalah aplikasi server yang membolehkan Anda untuk berbagi sesi Anda saat ini dengan pengguna di mesin lain, yang bisa menggunakan klien VNC untuk menampilkan atau bahkan mengendalikan desktop.</p>
<p xml:lang="it">Condivisione del desktop Krfb è un'applicazione server che permette di condividere la sessione attuale con un utente su un'altra macchina, che potrà usare un client VNC per visualizzare ed anche controllare il desktop.</p>
<p xml:lang="ko">Krfb 데스크톱 공유는 현재 세션을 다른 머신의 사용자와 VNC를 통해서 공유하거나 원격 제어를 요청할 수 있는 서버 프로그램입니다.</p>
<p xml:lang="nl">Bureaublad delen is een server-applicatie die u in staat stelt uw huidige sessie te delen met een gebruiker op een andere machine, die een VNC-client kan gebruiken om uw bureaublad te bekijken of zelfs te besturen.</p>
<p xml:lang="pl">Współdzielenie pulpitu Krfb jest aplikacją serwerową, która umożliwia współdzielenie twojej bieżącej sesji z użytkownikiem na innym komputerze, który może użyć klienta VNC do oglądania,a a nawet sterowania twoim pulpitem.</p>
<p xml:lang="pt">A Partilha de Ecrã Krfb é uma aplicação de servidor que lhe permite partilhar a sua sessão actual com um utilizador noutra máquina, o qual poderá usar um cliente de VNC para ver ou mesmo controlar o ambiente de trabalho.</p>
<p xml:lang="pt-BR">Krfb Desktop Sharing é um aplicativo de servidor que lhe permite compartilhar a sua sessão atual com um usuário em outra máquina, que poderá usar um cliente de VNC para ver ou mesmo controlar a máquina.</p>
<p xml:lang="ru">Krfb является сервером, который позволяет вам предоставлять доступ к своему текущему сеансу пользователю на другом компьютере, который использует клиент VNC для просмотра или управления вашим рабочим столом.</p>
<p xml:lang="sk">Krfb je serverová aplikácia, ktorá vám umožní zdieľať vaše aktuálne sedenie s používateľom na inom stroji, ktorý môže používať VNC klienta na pripojenie alebo ovládanie stanice.</p>
<p xml:lang="sl">Souporaba namizja Krfb je strežniški program, ki vam dovoli, da delite vašo trenutno sejo z uporabnikom na drugem računalniku, ki ima odjemalec VNC. Uporabnik lahko gleda ali celo nadzira namizje.</p>
<p xml:lang="sr">КРФБ је серверски програм за дељење површи, којим можете да поделите своју текућу сесију са корисником на другој машини. Удаљени корисник може да употреби неки ВНЦ клијент за гледање површи, па чак и управљање њоме.</p>

View File

@@ -34,6 +34,7 @@ Name[hne]=केआरएफबी
Name[hr]=Krfb
Name[hu]=Krfb
Name[ia]=Krfb
Name[id]=Krfb
Name[is]=Krfb
Name[it]=Krfb
Name[ja]=Krfb
@@ -104,6 +105,7 @@ GenericName[hne]=डेस्कटाप साझेदारी
GenericName[hr]=Dijeljenje radne površine
GenericName[hu]=Munkaasztal-megosztás
GenericName[ia]=Compartir de scriptorio
GenericName[id]=Desktop Sharing
GenericName[is]=Skjáborðsmiðlun
GenericName[it]=Condivisione del desktop
GenericName[ja]=デスクトップ共有
@@ -174,6 +176,7 @@ Comment[hne]=डेस्कटाप साझेदारी
Comment[hr]=Dijeljenje radne površine
Comment[hu]=Munkaasztal-megosztás
Comment[ia]=Compartir de scriptorio
Comment[id]=Desktop Sharing
Comment[is]=Skjáborðamiðlun
Comment[it]=Condivisione del desktop
Comment[ja]=デスクトップ共有

View File

@@ -22,6 +22,7 @@
#include <QtCore/QSocketNotifier>
#include <QApplication>
#include <QClipboard>
#include <QPointer>
#include <QDebug>
struct RfbServer::Private
@@ -30,7 +31,8 @@ struct RfbServer::Private
int listeningPort;
bool passwordRequired;
rfbScreenInfoPtr screen;
QSocketNotifier *notifier;
QPointer<QSocketNotifier> ipv4notifier;
QPointer<QSocketNotifier> ipv6notifier;
};
RfbServer::RfbServer(QObject *parent)
@@ -40,7 +42,6 @@ RfbServer::RfbServer(QObject *parent)
d->listeningPort = 0;
d->passwordRequired = true;
d->screen = NULL;
d->notifier = NULL;
RfbServerManager::instance()->registerServer(this);
}
@@ -135,9 +136,13 @@ bool RfbServer::start()
return false;
};
d->notifier = new QSocketNotifier(d->screen->listenSock, QSocketNotifier::Read, this);
d->notifier->setEnabled(true);
connect(d->notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated);
d->ipv4notifier = new QSocketNotifier(d->screen->listenSock, QSocketNotifier::Read, this);
connect(d->ipv4notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated);
if (d->screen->listen6Sock > 0) {
// we're also listening on additional IPv6 socket, get events from there
d->ipv6notifier = new QSocketNotifier(d->screen->listen6Sock, QSocketNotifier::Read, this);
connect(d->ipv6notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated);
}
connect(QApplication::clipboard(), &QClipboard::dataChanged,
this, &RfbServer::krfbSendServerCutText);
@@ -148,10 +153,11 @@ void RfbServer::stop()
{
if (d->screen) {
rfbShutdownServer(d->screen, true);
if (d->notifier) {
d->notifier->setEnabled(false);
d->notifier->deleteLater();
d->notifier = NULL;
for (auto notifier : {d->ipv4notifier, d->ipv6notifier}) {
if (notifier) {
notifier->setEnabled(false);
notifier->deleteLater();
}
}
}
}

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Framebuffer</class>
<widget class="QWidget" name="Framebuffer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Framebuffer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Preferred frameb&amp;uffer plugin:</string>
</property>
<property name="buddy">
<cstring>cb_preferredFrameBufferPlugin</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cb_preferredFrameBufferPlugin">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="kcfg_preferredFrameBufferPlugin"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="helpText">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When using x11, &lt;span style=&quot; font-weight:600;&quot;&gt;xcb&lt;/span&gt; plugin should be preferred, because it is more performant.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;qt&lt;/span&gt; plugin is a safe fallback, if for some reason others don't work. But also it is very slow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>5</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>63</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>cb_preferredFrameBufferPlugin</tabstop>
<tabstop>kcfg_preferredFrameBufferPlugin</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>