Fix pen tablet stuck on Windows for some non-Wacom tablets.
authorColby Klein <shakesoda>
Sun, 26 Aug 2018 21:16:43 +0000 (23:16 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Sun, 26 Aug 2018 21:19:31 +0000 (23:19 +0200)
Differential Revision: https://developer.blender.org/D3573

intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.h

index 1e0c17f8b729d198bf3cb102d3588f8d8cc3a8b4..ae4aae380c55d92281fd1210b03a38fd5baa899d 100644 (file)
@@ -1248,7 +1248,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * will not be dispatched to OUR active window if we minimize one of OUR windows. */
                                        if (LOWORD(wParam) == WA_INACTIVE)
                                                window->lostMouseCapture();
-
+                                       window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
                                        lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
                                        break;
                                }
index 6e89299e1ca1156a4a7363c13013e8d66764f218..92de41a859b52b06526d95daa451fbfd3670aca5 100644 (file)
@@ -265,23 +265,22 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
                GHOST_WIN32_WTInfo fpWTInfo = (GHOST_WIN32_WTInfo) ::GetProcAddress(m_wintab, "WTInfoA");
                GHOST_WIN32_WTOpen fpWTOpen = (GHOST_WIN32_WTOpen) ::GetProcAddress(m_wintab, "WTOpenA");
 
-               // let's see if we can initialize tablet here
-               /* check if WinTab available. */
-               if (fpWTInfo && fpWTInfo(0, 0, NULL)) {
+               // Let's see if we can initialize tablet here.
+               // Check if WinTab available by getting system context info.
+               LOGCONTEXT lc = { 0 };
+               lc.lcOptions |= CXO_SYSTEM;
+               if (fpWTInfo && fpWTInfo(WTI_DEFSYSCTX, 0, &lc)) {
                        // Now init the tablet
-                       LOGCONTEXT lc;
                        /* The maximum tablet size, pressure and orientation (tilt) */
                        AXIS TabletX, TabletY, Pressure, Orientation[3];
 
                        // Open a Wintab context
 
-                       // Get default context information
-                       fpWTInfo(WTI_DEFCONTEXT, 0, &lc);
-
                        // Open the context
                        lc.lcPktData = PACKETDATA;
                        lc.lcPktMode = PACKETMODE;
-                       lc.lcOptions |= CXO_MESSAGES | CXO_SYSTEM;
+                       lc.lcOptions |= CXO_MESSAGES;
+                       lc.lcMoveMask = PACKETDATA;
 
                        /* Set the entire tablet as active */
                        fpWTInfo(WTI_DEVICES, DVC_X, &TabletX);
@@ -309,11 +308,17 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
                        }
 
                        if (fpWTOpen) {
-                               m_tablet = fpWTOpen(m_hWnd, &lc, TRUE);
+                               // The Wintab spec says we must open the context disabled if we are using cursor masks.
+                               m_tablet = fpWTOpen(m_hWnd, &lc, FALSE);
                                if (m_tablet) {
                                        m_tabletData = new GHOST_TabletData();
                                        m_tabletData->Active = GHOST_kTabletModeNone;
                                }
+
+                               GHOST_WIN32_WTEnable fpWTEnable = (GHOST_WIN32_WTEnable) ::GetProcAddress(m_wintab, "WTEnable");
+                               if (fpWTEnable) {
+                                       fpWTEnable(m_tablet, TRUE);
+                               }
                        }
                }
        }
@@ -857,6 +862,23 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorShape(GHOST_TStandardCursor cur
        return GHOST_kSuccess;
 }
 
+void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
+{
+       if (!m_tablet) {
+               return;
+       }
+
+       GHOST_WIN32_WTEnable fpWTEnable = (GHOST_WIN32_WTEnable) ::GetProcAddress(m_wintab, "WTEnable");
+       GHOST_WIN32_WTOverlap fpWTOverlap = (GHOST_WIN32_WTOverlap) ::GetProcAddress(m_wintab, "WTOverlap");
+
+       if (fpWTEnable) {
+               fpWTEnable(m_tablet, state);
+               if (fpWTOverlap && state) {
+                       fpWTOverlap(m_tablet, TRUE);
+               }
+       }
+}
+
 void GHOST_WindowWin32::processWin32TabletInitEvent()
 {
        if (m_wintab && m_tabletData) {
index d998e86c9b15756c0ef19ead6bd7f5b479fa7054..c72669ed8983417e85597842b39671b5c8a883f5 100644 (file)
@@ -56,6 +56,7 @@ typedef UINT (API * GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
 typedef HCTX (API * GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
 typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
 typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
+typedef BOOL (API * GHOST_WIN32_WTEnable)(HCTX, BOOL);
 typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
 
 // typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
@@ -249,6 +250,7 @@ public:
                return m_tabletData;
        }
 
+       void processWin32TabletActivateEvent(WORD state);
        void processWin32TabletInitEvent();
        void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
        void bringTabletContextToFront();