Warning, /graphics/krita/3rdparty/ext_qt/0026-Fetch-mapped-screen-size-from-the-Wintab-driver.patch is written in an unsupported language. File is not indexed.

0001 From 59dcf9d1c5ba650e354e1c858a445ff44b8dd235 Mon Sep 17 00:00:00 2001
0002 From: Dmitry Kazakov <dimula73@gmail.com>
0003 Date: Sat, 13 Apr 2019 23:24:01 +0300
0004 Subject: [PATCH 07/47] Fetch mapped screen size from the Wintab driver
0005 
0006 Some devices, like Microsoft Surface Pro 5, don't map tablet's
0007 input range to the entire virtual screen area, but map it to
0008 the primary display that has actual built-in tablet sensor.
0009 
0010 In such cases we should fetch actualy mapped aread from Wintab's
0011 lcSys{Org,Ext}{X,Y} fields and use it for cursor mapping.
0012 
0013 If one wants to fall back to the old screen size detection method,
0014 then an environment variable can be set:
0015 
0016 QT_IGNORE_WINTAB_MAPPING=1
0017 
0018 When the variable is set, the scaling is done via virtual desktop
0019 area only.
0020 
0021 If the tablet driver is broken (e.g. Microsoft SP5, when primary
0022 display is set to an external monitor) the user might want to override
0023 mapping completely. Then the following variable can be used:
0024 
0025 QT_WINTAB_DESKTOP_RECT=x;y;width;height
0026 
0027 Change-Id: Idd8bcf0323ce0811d2ad8976eaed48ad13ac3af8
0028 ---
0029  .../windows/qwindowstabletsupport.cpp         | 89 ++++++++++++++++++-
0030  .../platforms/windows/qwindowstabletsupport.h | 13 ++-
0031  2 files changed, 99 insertions(+), 3 deletions(-)
0032 
0033 diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
0034 index 6a9fe28e75..15820533c4 100644
0035 --- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
0036 +++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
0037 @@ -53,6 +53,7 @@
0038  #include <QtCore/qdebug.h>
0039  #include <QtCore/qvarlengtharray.h>
0040  #include <QtCore/qmath.h>
0041 +#include <QtCore/qregularexpression.h>
0042  
0043  #include <private/qguiapplication_p.h>
0044  #include <QtCore/private/qsystemlibrary_p.h>
0045 @@ -216,6 +217,10 @@ QWindowsTabletSupport::QWindowsTabletSupport(HWND window, HCTX context)
0046      // Some tablets don't support tilt, check if it is possible,
0047      if (QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEVICES, DVC_ORIENTATION, &orientation))
0048          m_tiltSupport = orientation[0].axResolution && orientation[1].axResolution;
0049 +
0050 +    connect(qGuiApp, &QGuiApplication::primaryScreenChanged,
0051 +            this, &QWindowsTabletSupport::slotPrimaryScreenChanged);
0052 +    slotScreenGeometryChanged();
0053  }
0054  
0055  QWindowsTabletSupport::~QWindowsTabletSupport()
0056 @@ -394,6 +399,84 @@ QWindowsTabletDeviceData QWindowsTabletSupport::tabletInit(qint64 uniqueId, UINT
0057      return result;
0058  }
0059  
0060 +void QWindowsTabletSupport::slotPrimaryScreenChanged(QScreen *screen)
0061 +{
0062 +    if (m_connectedScreen)
0063 +        disconnect(m_connectedScreen, 0, this, 0);
0064 +
0065 +    m_connectedScreen = screen;
0066 +
0067 +    if (m_connectedScreen)
0068 +        connect(m_connectedScreen, &QScreen::virtualGeometryChanged,
0069 +                this, &QWindowsTabletSupport::slotScreenGeometryChanged);
0070 +
0071 +    slotScreenGeometryChanged();
0072 +}
0073 +
0074 +void QWindowsTabletSupport::slotScreenGeometryChanged()
0075 +{
0076 +    /**
0077 +     * Some Wintab implementations map the tablet area to the entire
0078 +     * virtual screen, but others (e.g. Microsoft SP5) don't. They
0079 +     * may input range to a single (built-in) screen. The logic is
0080 +     * quite obvious: when the screen has integrated tablet device,
0081 +     * one cannot map this tablet device to another display.
0082 +     *
0083 +     * For such devices, we should always request mapped area from
0084 +     * lcSys{Org,Ext}{X,Y} fields and use it accordingly.
0085 +     */
0086 +
0087 +    LOGCONTEXT lc;
0088 +    QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_DEFSYSCTX, 0, &lc);
0089 +    m_wintabScreenGeometry = QRect(lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY);
0090 +
0091 +    qCDebug(lcQpaTablet) << "Updated tablet mapping: " << m_wintabScreenGeometry;
0092 +    if (QGuiApplication::primaryScreen()) {
0093 +        qCDebug(lcQpaTablet) << "   real desktop geometry: " << QWindowsScreen::virtualGeometry(QGuiApplication::primaryScreen()->handle());
0094 +    }
0095 +}
0096 +
0097 +void QWindowsTabletSupport::updateEffectiveScreenGeometry()
0098 +{
0099 +    QRect customGeometry;
0100 +    bool dontUseWintabDesktopRect = false;
0101 +
0102 +    const QString geometry = qEnvironmentVariable("QT_WINTAB_DESKTOP_RECT");
0103 +    if (!geometry.isEmpty()) {
0104 +        QString tmp = QString::fromLatin1("([+-]?\\d+);([+-]?\\d+);(\\d+);(\\d+)");
0105 +
0106 +        QRegularExpression rex(tmp);
0107 +        QRegularExpressionMatch match = rex.match(geometry);
0108 +
0109 +        if (match.hasMatch()) {
0110 +            customGeometry.setRect(match.captured(1).toInt(),
0111 +                                   match.captured(2).toInt(),
0112 +                                   match.captured(3).toInt(),
0113 +                                   match.captured(4).toInt());
0114 +
0115 +            qCDebug(lcQpaTablet) << "apply QT_WINTAB_DESKTOP_RECT:" << customGeometry;
0116 +        } else {
0117 +            qCWarning(lcQpaTablet) << "failed to parse QT_WINTAB_DESKTOP_RECT:" << geometry;
0118 +        }
0119 +    }
0120 +
0121 +    if (qEnvironmentVariableIsSet("QT_IGNORE_WINTAB_MAPPING")) {
0122 +        if (!customGeometry.isValid()) {
0123 +            qCDebug(lcQpaTablet) << "fallback mapping is requested via QT_IGNORE_WINTAB_MAPPING";
0124 +        } else {
0125 +            qCWarning(lcQpaTablet) << "ignoring QT_IGNORE_WINTAB_MAPPING, because QT_WINTAB_DESKTOP_RECT is set";
0126 +        }
0127 +        dontUseWintabDesktopRect = true;
0128 +    }
0129 +
0130 +    m_effectiveScreenGeometry =
0131 +        !customGeometry.isValid() ?
0132 +        (dontUseWintabDesktopRect ?
0133 +             QWindowsScreen::virtualGeometry(QGuiApplication::primaryScreen()->handle()) :
0134 +             m_wintabScreenGeometry) :
0135 +        customGeometry;
0136 +}
0137 +
0138  bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, LPARAM lParam)
0139  {
0140      PACKET proximityBuffer[1]; // we are only interested in the first packet in this case
0141 @@ -421,6 +504,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
0142      if (!totalPacks)
0143          return false;
0144  
0145 +    updateEffectiveScreenGeometry();
0146 +
0147      const UINT currentCursor = proximityBuffer[0].pkCursor;
0148      UINT physicalCursorId;
0149      QWindowsTabletSupport::m_winTab32DLL.wTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &physicalCursorId);
0150 @@ -537,8 +622,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
0151      //    in which case we snap the position to the mouse position.
0152      // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
0153      // area is always the virtual desktop.
0154 -    const QRect virtualDesktopArea =
0155 -        QWindowsScreen::virtualGeometry(QGuiApplication::primaryScreen()->handle());
0156 +
0157 +    const QRect virtualDesktopArea = m_effectiveScreenGeometry;
0158  
0159      if (QWindowsContext::verbose > 1)  {
0160          qCDebug(lcQpaTablet) << __FUNCTION__ << "processing" << packetCount
0161 diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
0162 index 8f97982308..fe7e7815d6 100644
0163 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h
0164 +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
0165 @@ -45,7 +45,9 @@
0166  
0167  #include <QtCore/qvector.h>
0168  #include <QtCore/qpoint.h>
0169 +#include <QtCore/qrect.h>
0170  #include <QtCore/qhash.h>
0171 +#include <QtCore/qobject.h>
0172  
0173  #include <wintab.h>
0174  
0175 @@ -56,6 +58,7 @@ QT_BEGIN_NAMESPACE
0176  class QDebug;
0177  class QWindow;
0178  class QRect;
0179 +class QScreen;
0180  
0181  struct QWindowsWinTab32DLL
0182  {
0183 @@ -108,7 +111,7 @@ struct QWindowsTabletDeviceData
0184  QDebug operator<<(QDebug d, const QWindowsTabletDeviceData &t);
0185  #endif
0186  
0187 -class QWindowsTabletSupport
0188 +class QWindowsTabletSupport : public QObject
0189  {
0190      Q_DISABLE_COPY(QWindowsTabletSupport)
0191  
0192 @@ -141,9 +144,14 @@ public:
0193      int absoluteRange() const { return m_absoluteRange; }
0194      void setAbsoluteRange(int a) { m_absoluteRange = a; }
0195  
0196 +private Q_SLOTS:
0197 +    void slotPrimaryScreenChanged(QScreen *screen);
0198 +    void slotScreenGeometryChanged();
0199 +
0200  private:
0201      unsigned options() const;
0202      QWindowsTabletDeviceData tabletInit(qint64 uniqueId, UINT cursorType) const;
0203 +    void updateEffectiveScreenGeometry();
0204  
0205      static QWindowsWinTab32DLL m_winTab32DLL;
0206      const HWND m_window;
0207 @@ -154,6 +162,9 @@ private:
0208      int m_currentDevice = -1;
0209      Mode m_mode = PenMode;
0210      State m_state = PenUp;
0211 +    QScreen *m_connectedScreen = 0;
0212 +    QRect m_wintabScreenGeometry;
0213 +    QRect m_effectiveScreenGeometry;
0214  };
0215  
0216  QT_END_NAMESPACE
0217 -- 
0218 2.20.1.windows.1
0219