Commit c7170918 authored by Alexander Maret-Huskinson's avatar Alexander Maret-Huskinson
Browse files

Adds support to invert the scroll direction of the touch device.

The user can now invert the scroll direction of the touch device again.
BUG: 309911
parent e30a3689
......@@ -138,6 +138,32 @@ bool X11InputDevice::getAtomProperty(const QString& property, QList< long int >&
}
const QList< int > X11InputDevice::getDeviceButtonMapping() const
{
Q_D(const X11InputDevice);
QList<int> buttonMap;
if (!isOpen()) {
return buttonMap;
}
static const int nmap = 100; // maximum number of buttons this method will fetch
unsigned char map_return[nmap];
int buttonCount = 0;
if ((buttonCount = XGetDeviceButtonMapping(d->display, d->device, map_return, nmap)) <= 0) {
return buttonMap; // the device has no buttons
}
for (int i = 0 ; i < buttonCount ; ++i) {
buttonMap.append((int)map_return[i]);
}
return buttonMap;
}
long X11InputDevice::getDeviceId() const
{
......@@ -314,6 +340,30 @@ bool X11InputDevice::open(Display* display, X11InputDevice::XID id, const QStrin
bool X11InputDevice::setDeviceButtonMapping(const QList< int >& buttonMap) const
{
Q_D(const X11InputDevice);
if (!isOpen() || buttonMap.count() == 0) {
return false;
}
const int nmap = buttonMap.count();
unsigned char* map = new unsigned char[nmap];
for (int i = 0 ; i < nmap ; ++i) {
map[i] = (unsigned char)buttonMap.at(i);
}
int result = XSetDeviceButtonMapping(d->display, d->device, map, nmap);
delete map;
return (result == MappingSuccess);
}
bool X11InputDevice::setFloatProperty(const QString& property, const QString& values) const
{
QStringList valueList = values.split (QLatin1String(" "));
......
......@@ -102,6 +102,13 @@ public:
*/
bool getAtomProperty (const QString& property, QList<long>& values, long nelements = 1) const;
/**
* Gets the button map of the device.
*
* @return A list of buttons numbers.
*/
const QList<int> getDeviceButtonMapping() const;
/**
* Gets the device id of this device.
*
......@@ -198,6 +205,16 @@ public:
*/
bool open (Display* display, XID id, const QString& name);
/**
* Sets a button mapping on the device. The parameter \a buttonMap has
* to contain as many values as returned by \a getDeviceButtonMapping().
*
* @param buttonMap The new button map for the device.
*
* @return True on success, false on error.
*/
bool setDeviceButtonMapping(const QList<int>& buttonMap) const;
/**
* Sets a float property. The values have to be separated by a single whitespace.
*
......
......@@ -84,6 +84,24 @@ const QRect X11Wacom::getMaximumTabletArea(const QString& deviceName)
}
bool X11Wacom::isScrollDirectionInverted(const QString& deviceName)
{
X11InputDevice device;
if (!X11Input::findDevice(deviceName, device)) {
return false;
}
QList<int> buttonMap = device.getDeviceButtonMapping();
if (buttonMap.count() == 0 || buttonMap.count() < 5) {
return false;
}
return (buttonMap.at(3) == 5 && buttonMap.at(4) == 4);
}
bool X11Wacom::setCoordinateTransformationMatrix(const QString& deviceName, qreal offsetX, qreal offsetY, qreal width, qreal height)
{
X11InputDevice device;
......@@ -112,4 +130,28 @@ bool X11Wacom::setCoordinateTransformationMatrix(const QString& deviceName, qrea
}
bool X11Wacom::setScrollDirection(const QString& deviceName, bool inverted)
{
X11InputDevice device;
if (!X11Input::findDevice(deviceName, device)) {
return false;
}
QList<int> buttonMap = device.getDeviceButtonMapping();
if (buttonMap.count() == 0 || buttonMap.count() < 5) {
return false;
}
if (inverted) {
buttonMap[3] = 5;
buttonMap[4] = 4;
} else {
buttonMap[3] = 4;
buttonMap[4] = 5;
}
return device.setDeviceButtonMapping(buttonMap);
}
......@@ -45,6 +45,14 @@ public:
*/
static const QRect getMaximumTabletArea(const QString& deviceName);
/**
* Checks if the current scroll direction is inverted.
*
* @param deviceName The device to query.
*
* @return True if it is inverted, else false.
*/
static bool isScrollDirectionInverted(const QString& deviceName);
/**
* Sets the coordinate transformation property on the given device.
......@@ -53,6 +61,16 @@ public:
*/
static bool setCoordinateTransformationMatrix(const QString& deviceName, qreal offsetX, qreal offsetY, qreal width, qreal height);
/**
* Sets the scroll direction on a device.
*
* @param deviceName The xinput device name of the touch device.
* @param inverted If true, the scroll direction is inverted.
*
* @return True on success, false on error.
*/
static bool setScrollDirection(const QString& deviceName, bool inverted = false);
}; // CLASS
} // NAMESPACE
......
......@@ -86,6 +86,7 @@ void TouchPageWidget::loadFromProfile()
setTabletAreaMapping( touchProfile.getProperty( Property::ScreenMap ) );
setGesturesSupportEnabled( touchProfile.getPropertyAsBool( Property::Gesture ) );
setScrollDistance( touchProfile.getProperty( Property::ScrollDistance ) );
setScrollInversion( touchProfile.getProperty( Property::InvertScroll) );
setZoomDistance( touchProfile.getProperty( Property::ZoomDistance ) );
setTapTime( touchProfile.getProperty( Property::TapTime ) );
}
......@@ -126,6 +127,7 @@ void TouchPageWidget::saveToProfile()
touchProfile.setProperty ( Property::ScreenMap, getTabletAreaMapping() );
touchProfile.setProperty ( Property::Gesture, getGestureSupportEnabled() );
touchProfile.setProperty ( Property::ScrollDistance, getScrollDistance() );
touchProfile.setProperty ( Property::InvertScroll, getScrollInversion() );
touchProfile.setProperty ( Property::ZoomDistance, getZoomDistance() );
touchProfile.setProperty ( Property::TapTime, getTapTime() );
......@@ -213,6 +215,14 @@ const QString TouchPageWidget::getScrollDistance() const
}
const QString TouchPageWidget::getScrollInversion() const
{
Q_D (const TouchPageWidget);
return (d->ui->scrollInversionCheckBox->isChecked() ? QLatin1String("on") : QLatin1String("off"));
}
const QString& TouchPageWidget::getTabletAreaMapping() const
{
Q_D (const TouchPageWidget);
......@@ -300,6 +310,16 @@ void TouchPageWidget::setScrollDistance(const QString& value)
}
void TouchPageWidget::setScrollInversion(const QString& value)
{
Q_D(TouchPageWidget);
d->ui->scrollInversionCheckBox->blockSignals(true);
d->ui->scrollInversionCheckBox->setChecked(StringUtils::asBool(value));
d->ui->scrollInversionCheckBox->blockSignals(false);
}
void TouchPageWidget::setTouchSupportEnabled(bool value)
{
Q_D (TouchPageWidget);
......
......@@ -121,6 +121,13 @@ protected:
*/
const QString getScrollDistance() const;
/**
* Gets the current state of the scroll inversion checkbox as string.
*
* @return Either "on" or "off".
*/
const QString getScrollInversion() const;
/**
* Gets the current tablet area mapping in profile format.
* Possible return values are:
......@@ -198,6 +205,13 @@ protected:
*/
void setScrollDistance(const QString& value);
/**
* Sets the value of the scroll inversion checkbox.
*
* @param value Either "on" or "off" or empty string.
*/
void setScrollInversion(const QString& value);
/**
* Sets a new tablet area mapping and updates all widgets accordingly.
* The given value has to be in profile format. Valid values are:
......
......@@ -160,11 +160,17 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Gestures</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<item row="2" column="0">
<widget class="QLabel" name="scrollDistanceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
......@@ -183,7 +189,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="2" column="1">
<widget class="QSpinBox" name="scrollDistanceSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
......@@ -191,6 +197,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The minimum motion in tablet units before sending a scroll event.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
......@@ -199,7 +208,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="3" column="0">
<widget class="QLabel" name="zoomDistanceLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
......@@ -218,7 +227,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="zoomDistanceSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
......@@ -226,6 +235,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>The minimum distance in tablet units for a zoom gesture to be recognized.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
......@@ -234,7 +246,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="4" column="0">
<widget class="QLabel" name="tapTimeLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
......@@ -253,8 +265,11 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="4" column="1">
<widget class="QSpinBox" name="tapTimeSpinBox">
<property name="toolTip">
<string>The minimum time in milliseconds between taps to trigger a right click.</string>
</property>
<property name="maximum">
<number>1000</number>
</property>
......@@ -263,11 +278,35 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="scrollInversionLabel">
<property name="text">
<string>Invert Scroll Direction</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="scrollInversionCheckBox">
<property name="toolTip">
<string>If selected, the scroll direction for the scroll gesture is inverted.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="dummyWidget" native="true"/>
<widget class="QWidget" name="dummyWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
......@@ -422,6 +461,22 @@
</hint>
</hints>
</connection>
<connection>
<sender>scrollInversionCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>TouchPageWidget</receiver>
<slot>onProfileChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>143</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>271</x>
<y>167</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onTouchModeChanged(int)</slot>
......
......@@ -120,6 +120,8 @@ bool XinputAdaptor::supportsProperty(const Property& property) const
const QString XinputAdaptor::getProperty(const XinputProperty& property) const
{
Q_D( const XinputAdaptor );
if (property == XinputProperty::CursorAccelProfile) {
return getLongProperty (property);
......@@ -132,6 +134,9 @@ const QString XinputAdaptor::getProperty(const XinputProperty& property) const
} else if (property == XinputProperty::CursorAccelVelocityScaling) {
return getFloatProperty (property);
} else if (property == XinputProperty::InvertScroll) {
return (X11Wacom::isScrollDirectionInverted(d->deviceName) ? QLatin1String("on") : QLatin1String("off"));
} else {
kError() << QString::fromLatin1("Getting Xinput property '%1' is not yet implemented!").arg(property.key());
}
......@@ -278,6 +283,9 @@ bool XinputAdaptor::setProperty (const XinputProperty& property, const QString&
} else if (property == XinputProperty::CursorAccelVelocityScaling) {
return d->device.setFloatProperty (property.key(), value);
} else if (property == XinputProperty::InvertScroll) {
return X11Wacom::setScrollDirection(d->deviceName, StringUtils::asBool(value));
} else if (property == XinputProperty::ScreenSpace) {
return mapTabletToScreen (value);
......
......@@ -32,4 +32,5 @@ const XinputProperty XinputProperty::CursorAccelProfile ( Property:
const XinputProperty XinputProperty::CursorAccelConstantDeceleration ( Property::CursorAccelConstantDeceleration, QLatin1String("Device Accel Constant Deceleration") );
const XinputProperty XinputProperty::CursorAccelAdaptiveDeceleration ( Property::CursorAccelAdaptiveDeceleration, QLatin1String("Device Accel Adaptive Deceleration") );
const XinputProperty XinputProperty::CursorAccelVelocityScaling ( Property::CursorAccelVelocityScaling, QLatin1String("Device Accel Velocity Scaling") );
const XinputProperty XinputProperty::InvertScroll ( Property::InvertScroll, QLatin1String("Invert Scroll") );
const XinputProperty XinputProperty::ScreenSpace ( Property::ScreenSpace, QLatin1String("Coordinate Transformation Matrix") );
......@@ -42,6 +42,7 @@ public:
static const XinputProperty CursorAccelConstantDeceleration;
static const XinputProperty CursorAccelAdaptiveDeceleration;
static const XinputProperty CursorAccelVelocityScaling;
static const XinputProperty InvertScroll;
static const XinputProperty ScreenSpace;
private:
......
......@@ -107,10 +107,7 @@ bool XsetwacomAdaptor::setProperty(const Property& property, const QString& valu
}
// check for special property
if (property == Property::InvertScroll) {
return setInvertScroll(value);
} else if (property == Property::Rotate) {
if (property == Property::Rotate) {
return setRotation(value);
} else {
......@@ -208,22 +205,6 @@ const QString XsetwacomAdaptor::getParameter(const QString& device, const QStrin
bool XsetwacomAdaptor::setInvertScroll(const QString& value)
{
Q_D( const XsetwacomAdaptor );
if (StringUtils::asBool(value)) {
setParameter(d->device, XsetwacomProperty::Button4.key(), QLatin1String("5"));
setParameter(d->device, XsetwacomProperty::Button5.key(), QLatin1String("4"));
} else {
setParameter(d->device, XsetwacomProperty::Button5.key(), QLatin1String("4"));
setParameter(d->device, XsetwacomProperty::Button4.key(), QLatin1String("5"));
}
return true;
}
bool XsetwacomAdaptor::setRotation(const QString& value)
{
Q_D( const XsetwacomAdaptor );
......
......@@ -113,11 +113,6 @@ private:
*/
const QString getParameter(const QString& device, const QString& param) const;
/**
* Inverts scrolling or sets it back to normal.
*/
bool setInvertScroll(const QString& value);
/**
* Sets the tablet rotation.
*/
......
......@@ -41,13 +41,13 @@ const XsetwacomProperty XsetwacomProperty::Button9 ( Property::Button9,
const XsetwacomProperty XsetwacomProperty::Button10 ( Property::Button10, QLatin1String("Button 10") );
const XsetwacomProperty XsetwacomProperty::CursorProximity ( Property::CursorProximity, QLatin1String("CursorProximity") );
const XsetwacomProperty XsetwacomProperty::Gesture ( Property::Gesture, QLatin1String("Gesture") );
const XsetwacomProperty XsetwacomProperty::MapToOutput ( Property::MapToOutput, QLatin1String("MapToOutput") );
const XsetwacomProperty XsetwacomProperty::Mode ( Property::Mode, QLatin1String("Mode") );
const XsetwacomProperty XsetwacomProperty::PressureCurve ( Property::PressureCurve, QLatin1String("PressureCurve") );
const XsetwacomProperty XsetwacomProperty::RawSample ( Property::RawSample, QLatin1String("RawSample") );
const XsetwacomProperty XsetwacomProperty::RelWheelDown ( Property::RelWheelDown, QLatin1String("RelWheelDown") );
const XsetwacomProperty XsetwacomProperty::RelWheelUp ( Property::RelWheelUp, QLatin1String("RelWheelUp") );
const XsetwacomProperty XsetwacomProperty::Rotate ( Property::Rotate, QLatin1String("Rotate") );
const XsetwacomProperty XsetwacomProperty::MapToOutput ( Property::MapToOutput, QLatin1String("MapToOutput") ); // needs to be done after rotation
const XsetwacomProperty XsetwacomProperty::ScrollDistance ( Property::ScrollDistance, QLatin1String("ScrollDistance") );
const XsetwacomProperty XsetwacomProperty::StripLeftDown ( Property::StripLeftDown, QLatin1String("StripLeftDown") );
const XsetwacomProperty XsetwacomProperty::StripLeftUp ( Property::StripLeftUp, QLatin1String("StripLeftUp") );
......@@ -63,4 +63,3 @@ const XsetwacomProperty XsetwacomProperty::AbsWheel2Down ( Property::AbsWheel
const XsetwacomProperty XsetwacomProperty::AbsWheel2Up ( Property::AbsWheel2Up, QLatin1String("AbsWheel2Up") );
const XsetwacomProperty XsetwacomProperty::AbsWheelDown ( Property::AbsWheelDown, QLatin1String("AbsWheelDown") );
const XsetwacomProperty XsetwacomProperty::AbsWheelUp ( Property::AbsWheelUp, QLatin1String("AbsWheelUp") );
const XsetwacomProperty XsetwacomProperty::InvertScroll ( Property::InvertScroll, QLatin1String("InvertScroll") );
......@@ -55,7 +55,6 @@ public:
static const XsetwacomProperty Button10;
static const XsetwacomProperty CursorProximity;
static const XsetwacomProperty Gesture;
static const XsetwacomProperty InvertScroll;
static const XsetwacomProperty MapToOutput;
static const XsetwacomProperty Mode;
static const XsetwacomProperty PressureCurve;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment