diff --git a/src/common/screenspace.cpp b/src/common/screenspace.cpp
index f1c2160..e543ca1 100644
--- a/src/common/screenspace.cpp
+++ b/src/common/screenspace.cpp
@@ -1,168 +1,186 @@
/*
* This file is part of the KDE wacomtablet project. For copyright
* information and license terms see the AUTHORS and COPYING files
* in the top-level directory of this distribution.
*
* 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. If not, see .
*/
#include "screenspace.h"
#include "logging.h"
#include "x11info.h"
using namespace Wacom;
namespace Wacom
{
static const QString DESKTOP_STRING = QLatin1String("desktop");
static const QString AREA_STRING = QLatin1String("area");
static const QString SPEED_STRING = QLatin1String("speed");
}
ScreenSpace::ScreenSpace()
{
}
ScreenSpace::ScreenSpace(const QString &screenSpaceString)
{
if (screenSpaceString == DESKTOP_STRING) {
_type = ScreenSpaceType::Desktop;
return;
}
QStringList tokens = screenSpaceString.split(QChar::fromLatin1('x'));
if (tokens.size() == 5 && tokens.at(0) == AREA_STRING) {
_type = ScreenSpaceType::Area;
_area = QRect(
tokens.at(1).toInt(),
tokens.at(2).toInt(),
tokens.at(3).toInt(),
tokens.at(4).toInt()
);
return;
}
if (tokens.size() == 3 && tokens.at(0) == SPEED_STRING) {
_type = ScreenSpaceType::ArbitraryTranslationMatrix;
_speed = QPointF(
tokens.at(1).toDouble(),
tokens.at(2).toDouble()
);
return;
}
_type = ScreenSpaceType::Output;
_output = screenSpaceString;
}
ScreenSpace::~ScreenSpace()
{
}
bool ScreenSpace::operator==(const ScreenSpace& screenSpace) const
{
if (getType() != screenSpace.getType())
return false;
switch (getType()) {
case Wacom::ScreenSpace::ScreenSpaceType::Output:
return _output == screenSpace._output;
case Wacom::ScreenSpace::ScreenSpaceType::Area:
return _area == screenSpace._area;
case Wacom::ScreenSpace::ScreenSpaceType::ArbitraryTranslationMatrix:
return _speed == screenSpace._speed;
case Wacom::ScreenSpace::ScreenSpaceType::Desktop:
default:
return true;
}
}
const ScreenSpace ScreenSpace::desktop()
{
return ScreenSpace(DESKTOP_STRING);
}
bool ScreenSpace::isDesktop() const
{
return _type == ScreenSpaceType::Desktop;
}
bool ScreenSpace::isMonitor() const
{
return _type == ScreenSpaceType::Output;
}
const ScreenSpace ScreenSpace::monitor(QString output)
{
return ScreenSpace(output);
}
const QString ScreenSpace::toString() const
{
switch (getType()) {
case ScreenSpaceType::Desktop:
return DESKTOP_STRING;
case ScreenSpaceType::Output:
return _output;
case ScreenSpaceType::Area:
return QString::fromLatin1("%1x%2x%3x%4x%5")
.arg(AREA_STRING).arg(_area.left()).arg(_area.top()).arg(_area.width()).arg(_area.height());
case ScreenSpaceType::ArbitraryTranslationMatrix:
return QString::fromLatin1("%1x%2x%3")
.arg(SPEED_STRING).arg(_speed.x()).arg(_speed.y());
default:
qCDebug(COMMON) << "Broken ScreenSpace serialized";
return DESKTOP_STRING;
}
}
+QRect ScreenSpace::toScreenGeometry() const
+{
+ switch (getType()) {
+ case ScreenSpaceType::Output:
+ {
+ const auto screenList = X11Info::getScreenGeometries();
+ return screenList.contains(toString()) ? screenList.value(toString()) : QRect();
+ }
+ case ScreenSpaceType::Area:
+ return getArea();
+ case ScreenSpaceType::Desktop:
+ return X11Info::getDisplayGeometry();
+ case ScreenSpaceType::ArbitraryTranslationMatrix:
+ default:
+ return QRect();
+ }
+}
+
ScreenSpace ScreenSpace::next() const
{
ScreenSpace nextScreen = ScreenSpace::desktop();
if (getType() != ScreenSpaceType::Output) {
nextScreen = ScreenSpace::monitor(X11Info::getPrimaryScreenName());
} else {
auto nextScreenName = X11Info::getNextScreenName(toString());
if (nextScreenName == X11Info::getPrimaryScreenName()) {
nextScreen = ScreenSpace::desktop();
} else {
nextScreen = ScreenSpace::monitor(nextScreenName);
}
}
return nextScreen;
}
ScreenSpace::ScreenSpaceType ScreenSpace::getType() const
{
return _type;
}
QPointF ScreenSpace::getSpeed() const
{
return _speed;
}
QRect ScreenSpace::getArea() const
{
return _area;
}
diff --git a/src/common/screenspace.h b/src/common/screenspace.h
index c5fa1c3..6ecc32f 100644
--- a/src/common/screenspace.h
+++ b/src/common/screenspace.h
@@ -1,85 +1,95 @@
/*
* This file is part of the KDE wacomtablet project. For copyright
* information and license terms see the AUTHORS and COPYING files
* in the top-level directory of this distribution.
*
* 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. If not, see .
*/
#ifndef SCREENSPACE_H
#define SCREENSPACE_H
#include
#include
namespace Wacom
{
/**
* @brief Specifies screen area that is used for mapping
*
* Stores either "desktop", specific output, arbitrary area
* or translation matrix (for relative mode).
* When set as a device property, is converted into translation matrix.
*/
class ScreenSpace
{
public:
enum class ScreenSpaceType {
Desktop,
Output,
Area,
ArbitraryTranslationMatrix,
};
ScreenSpace();
ScreenSpace(const QString& screenSpaceString);
virtual ~ScreenSpace();
bool operator== (const ScreenSpace& screenSpace) const;
static const ScreenSpace desktop();
bool isDesktop() const;
bool isMonitor() const;
static const ScreenSpace monitor(QString output);
const QString toString() const;
+ /**
+ * @brief Converts ScreenSpace to corresponding geometry
+ *
+ * For example, if it's set to output DVI-1, returns geometry of the screen
+ * connected to DVI-1
+ *
+ * Returns empty rectangle on error
+ */
+ QRect toScreenGeometry() const;
+
/**
* This function allows to cycle through all existing screen spaces in a loop,
* which means every individual connected screen and "desktop" (whole screen)
*
* @return Next ScreenSpace after this
*/
ScreenSpace next() const;
ScreenSpaceType getType() const;
QPointF getSpeed() const;
QRect getArea() const;
private:
ScreenSpaceType _type = ScreenSpaceType::Desktop;
QString _output;
QRect _area;
QPointF _speed;
}; // CLASS
} // NAMESPACE
#endif // HEADER PROTECTION
diff --git a/src/kcmodule/kcmwacomtabletwidget.ui b/src/kcmodule/kcmwacomtabletwidget.ui
index 8c252ab..f51a6d0 100644
--- a/src/kcmodule/kcmwacomtabletwidget.ui
+++ b/src/kcmodule/kcmwacomtabletwidget.ui
@@ -1,130 +1,118 @@
KCMWacomTabletWidget
0
0
646
522
Graphic Tablet Settings
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
+
+
-
&Select Tablet:
tabletListSelector
- -
+
-
0
0
-
-
- -
-
-
-
+
-
Select &Profile:
profileSelector
- -
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- Creates a new default profile
-
-
-
-
-
- Qt::ToolButtonIconOnly
-
-
- document-new
-
-
-
- -
-
-
- Deletes the current profile
-
-
- edit-delete-page
-
-
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Creates a new default profile
+
+
+
+
+
+ Qt::ToolButtonIconOnly
+
+
+ document-new
+
+
+
+ -
+
+
+ Deletes the current profile
+
+
+ edit-delete-page
+
+
+
+
-
true
KAnimatedButton
QToolButton
profileSelector
addProfileButton
delProfileButton
deviceTabWidget
diff --git a/src/kded/xsetwacomadaptor.cpp b/src/kded/xsetwacomadaptor.cpp
index 6b0a645..4389739 100644
--- a/src/kded/xsetwacomadaptor.cpp
+++ b/src/kded/xsetwacomadaptor.cpp
@@ -1,273 +1,273 @@
/*
* This file is part of the KDE wacomtablet project. For copyright
* information and license terms see the AUTHORS and COPYING files
* in the top-level directory of this distribution.
*
* 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. If not, see .
*/
#include "xsetwacomadaptor.h"
#include "logging.h"
#include "xsetwacomproperty.h"
#include "stringutils.h"
#include "buttonshortcut.h"
#include "screenrotation.h"
#include "tabletarea.h"
#include
#include
using namespace Wacom;
namespace Wacom {
class XsetwacomAdaptorPrivate
{
public:
QMap buttonMap;
QString device;
}; // CLASS
} // NAMESPACE
XsetwacomAdaptor::XsetwacomAdaptor(const QString& deviceName)
: PropertyAdaptor(nullptr), d_ptr(new XsetwacomAdaptorPrivate)
{
Q_D( XsetwacomAdaptor );
d->device = deviceName;
}
XsetwacomAdaptor::XsetwacomAdaptor(const QString& deviceName, const QMap< QString, QString >& buttonMap)
: PropertyAdaptor(nullptr), d_ptr(new XsetwacomAdaptorPrivate)
{
Q_D( XsetwacomAdaptor );
d->buttonMap = buttonMap;
d->device = deviceName;
}
XsetwacomAdaptor::~XsetwacomAdaptor()
{
delete this->d_ptr;
}
const QList< Property > XsetwacomAdaptor::getProperties() const
{
return XsetwacomProperty::ids();
}
const QString XsetwacomAdaptor::getProperty(const Property& property) const
{
Q_D( const XsetwacomAdaptor );
const XsetwacomProperty *xsetproperty = XsetwacomProperty::map(property);
if (!xsetproperty) {
qCWarning(KDED) << QString::fromLatin1("Can not get unsupported property '%1' using xsetwacom!").arg(property.key());
return QString();
}
// TODO: get invert scroll parameter
QString convertedParam = convertParameter (*xsetproperty);
QString xsetwacomValue = getParameter (d->device, convertedParam);
// convert value to a unified format
convertFromXsetwacomValue (*xsetproperty, xsetwacomValue);
qCDebug(KDED) << QString::fromLatin1("Reading property '%1' from device '%2' -> '%3'.").arg(property.key()).arg(d->device).arg(xsetwacomValue);
return xsetwacomValue;
}
bool XsetwacomAdaptor::setProperty(const Property& property, const QString& value)
{
Q_D( const XsetwacomAdaptor );
qCDebug(KDED) << QString::fromLatin1("Setting property '%1' to '%2' on device '%3'.").arg(property.key()).arg(value).arg(d->device);
const XsetwacomProperty *xsetproperty = XsetwacomProperty::map(property);
if (!xsetproperty) {
qCWarning(KDED) << QString::fromLatin1("Can not set unsupported property '%1' to '%2' on device '%3' using xsetwacom!").arg(property.key()).arg(value).arg(d->device);
return false;
}
// check for properties which need special handling
if (property == Property::Area) {
return setArea(value);
}else if (property == Property::Rotate) {
return setRotation(value);
} else {
// normal property
QString convertedParam = convertParameter(*xsetproperty);
QString convertedValue = value;
convertToXsetwacomValue(*xsetproperty, convertedValue);
return setParameter(d->device, convertedParam, convertedValue);
}
return false;
}
bool XsetwacomAdaptor::supportsProperty(const Property& property) const
{
return (XsetwacomProperty::map(property) != nullptr);
}
const QString XsetwacomAdaptor::convertParameter(const XsetwacomProperty& param) const
{
Q_D( const XsetwacomAdaptor );
QString modifiedParam = param.key();
// convert tablet button number to hardware button number
QRegExp rx(QLatin1String("^Button\\s*([0-9]+)$"), Qt::CaseInsensitive);
if (rx.indexIn(modifiedParam, 0) != -1) {
QString hwButtonNumber = rx.cap(1);
QString kernelButtonNumber;
if (!d->buttonMap.isEmpty()) {
kernelButtonNumber = d->buttonMap.value(hwButtonNumber);
}
if (kernelButtonNumber.isEmpty()) {
kernelButtonNumber = hwButtonNumber;
}
- //qCDebug(KDED) << QString::fromLatin1("Mapping tablet button %1 to X11 button %2.").arg(hwButtonNumber).arg(kernelButtonNumber);
+ qCDebug(KDED) << QString::fromLatin1("Mapping tablet button %1 to X11 button %2.").arg(hwButtonNumber).arg(kernelButtonNumber);
modifiedParam = QString(QLatin1String("Button %1")).arg(kernelButtonNumber);
}
return modifiedParam;
}
void XsetwacomAdaptor::convertButtonShortcut (const XsetwacomProperty& property, QString& value) const
{
QRegExp rx (QLatin1String("^Button\\s*[0-9]+$"), Qt::CaseInsensitive);
if (rx.indexIn(property.key(), 0) != -1) {
ButtonShortcut buttonshortcut(value);
value = buttonshortcut.toString();
}
}
void XsetwacomAdaptor::convertFromXsetwacomValue(const XsetwacomProperty& property, QString& value) const
{
// convert button shortcuts to a unified format
convertButtonShortcut(property, value);
}
void XsetwacomAdaptor::convertToXsetwacomValue(const XsetwacomProperty& property, QString& value) const
{
// convert button shortcuts to a unified format
convertButtonShortcut(property, value);
}
const QString XsetwacomAdaptor::getParameter(const QString& device, const QString& param) const
{
QString cmd = QString::fromLatin1( "xsetwacom get \"%1\" %2" ).arg( device ).arg( param );
QProcess getConf;
getConf.start( cmd );
if( !getConf.waitForStarted() || !getConf.waitForFinished() ) {
return QString();
}
QString result = QLatin1String( getConf.readAll() );
return result.remove( QLatin1Char( '\n' ) );
}
bool XsetwacomAdaptor::setArea(const QString& value)
{
Q_D( const XsetwacomAdaptor );
TabletArea area(value);
if ( area.isEmpty() ) {
return setParameter(d->device, XsetwacomProperty::ResetArea.key(), QString());
}
return setParameter(d->device, XsetwacomProperty::Area.key(), area.toString());
}
bool XsetwacomAdaptor::setRotation(const QString& value)
{
Q_D( const XsetwacomAdaptor );
const ScreenRotation* lookup = ScreenRotation::find(value);
ScreenRotation rotation = lookup ? *lookup : ScreenRotation::NONE;
// only accept real rotations
if (rotation == ScreenRotation::NONE || rotation == ScreenRotation::CW ||
rotation == ScreenRotation::CCW || rotation == ScreenRotation::HALF) {
setParameter(d->device, XsetwacomProperty::Rotate.key(), rotation.key());
return true;
}
// do not set this value as it is not a real screen rotation
// probably some auto-mode.
return false;
}
bool XsetwacomAdaptor::setParameter(const QString& device, const QString& param, const QString& value) const
{
QString cmd;
if (value.isEmpty()) {
cmd = QString::fromLatin1( "xsetwacom set \"%1\" %2" ).arg( device ).arg( param );
} else {
cmd = QString::fromLatin1( "xsetwacom set \"%1\" %2 \"%3\"" ).arg( device ).arg( param ).arg( value );
}
QProcess setConf;
setConf.start( cmd );
if( !setConf.waitForStarted() || !setConf.waitForFinished()) {
return false;
}
QByteArray errorOutput = setConf.readAll();
if( !errorOutput.isEmpty() ) {
qCDebug(KDED) << cmd << " : " << errorOutput;
return false;
}
return true;
}