This commit is contained in:
draekko 2023-02-21 05:48:53 -05:00 committed by GitHub
commit a9e9071ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 634 additions and 66 deletions

View File

@ -0,0 +1,7 @@
Adds clipboard memory limit for transfers between server/clients, the feature was documented
in wiki but missing in code. The feature can be set by using the spin box under the clipboard
checkbox in advanced settings.
The value used to limit clipboard size to transfer between client and sever is set in bytes
and can be set in the UI or throough the config file by setting the value in bytes with the
'clipboardSharingSize' tag.

View File

@ -52,6 +52,7 @@ ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows ,
m_IgnoreAutoConfigClient(false),
m_EnableDragAndDrop(false),
m_ClipboardSharing(true),
m_ClipboardSharingSize(defaultClipboardSharingSize()),
m_pMainWindow(mainWindow)
{
Q_ASSERT(m_pSettings);
@ -119,6 +120,7 @@ void ServerConfig::saveSettings()
settings().setValue("ignoreAutoConfigClient", ignoreAutoConfigClient());
settings().setValue("enableDragAndDrop", enableDragAndDrop());
settings().setValue("clipboardSharing", clipboardSharing());
settings().setValue("clipboardSharingSize", (int)clipboardSharingSize());
writeSettings<bool>(settings(), switchCorners(), "switchCorner");
@ -164,6 +166,8 @@ void ServerConfig::loadSettings()
setIgnoreAutoConfigClient(settings().value("ignoreAutoConfigClient").toBool());
setEnableDragAndDrop(settings().value("enableDragAndDrop", true).toBool());
setClipboardSharing(settings().value("clipboardSharing", true).toBool());
setClipboardSharingSize(settings().value("clipboardSharingSize",
(int) ServerConfig::defaultClipboardSharingSize()).toULongLong());
readSettings<bool>(settings(), switchCorners(), "switchCorner", false,
static_cast<int>(SwitchCorner::Count));
@ -412,3 +416,18 @@ void::ServerConfig::addToFirstEmptyGrid(const QString &clientName)
}
}
}
size_t ServerConfig::defaultClipboardSharingSize() {
return 100 * 1000 * 1000; // 100 MB
}
size_t ServerConfig::setClipboardSharingSize(size_t size) {
if (size) {
setClipboardSharing(true);
} else {
setClipboardSharing(false);
}
using std::swap;
swap (size, m_ClipboardSharingSize);
return size;
}

View File

@ -63,7 +63,9 @@ class ServerConfig : public BaseConfig
bool ignoreAutoConfigClient() const { return m_IgnoreAutoConfigClient; }
bool enableDragAndDrop() const { return m_EnableDragAndDrop; }
bool clipboardSharing() const { return m_ClipboardSharing; }
size_t clipboardSharingSize() const { return m_ClipboardSharingSize; }
static size_t defaultClipboardSharingSize();
void saveSettings();
void loadSettings();
bool save(const QString& fileName) const;
@ -92,6 +94,7 @@ class ServerConfig : public BaseConfig
void setIgnoreAutoConfigClient(bool on) { m_IgnoreAutoConfigClient = on; }
void setEnableDragAndDrop(bool on) { m_EnableDragAndDrop = on; }
void setClipboardSharing(bool on) { m_ClipboardSharing = on; }
size_t setClipboardSharingSize(size_t size);
QList<bool>& switchCorners() { return m_SwitchCorners; }
std::vector<Hotkey>& hotkeys() { return m_Hotkeys; }
@ -125,6 +128,7 @@ class ServerConfig : public BaseConfig
bool m_IgnoreAutoConfigClient;
bool m_EnableDragAndDrop;
bool m_ClipboardSharing;
size_t m_ClipboardSharingSize;
MainWindow* m_pMainWindow;
};

View File

