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> 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 class GHOST_SystemWin32; @@ -466,6 +466,11 @@ class GHOST_WindowWin32 : public GHOST_Window { */ void setWintabOverlap(bool overlap); + /** + * Resets Wintab state. + */ + void processWintabLeave(); + /** * Handle Wintab coordinate changes when DisplayChange events occur. */ @@ -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. */