Fetch stylus button remapping from WinTab driver
The user can remap the stylus buttons using tablet driver settings. This information is available to the application via CSR_SYSBTNMAP WinTab feature. We should fetch this information every time the stylus gets into proximity, because the user can change these settings on the fly. Change-Id: Idc839905c3485179d782814f78fa862fd4a99127 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
parent
050e7bafad
commit
a5725561da
@ -435,6 +435,27 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
|
|||||||
m_currentDevice = m_devices.size();
|
m_currentDevice = m_devices.size();
|
||||||
m_devices.push_back(tabletInit(uniqueId, cursorType));
|
m_devices.push_back(tabletInit(uniqueId, cursorType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We should check button map for changes on every proximity event, not
|
||||||
|
* only during initialization phase.
|
||||||
|
*
|
||||||
|
* WARNING: in 2016 there were some Wacom table drivers, which could mess up
|
||||||
|
* button mapping if the remapped button was pressed, while the
|
||||||
|
* application **didn't have input focus**. This bug is somehow
|
||||||
|
* related to the fact that Wacom drivers allow user to configure
|
||||||
|
* per-application button-mappings. If the bug shows up again,
|
||||||
|
* just move this button-map fetching into initialization block.
|
||||||
|
*
|
||||||
|
* See https://bugs.kde.org/show_bug.cgi?id=359561
|
||||||
|
*/
|
||||||
|
BYTE logicalButtons[32];
|
||||||
|
memset(logicalButtons, 0, 32);
|
||||||
|
m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_SYSBTNMAP, &logicalButtons);
|
||||||
|
m_devices[m_currentDevice].buttonsMap[0x1] = logicalButtons[0];
|
||||||
|
m_devices[m_currentDevice].buttonsMap[0x2] = logicalButtons[1];
|
||||||
|
m_devices[m_currentDevice].buttonsMap[0x4] = logicalButtons[2];
|
||||||
|
|
||||||
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
|
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
|
||||||
m_state = PenProximity;
|
m_state = PenProximity;
|
||||||
qCDebug(lcQpaTablet) << "enter proximity for device #"
|
qCDebug(lcQpaTablet) << "enter proximity for device #"
|
||||||
@ -446,6 +467,52 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::MouseButton buttonValueToEnum(DWORD button,
|
||||||
|
const QWindowsTabletDeviceData &tdd) {
|
||||||
|
|
||||||
|
enum : unsigned {
|
||||||
|
leftButtonValue = 0x1,
|
||||||
|
middleButtonValue = 0x2,
|
||||||
|
rightButtonValue = 0x4,
|
||||||
|
doubleClickButtonValue = 0x7
|
||||||
|
};
|
||||||
|
|
||||||
|
button = tdd.buttonsMap.value(button);
|
||||||
|
|
||||||
|
return button == leftButtonValue ? Qt::LeftButton :
|
||||||
|
button == rightButtonValue ? Qt::RightButton :
|
||||||
|
button == doubleClickButtonValue ? Qt::MiddleButton :
|
||||||
|
button == middleButtonValue ? Qt::MiddleButton :
|
||||||
|
button ? Qt::LeftButton /* fallback item */ :
|
||||||
|
Qt::NoButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::MouseButtons convertTabletButtons(DWORD btnNew,
|
||||||
|
const QWindowsTabletDeviceData &tdd) {
|
||||||
|
|
||||||
|
Qt::MouseButtons buttons = Qt::NoButton;
|
||||||
|
for (unsigned int i = 0; i < 3; i++) {
|
||||||
|
unsigned int btn = 0x1 << i;
|
||||||
|
|
||||||
|
if (btn & btnNew) {
|
||||||
|
Qt::MouseButton convertedButton =
|
||||||
|
buttonValueToEnum(btn, tdd);
|
||||||
|
|
||||||
|
buttons |= convertedButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a button that is present in hardware input is
|
||||||
|
* mapped to a Qt::NoButton, it means that it is going
|
||||||
|
* to be eaten by the driver, for example by its
|
||||||
|
* "Pan/Scroll" feature. Therefore we shouldn't handle
|
||||||
|
* any of the events associated to it. We'll just return
|
||||||
|
* Qt::NoButtons here.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
bool QWindowsTabletSupport::translateTabletPacketEvent()
|
bool QWindowsTabletSupport::translateTabletPacketEvent()
|
||||||
{
|
{
|
||||||
static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
|
static PACKET localPacketBuf[TabletPacketQSize]; // our own tablet packet queue.
|
||||||
@ -552,9 +619,12 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
|
|||||||
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
|
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::MouseButtons buttons =
|
||||||
|
convertTabletButtons(packet.pkButtons, m_devices.at(m_currentDevice));
|
||||||
|
|
||||||
QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
|
QWindowSystemInterface::handleTabletEvent(target, packet.pkTime, QPointF(localPos), globalPosF,
|
||||||
currentDevice, currentPointer,
|
currentDevice, currentPointer,
|
||||||
static_cast<Qt::MouseButtons>(packet.pkButtons),
|
buttons,
|
||||||
pressureNew, tiltX, tiltY,
|
pressureNew, tiltX, tiltY,
|
||||||
tangentialPressure, rotation, z,
|
tangentialPressure, rotation, z,
|
||||||
uniqueId,
|
uniqueId,
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
#include <QtCore/qvector.h>
|
#include <QtCore/qvector.h>
|
||||||
#include <QtCore/qpoint.h>
|
#include <QtCore/qpoint.h>
|
||||||
|
#include <QtCore/qhash.h>
|
||||||
|
|
||||||
#include <wintab.h>
|
#include <wintab.h>
|
||||||
|
|
||||||
@ -100,6 +101,7 @@ struct QWindowsTabletDeviceData
|
|||||||
qint64 uniqueId = 0;
|
qint64 uniqueId = 0;
|
||||||
int currentDevice = 0;
|
int currentDevice = 0;
|
||||||
int currentPointerType = 0;
|
int currentPointerType = 0;
|
||||||
|
QHash<quint8, quint8> buttonsMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
|
Loading…
Reference in New Issue
Block a user