@ -59,6 +59,8 @@ ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, co
m_pCheckBoxEnableDragAndDrop->setChecked(serverConfig().enableDragAndDrop());
m_pCheckBoxEnableClipboard->setChecked(serverConfig().clipboardSharing());
m_pSpinBoxClipboardSizeLimit->setValue(serverConfig().clipboardSharingSize());
m_pSpinBoxClipboardSizeLimit->setEnabled(serverConfig().clipboardSharing());
for (const Hotkey& hotkey : serverConfig().hotkeys()) {
m_pListHotkeys->addItem(hotkey.text());
@ -108,6 +110,7 @@ void ServerConfigDialog::accept()
serverConfig().setIgnoreAutoConfigClient(m_pCheckBoxIgnoreAutoConfigClient->isChecked());
serverConfig().setEnableDragAndDrop(m_pCheckBoxEnableDragAndDrop->isChecked());
serverConfig().setClipboardSharing(m_pCheckBoxEnableClipboard->isChecked());
serverConfig().setClipboardSharingSize(m_pSpinBoxClipboardSizeLimit->value());
// now that the dialog has been accepted, copy the new server config to the original one,
// which is a reference to the one in MainWindow.

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>795</width>
<height>534</height>
<width>816</width>
<height>580</height>
</rect>
</property>
<property name="windowTitle">
@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="m_pTabWidget">
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="m_pTabScreens">
<attribute name="title">
@ -44,7 +44,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="Barrier.qrc">:/res/icons/64x64/user-trash.png</pixmap>
<pixmap>:/res/icons/64x64/user-trash.png</pixmap>
</property>
</widget>
</item>
@ -82,7 +82,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="Barrier.qrc">:/res/icons/64x64/video-display.png</pixmap>
<pixmap>:/res/icons/64x64/video-display.png</pixmap>
</property>
</widget>
</item>
@ -422,13 +422,27 @@ Double click on a screen to edit its settings.</string>
<string>&amp;Options</string>
</property>
<layout class="QGridLayout">
<item row="3" column="0">
<widget class="QCheckBox" name="m_pCheckBoxWin32KeepForeground">
<item row="5" column="0">
<widget class="QCheckBox" name="m_pCheckBoxEnableDragAndDrop">
<property name="text">
<string>Enable drag and drop file transfers</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="m_pCheckBoxIgnoreAutoConfigClient">
<property name="text">
<string>Ignore auto config clients</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="m_pCheckBoxScreenSaverSync">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Don't take &amp;foreground window on Windows servers</string>
<string>S&amp;ynchronize screen savers</string>
</property>
</widget>
</item>
@ -442,13 +456,36 @@ Double click on a screen to edit its settings.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="m_pCheckBoxScreenSaverSync">
<item row="3" column="0">
<widget class="QCheckBox" name="m_pCheckBoxWin32KeepForeground">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>S&amp;ynchronize screen savers</string>
<string>Don't take &amp;foreground window on Windows servers</string>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
<property name="text">
<string>Enable clipboard sharing</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
@ -505,41 +542,23 @@ Double click on a screen to edit its settings.</string>
</item>
</layout>
</item>
<item row="7" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="m_pCheckBoxEnableDragAndDrop">
<property name="text">
<string>Enable drag and drop file transfers</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="m_pCheckBoxIgnoreAutoConfigClient">
<property name="text">
<string>Ignore auto config clients</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
<property name="text">
<string>Enable clipboard sharing</string>
</property>
<property name="checked">
<item row="8" column="0">
<widget class="QSpinBox" name="m_pSpinBoxClipboardSizeLimit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimum">
<number>1000000</number>
</property>
<property name="maximum">
<number>1000000000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="value">
<number>100000000</number>
</property>
</widget>
</item>
</layout>

View File

@ -58,8 +58,12 @@ public:
enum EFormat {
kText, //!< Text format, UTF-8, newline is LF
kHTML, //!< HTML format, HTML fragment, UTF-8, newline is LF
kBitmap, //!< Bitmap format, BMP 24/32bpp, BI_RGB
kNumFormats //!< The number of clipboard formats
kBitmap, //!< Bitmap format, BMP 24/32bpp, BI_RGB
kPNG, //!< PNG format
kJpeg, //!< JPEG format
kTiff, //!< TIFF format
kWebp, //!< WEBP format
kNumFormats //!< The number of clipboard formats
};
//! @name manipulators

View File

@ -68,6 +68,7 @@ static const OptionID kOptionScreenPreserveFocus = OPTION_CODE("SFOC")
static const OptionID kOptionRelativeMouseMoves = OPTION_CODE("MDLT");
static const OptionID kOptionWin32KeepForeground = OPTION_CODE("_KFW");
static const OptionID kOptionClipboardSharing = OPTION_CODE("CLPS");
static const OptionID kOptionClipboardSharingSize = OPTION_CODE("CLSZ");
//@}
//! @name Screen switch corner enumeration

View File

@ -70,7 +70,8 @@ Client::Client(IEventQueue* events, const std::string& name, const NetworkAddres
m_socket(NULL),
m_useSecureNetwork(args.m_enableCrypto),
m_args(args),
m_enableClipboard(true)
m_enableClipboard(true),
m_maximumClipboardSize(INT_MAX)
{
assert(m_socketFactory != NULL);
assert(m_screen != NULL);
@ -369,9 +370,20 @@ Client::setOptions(const OptionsList& options)
m_enableClipboard = *index;
break;
} else if (id == kOptionClipboardSharingSize) {
index++;
if (index != options.end()) {
m_maximumClipboardSize = *index;
}
}
}
if (m_enableClipboard && !m_maximumClipboardSize) {
m_enableClipboard = false;
LOG((CLOG_NOTE "clipboard sharing is disabled because the server "
"set the maximum clipboard size to 0"));
}
m_screen->setOptions(options);
}
@ -406,6 +418,12 @@ Client::sendClipboard(ClipboardID id)
// marshall the data
std::string data = clipboard.marshall();
if (data.size() >= m_maximumClipboardSize) {
LOG((CLOG_NOTE "Skipping clipboard transfer because the clipboard"
" contents exceeds the %i MB size limit set by the server",
m_maximumClipboardSize));
return;
}
// save and send data if different or not yet sent
if (!m_sentClipboard[id] || data != m_dataClipboard[id]) {
@ -660,7 +678,7 @@ Client::handleShapeChanged(const Event&, void*)
void
Client::handleClipboardGrabbed(const Event& event, void*)
{
if (!m_enableClipboard) {
if (!m_enableClipboard || (m_maximumClipboardSize == 0)) {
return;
}

View File

@ -224,4 +224,5 @@ private:
bool m_useSecureNetwork;
ClientArgs m_args;
bool m_enableClipboard;
size_t m_maximumClipboardSize;
};

View File

@ -23,6 +23,10 @@
#include "platform/XWindowsClipboardUTF8Converter.h"
#include "platform/XWindowsClipboardHTMLConverter.h"
#include "platform/XWindowsClipboardBMPConverter.h"
#include "platform/XWindowsClipboardJPGConverter.h"
#include "platform/XWindowsClipboardPNGConverter.h"
#include "platform/XWindowsClipboardTIFConverter.h"
#include "platform/XWindowsClipboardWEBPConverter.h"
#include "platform/XWindowsUtil.h"
#include "mt/Thread.h"
#include "arch/Arch.h"
@ -82,11 +86,15 @@ XWindowsClipboard::XWindowsClipboard(IXWindowsImpl* impl, Display* display,
}
// add converters, most desired first
m_converters.push_back(new XWindowsClipboardPNGConverter(m_display));
m_converters.push_back(new XWindowsClipboardWEBPConverter(m_display));
m_converters.push_back(new XWindowsClipboardJPGConverter(m_display));
m_converters.push_back(new XWindowsClipboardTIFConverter(m_display));
m_converters.push_back(new XWindowsClipboardBMPConverter(m_display));
m_converters.push_back(new XWindowsClipboardHTMLConverter(m_display,
"text/html"));
m_converters.push_back(new XWindowsClipboardHTMLConverter(m_display,
"application/x-moz-nativehtml"));
m_converters.push_back(new XWindowsClipboardBMPConverter(m_display));
m_converters.push_back(new XWindowsClipboardUTF8Converter(m_display,
"text/plain;charset=UTF-8"));
m_converters.push_back(new XWindowsClipboardUTF8Converter(m_display,
@ -545,31 +553,54 @@ XWindowsClipboard::icccmFillCache()
// available rather than checking TARGETS. i've seen clipboard
// owners that don't report all the targets they support.
target = converter->getAtom();
/*
#if 0
for (UInt32 i = 0; i < numTargets; ++i) {
if (converter->getAtom() == targets[i]) {
target = targets[i];
break;
}
}
*/
#endif
if (target == None) {
continue;
}
// get the data
Atom actualTarget;
IClipboard::EFormat format = converter->getFormat();
std::string targetData;
if (!icccmGetSelection(target, &actualTarget, &targetData)) {
LOG((CLOG_DEBUG1 " no data for target %s", XWindowsUtil::atomToString(m_display, target).c_str()));
m_added[format] = false;
continue;
}
if (actualTarget != target) {
LOG((CLOG_DEBUG1 " target %s not same as actual target %s",
XWindowsUtil::atomToString(m_display, target).c_str(),
XWindowsUtil::atomToString(m_display, actualTarget).c_str()));
m_added[format] = false;
continue;
}
if (targetData.empty()) {
m_added[format] = false;
LOG((CLOG_DEBUG1 " no targetdata for target %s (actual target %s)",
XWindowsUtil::atomToString(m_display, target).c_str(),
XWindowsUtil::atomToString(m_display, actualTarget).c_str()));
continue;
}
// add to clipboard and note we've done it
IClipboard::EFormat format = converter->getFormat();
m_data[format] = converter->toIClipboard(targetData);
m_added[format] = true;
LOG((CLOG_DEBUG "added format %d for target %s (%u %s)", format, XWindowsUtil::atomToString(m_display, target).c_str(), targetData.size(), targetData.size() == 1 ? "byte" : "bytes"));
if (!converter->toIClipboard(targetData).empty()) {
// add to clipboard and note we've done it
m_data[format] = converter->toIClipboard(targetData);
m_added[format] = true;
LOG((CLOG_DEBUG " added format %d for target %s (%u %s)", format, XWindowsUtil::atomToString(m_display, target).c_str(), targetData.size(), targetData.size() == 1 ? "byte" : "bytes"));
} else {
LOG((CLOG_DEBUG1 " no clipboard data for target %s", XWindowsUtil::atomToString(m_display, target).c_str()));
m_added[format] = false;
}
}
}
@ -799,17 +830,39 @@ XWindowsClipboard::motifFillCache()
// get the data (finally)
Atom actualTarget;
IClipboard::EFormat format = converter->getFormat();
std::string targetData;
if (!motifGetSelection(&motifFormat, &actualTarget, &targetData)) {
LOG((CLOG_DEBUG1 " no data for target %s", XWindowsUtil::atomToString(m_display, target).c_str()));
m_added[format] = false;
continue;
}
// add to clipboard and note we've done it
IClipboard::EFormat format = converter->getFormat();
m_data[format] = converter->toIClipboard(targetData);
m_added[format] = true;
LOG((CLOG_DEBUG "added format %d for target %s", format, XWindowsUtil::atomToString(m_display, target).c_str()));
if (actualTarget != target) {
LOG((CLOG_DEBUG1 " target %s not same as actual target %s",
XWindowsUtil::atomToString(m_display, target).c_str(),
XWindowsUtil::atomToString(m_display, actualTarget).c_str()));
m_added[format] = false;
continue;
}
if (targetData.empty()) {
m_added[format] = false;
LOG((CLOG_DEBUG1 " no targetdata for target %s (actual target %s)",
XWindowsUtil::atomToString(m_display, target).c_str(),
XWindowsUtil::atomToString(m_display, actualTarget).c_str()));
continue;
}
if (!converter->toIClipboard(targetData).empty()) {
// add to clipboard and note we've done it
m_data[format] = converter->toIClipboard(targetData);
m_added[format] = true;
LOG((CLOG_DEBUG " added format %d for target %s (%u %s)", format, XWindowsUtil::atomToString(m_display, target).c_str(), targetData.size(), targetData.size() == 1 ? "byte" : "bytes"));
} else {
LOG((CLOG_DEBUG1 " no clipboard data for target %s", XWindowsUtil::atomToString(m_display, target).c_str()));
m_added[format] = false;
}
}
}

