Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorNicholas Rishel <rishel.nick@gmail.com>2021-01-11 08:13:44 +0300
committerNicholas Rishel <rishel.nick@gmail.com>2021-01-11 08:18:46 +0300
commitab5986cf3a2eea3a8ba3f7029f936f79ade921ef (patch)
tree8cc82e6eec6f21a7a0ecb8a7f541878c38634f2a /intern
parentaf88d23ffaab650f050886afc7595a8f6bff08b8 (diff)
Fix T84501: Wintab button lag.
Multiple Wintab tablets do not send relative button state when configured to do so. This causes button events to be delayed until processed as Win32 button events. This commit fixes the issue by configuring Wintab to use absolute button state and tracking changes manually.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp7
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp50
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h9
3 files changed, 49 insertions, 17 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 181e3ad4014..5de97199fd8 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1559,7 +1559,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
break;
case WT_PROXIMITY: {
if (window->useTabletAPI(GHOST_kTabletWintab)) {
- window->m_tabletInRange = LOWORD(lParam);
+ if (LOWORD(lParam)) {
+ window->m_tabletInRange = true;
+ }
+ else {
+ window->processWintabLeave();
+ }
}
eventHandled = true;
break;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index f5088c6505e..255d487649b 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1155,16 +1155,21 @@ void GHOST_WindowWin32::setWintabOverlap(bool overlap)
/* If context is disabled, Windows Ink may be active and managing m_tabletInRange. Don't
* modify it. */
if (!(context.lcStatus & CXS_DISABLED)) {
- /* Set tablet as not in range, proximity event may not occur. */
- m_tabletInRange = false;
- /* Clear the packet queue. */
- m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+ processWintabLeave();
}
}
}
}
}
+void GHOST_WindowWin32::processWintabLeave()
+{
+ m_tabletInRange = false;
+ m_wintab.buttons = 0;
+ /* Clear the packet queue. */
+ m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+}
+
void GHOST_WindowWin32::processWintabDisplayChangeEvent()
{
LOGCONTEXT lc_sys = {0}, lc_curr = {0};
@@ -1327,17 +1332,32 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
out.tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
}
- out.button = wintabMouseToGhost(pkt.pkCursor, LOWORD(pkt.pkButtons));
- switch (HIWORD(pkt.pkButtons)) {
- case TBN_NONE:
- out.type = GHOST_kEventCursorMove;
- break;
- case TBN_DOWN:
- out.type = GHOST_kEventButtonDown;
- break;
- case TBN_UP:
- out.type = GHOST_kEventButtonUp;
- break;
+ /* Some Wintab libraries don't handle relative button input, so we track button presses
+ * manually. */
+ out.button = GHOST_kButtonMaskNone;
+ out.type = GHOST_kEventCursorMove;
+
+ DWORD buttonsChanged = m_wintab.buttons ^ pkt.pkButtons;
+ if (buttonsChanged) {
+ /* Find the index for the changed button from the button map. */
+ WORD physicalButton = 0;
+ for (DWORD diff = (unsigned)buttonsChanged >> 1; diff > 0; diff = (unsigned)diff >> 1) {
+ physicalButton++;
+ }
+
+ out.button = wintabMouseToGhost(pkt.pkCursor, physicalButton);
+
+ if (out.button != GHOST_kButtonMaskNone) {
+ if (buttonsChanged & pkt.pkButtons) {
+ out.type = GHOST_kEventButtonDown;
+ }
+ else {
+ out.type = GHOST_kEventButtonUp;
+ }
+ }
+
+ /* Only update handled button, in case multiple button events arrived simultaneously. */
+ m_wintab.buttons ^= 1 << physicalButton;
}
out.time = system->tickCountToMillis(pkt.pkTime);
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 1cff8b2036e..a7e7cdc6602 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -41,7 +41,7 @@
// PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
#define PACKETDATA \
(PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME)
-#define PACKETMODE PK_BUTTONS
+#define PACKETMODE 0
#include <pktdef.h>
class GHOST_SystemWin32;
@@ -467,6 +467,11 @@ class GHOST_WindowWin32 : public GHOST_Window {
void setWintabOverlap(bool overlap);
/**
+ * Resets Wintab state.
+ */
+ void processWintabLeave();
+
+ /**
* Handle Wintab coordinate changes when DisplayChange events occur.
*/
void processWintabDisplayChangeEvent();
@@ -614,6 +619,8 @@ class GHOST_WindowWin32 : public GHOST_Window {
HCTX context = NULL;
/** Number of connected Wintab digitizers. */
UINT numDevices = 0;
+ /** Pressed button map. */
+ GHOST_TUns8 buttons = 0;
LONG maxPressure = 0;
LONG maxAzimuth = 0, maxAltitude = 0;
/** Reusable buffer to read in Wintab Packets. */