View File

@ -161,6 +161,10 @@ std::string XWindowsClipboardAnyBitmapConverter::fromIClipboard(const std::strin
std::string XWindowsClipboardAnyBitmapConverter::toIClipboard(const std::string& image) const
{
if (image.empty()) {
return {};
}
// convert to raw BMP data
UInt32 w, h, depth;
std::string rawBMP = doToIClipboard(image, w, h, depth);

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/Log.h"
#include "platform/XWindowsClipboardBMPConverter.h"
// BMP file header structure
@ -103,6 +104,11 @@ XWindowsClipboardBMPConverter::getDataSize() const
std::string XWindowsClipboardBMPConverter::fromIClipboard(const std::string& bmp) const
{
if (bmp.size() <= 14 + 40) {
LOG((CLOG_DEBUG2 "fromIClipboard BMP, sized failed"));
return {};
}
// create BMP image
UInt8 header[14];
UInt8* dst = header;
@ -128,6 +134,8 @@ std::string XWindowsClipboardBMPConverter::toIClipboard(const std::string& bmp)
return {};
}
LOG((CLOG_DEBUG2 "Prepare BMP"));
// get offset to image data
UInt32 offset = fromLEU32(rawBMPHeader + 10);

View File

@ -61,6 +61,10 @@ std::string XWindowsClipboardHTMLConverter::fromIClipboard(const std::string& da
std::string XWindowsClipboardHTMLConverter::toIClipboard(const std::string& data) const
{
if (data.empty()) {
return {};
}
// Older Firefox [1] and possibly other applications use UTF-16 for text/html - handle both
// [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1497580
if (Unicode::isUTF8(data)) {

View File

@ -0,0 +1,40 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/XWindowsClipboard.h"
//! Convert to/from some text encoding
class XWindowsClipboardJPGConverter :
public IXWindowsClipboardConverter {
public:
XWindowsClipboardJPGConverter(Display* display);
virtual ~XWindowsClipboardJPGConverter();
// IXWindowsClipboardConverter overrides
virtual IClipboard::EFormat
getFormat() const;
virtual Atom getAtom() const;
virtual int getDataSize() const;
virtual std::string fromIClipboard(const std::string&) const;
virtual std::string toIClipboard(const std::string&) const;
private:
Atom m_atom;
};

View File

@ -0,0 +1,72 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/Log.h"
#include "platform/XWindowsClipboardPNGConverter.h"
//
// XWindowsClipboardPNGConverter
//
XWindowsClipboardPNGConverter::XWindowsClipboardPNGConverter(
Display* display) :
m_atom(XInternAtom(display, "image/png", False))
{
// do nothing
}
XWindowsClipboardPNGConverter::~XWindowsClipboardPNGConverter()
{
// do nothing
}
IClipboard::EFormat
XWindowsClipboardPNGConverter::getFormat() const
{
return IClipboard::kPNG;
}
Atom
XWindowsClipboardPNGConverter::getAtom() const
{
return m_atom;
}
int
XWindowsClipboardPNGConverter::getDataSize() const
{
return 8;
}
std::string XWindowsClipboardPNGConverter::fromIClipboard(const std::string& pngdata) const
{
return pngdata;
}
std::string XWindowsClipboardPNGConverter::toIClipboard(const std::string& pngdata) const
{
// check PNG file header
const UInt8* rawPNGHeader = reinterpret_cast<const UInt8*>(pngdata.data());
if (rawPNGHeader[0] == 0x89 && rawPNGHeader[1] == 0x50 && rawPNGHeader[2] == 0x4e && rawPNGHeader[3] == 0x47) {
LOG((CLOG_DEBUG2 "Prepare PNG"));
return pngdata;
}
return {};
}

View File

@ -0,0 +1,40 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/XWindowsClipboard.h"
//! Convert to/from some text encoding
class XWindowsClipboardPNGConverter :
public IXWindowsClipboardConverter {
public:
XWindowsClipboardPNGConverter(Display* display);
virtual ~XWindowsClipboardPNGConverter();
// IXWindowsClipboardConverter overrides
virtual IClipboard::EFormat
getFormat() const;
virtual Atom getAtom() const;
virtual int getDataSize() const;
virtual std::string fromIClipboard(const std::string&) const;
virtual std::string toIClipboard(const std::string&) const;
private:
Atom m_atom;
};

View File

@ -0,0 +1,77 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/Log.h"
#include "platform/XWindowsClipboardTIFConverter.h"
//
// XWindowsClipboardTIFConverter
//
XWindowsClipboardTIFConverter::XWindowsClipboardTIFConverter(
Display* display) :
m_atom(XInternAtom(display, "image/tiff", False))
{
// do nothing
}
XWindowsClipboardTIFConverter::~XWindowsClipboardTIFConverter()
{
// do nothing
}
IClipboard::EFormat
XWindowsClipboardTIFConverter::getFormat() const
{
return IClipboard::kTiff;
}
Atom
XWindowsClipboardTIFConverter::getAtom() const
{
return m_atom;
}
int
XWindowsClipboardTIFConverter::getDataSize() const
{
return 8;
}
std::string XWindowsClipboardTIFConverter::fromIClipboard(const std::string& tiffdata) const
{
return tiffdata;
}
std::string XWindowsClipboardTIFConverter::toIClipboard(const std::string& tiffdata) const
{
// check TIFF file header, veirfy if Big or Little Endian
const UInt8* rawTIFHeader = reinterpret_cast<const UInt8*>(tiffdata.data());
if (rawTIFHeader[0] == 0x49 && rawTIFHeader[1] == 0x49 && rawTIFHeader[2] == 0x2a && rawTIFHeader[3] == 0x00) {
LOG((CLOG_DEBUG2 "Prepare Tiff (BE)"));
return tiffdata;
}
if (rawTIFHeader[0] == 0x4D && rawTIFHeader[1] == 0x4D && rawTIFHeader[2] == 0x00 && rawTIFHeader[3] == 0x2a) {
LOG((CLOG_DEBUG2 "Prepare Tiff (LE)"));
return tiffdata;
}
return {};
}

View File

@ -0,0 +1,40 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/XWindowsClipboard.h"
//! Convert to/from some text encoding
class XWindowsClipboardTIFConverter :
public IXWindowsClipboardConverter {
public:
XWindowsClipboardTIFConverter(Display* display);
virtual ~XWindowsClipboardTIFConverter();
// IXWindowsClipboardConverter overrides
virtual IClipboard::EFormat
getFormat() const;
virtual Atom getAtom() const;
virtual int getDataSize() const;
virtual std::string fromIClipboard(const std::string&) const;
virtual std::string toIClipboard(const std::string&) const;
private:
Atom m_atom;
};

View File

@ -61,6 +61,10 @@ std::string XWindowsClipboardTextConverter::fromIClipboard(const std::string& da
std::string XWindowsClipboardTextConverter::toIClipboard(const std::string& data) const
{
if (data.empty()) {
return {};
}
// convert to UTF-8
bool errors;
std::string utf8 = Unicode::textToUTF8(data, &errors);

View File

@ -61,5 +61,9 @@ std::string XWindowsClipboardUCS2Converter::fromIClipboard(const std::string& da
std::string XWindowsClipboardUCS2Converter::toIClipboard(const std::string& data) const
{
if (data.empty()) {
return {};
}
return Unicode::UCS2ToUTF8(data);
}

View File

@ -59,5 +59,9 @@ std::string XWindowsClipboardUTF8Converter::fromIClipboard(const std::string& da
std::string XWindowsClipboardUTF8Converter::toIClipboard(const std::string& data) const
{
if (data.empty()) {
return {};
}
return data;
}

View File

@ -0,0 +1,73 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/Log.h"
#include "platform/XWindowsClipboardWEBPConverter.h"
//
// XWindowsClipboardWEBPConverter
//
XWindowsClipboardWEBPConverter::XWindowsClipboardWEBPConverter(
Display* display) :
m_atom(XInternAtom(display, "image/webp", False))
{
// do nothing
}
XWindowsClipboardWEBPConverter::~XWindowsClipboardWEBPConverter()
{
// do nothing
}
IClipboard::EFormat
XWindowsClipboardWEBPConverter::getFormat() const
{
return IClipboard::kWebp;
}
Atom
XWindowsClipboardWEBPConverter::getAtom() const
{
return m_atom;
}
int
XWindowsClipboardWEBPConverter::getDataSize() const
{
return 8;
}
std::string XWindowsClipboardWEBPConverter::fromIClipboard(const std::string& webpdata) const
{
return webpdata;
}
std::string XWindowsClipboardWEBPConverter::toIClipboard(const std::string& webpdata) const
{
// check WEBPF file header, veirfy if Big or Little Endian
const UInt8* rawWEBPHeader = reinterpret_cast<const UInt8*>(webpdata.data());
if (rawWEBPHeader[0] == 'R' && rawWEBPHeader[1] == 'I' && rawWEBPHeader[2] == 'F' && rawWEBPHeader[3] == 'F' &&
rawWEBPHeader[8] == 'W' && rawWEBPHeader[9] == 'E' && rawWEBPHeader[10] == 'B' && rawWEBPHeader[11] == 'P' ) {
LOG((CLOG_DEBUG2 "Prepare WEBP"));
return webpdata;
}
return {};
}

View File

@ -0,0 +1,40 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2004 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package 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. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/XWindowsClipboard.h"
//! Convert to/from some text encoding
class XWindowsClipboardWEBPConverter :
public IXWindowsClipboardConverter {
public:
XWindowsClipboardWEBPConverter(Display* display);
virtual ~XWindowsClipboardWEBPConverter();
// IXWindowsClipboardConverter overrides
virtual IClipboard::EFormat
getFormat() const;
virtual Atom getAtom() const;
virtual int getDataSize() const;
virtual std::string fromIClipboard(const std::string&) const;
virtual std::string toIClipboard(const std::string&) const;
private:
Atom m_atom;
};

View File

@ -1812,9 +1812,11 @@ XWindowsUtil::ErrorLock::internalHandler(Display* display, XErrorEvent* event)
}
void
XWindowsUtil::ErrorLock::ignoreHandler(Display*, XErrorEvent* e, void*)
XWindowsUtil::ErrorLock::ignoreHandler(Display* display, XErrorEvent* e, void*)
{
LOG((CLOG_DEBUG1 "ignoring X error: %d", e->error_code));
char errtxt[1024];
XGetErrorText(display, e->error_code, errtxt, 1023);
LOG((CLOG_DEBUG1 "ignoring X error: %d - %.1023s", e->error_code, errtxt));
}
void

View File

@ -744,6 +744,9 @@ Config::readSectionOptions(ConfigReadContext& s)
else if (name == "clipboardSharing") {
addOption("", kOptionClipboardSharing, s.parseBoolean(value));
}
else if (name == "clipboardSharingSize") {
addOption("", kOptionClipboardSharingSize, s.parseInt(value));
}
else {
handled = false;
@ -1360,6 +1363,9 @@ Config::getOptionName(OptionID id)
if (id == kOptionClipboardSharing) {
return "clipboardSharing";
}
if (id == kOptionClipboardSharingSize) {
return "clipboardSharingSize";
}
return NULL;
}
@ -1376,7 +1382,8 @@ std::string Config::getOptionValue(OptionID id, OptionValue value)
id == kOptionRelativeMouseMoves ||
id == kOptionWin32KeepForeground ||
id == kOptionScreenPreserveFocus ||
id == kOptionClipboardSharing) {
id == kOptionClipboardSharing ||
id == kOptionClipboardSharingSize) {
return (value != 0) ? "true" : "false";
}
if (id == kOptionModifierMapForShift ||

View File

@ -90,6 +90,7 @@ Server::Server(
m_writeToDropDirThread(NULL),
m_ignoreFileTransfer(false),
m_enableClipboard(true),
m_maximumClipboardSize(INT_MAX),
m_sendDragInfoThread(NULL),
m_waitDragInfoThread(true),
m_args(args)
@ -511,6 +512,10 @@ Server::switchScreen(BaseClientProxy* dst,
if (m_enableClipboard) {
// send the clipboard data to new active screen
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
// Hackity hackity hack
if (m_clipboards[id].m_clipboard.marshall().size() > m_maximumClipboardSize) {
continue;
}
m_active->setClipboard(id, &m_clipboards[id].m_clipboard);
}
}
@ -1177,6 +1182,15 @@ Server::processOptions()
LOG((CLOG_NOTE "clipboard sharing is disabled"));
}
}
else if (id == kOptionClipboardSharingSize) {
if (value <= 0) {
m_maximumClipboardSize = 0;
LOG((CLOG_NOTE "clipboard sharing is disabled because the "
"maximum shared clipboard size is set to 0"));
} else {
m_maximumClipboardSize = static_cast<size_t>(value);
}
}
}
if (m_relativeMoves && !newRelativeMoves) {
stopRelativeMoves();
@ -1220,7 +1234,7 @@ Server::handleShapeChanged(const Event&, void* vclient)
void
Server::handleClipboardGrabbed(const Event& event, void* vclient)
{
if (!m_enableClipboard) {
if (!m_enableClipboard || (m_maximumClipboardSize == 0)) {
return;
}
@ -1553,6 +1567,11 @@ Server::onClipboardChanged(BaseClientProxy* sender,
// ignore if data hasn't changed
std::string data = clipboard.m_clipboard.marshall();
if (data.size() > m_maximumClipboardSize) {
LOG((CLOG_NOTE "not updating clipboard because it's over the size limit (%i KB) configured by the server",
m_maximumClipboardSize));
return;
}
if (data == clipboard.m_clipboardData) {
LOG((CLOG_DEBUG "ignored screen \"%s\" update of clipboard %d (unchanged)", clipboard.m_clipboardOwner.c_str(), id));
return;

View File

@ -475,6 +475,7 @@ private:
std::string m_dragFileExt;
bool m_ignoreFileTransfer;
bool m_enableClipboard;
size_t m_maximumClipboardSize;
Thread* m_sendDragInfoThread;
bool m_waitDragInfoThread;