diff options
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | intern/ghost/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_Debug.h | 14 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 48 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.cpp | 77 |
5 files changed, 144 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index eb04da749ab..9662f12613f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,6 +209,11 @@ option(WITH_NANOVDB "Enable usage of NanoVDB data structure for accelerate option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF) mark_as_advanced(WITH_GHOST_DEBUG) +if(WIN32) + option(WITH_WINTAB_DEBUG "Enable debugging output for Wintab" OFF) + mark_as_advanced(WITH_WINTAB_DEBUG) +endif() + option(WITH_GHOST_SDL "Enable building Blender against SDL for windowing rather than the native APIs" OFF) mark_as_advanced(WITH_GHOST_SDL) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 77e777db872..5d83fbec778 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -97,6 +97,10 @@ if(WITH_GHOST_DEBUG) add_definitions(-DWITH_GHOST_DEBUG) endif() +if(WITH_WINTAB_DEBUG) + add_definitions(-DWITH_WINTAB_DEBUG) +endif() + if(WITH_INPUT_NDOF) add_definitions(-DWITH_INPUT_NDOF) diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h index 424f95aa573..49b88bdc815 100644 --- a/intern/ghost/intern/GHOST_Debug.h +++ b/intern/ghost/intern/GHOST_Debug.h @@ -34,9 +34,6 @@ #ifdef WITH_GHOST_DEBUG # include <iostream> # include <stdio.h> //for printf() -#endif // WITH_GHOST_DEBUG - -#ifdef WITH_GHOST_DEBUG # define GHOST_PRINT(x) \ { \ std::cout << x; \ @@ -52,6 +49,17 @@ # define GHOST_PRINTF(x, ...) #endif // WITH_GHOST_DEBUG +#ifdef WITH_WINTAB_DEBUG +# include <stdio.h> //for printf() +# define WINTAB_PRINTF(x, ...) \ + { \ + printf(x, __VA_ARGS__); \ + } \ + (void)0 +#else // WITH_WINTAB_DEBUG +# define WINTAB_PRINTF(x, ...) +#endif // WITH_WINTAB_DEBUG + #ifdef WITH_ASSERT_ABORT # include <stdio.h> //for fprintf() # include <stdlib.h> //for abort() diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index aa282c73c92..99ce7d54580 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -940,9 +940,11 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); if (type == GHOST_kEventButtonDown) { + WINTAB_PRINTF("%p OS button down\n", window->getHWND()); window->updateMouseCapture(MousePressed); } else if (type == GHOST_kEventButtonUp) { + WINTAB_PRINTF("%p OS button up\n", window->getHWND()); window->updateMouseCapture(MouseReleased); } @@ -1015,13 +1017,18 @@ GHOST_TSuccess GHOST_SystemWin32::processWintabEvents(GHOST_TEventType type, * don't duplicate the prior button down as it interrupts drawing immediately after * changing a window. */ + WINTAB_PRINTF("%p wintab button down", window->getHWND()); system->pushEvent(new GHOST_EventCursor( info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData)); if (type == GHOST_kEventButtonDown && mask == info.button) { + WINTAB_PRINTF(" ... associated to system button\n"); system->pushEvent( new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData)); unhandledButton = false; } + else { + WINTAB_PRINTF(" ... but no system button\n"); + } window->updateWintabSysBut(MousePressed); break; } @@ -1030,11 +1037,16 @@ GHOST_TSuccess GHOST_SystemWin32::processWintabEvents(GHOST_TEventType type, info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData)); break; case GHOST_kEventButtonUp: + WINTAB_PRINTF("%p wintab button up", window->getHWND()); system->pushEvent( new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData)); if (type == GHOST_kEventButtonUp && mask == info.button) { + WINTAB_PRINTF(" ... associated to system button\n"); unhandledButton = false; } + else { + WINTAB_PRINTF(" ... but no system button\n"); + } window->updateWintabSysBut(MouseReleased); break; default: @@ -1056,6 +1068,7 @@ GHOST_TSuccess GHOST_SystemWin32::processWintabEvents(GHOST_TEventType type, // non-mouse mapping, means that we must pessimistically generate mouse up events when we are // unsure of an association to prevent the mouse locking into a down state. if (unhandledButton) { + WINTAB_PRINTF("%p unhandled system button\n", window->getHWND()); if (!window->wintabSysButPressed()) { GHOST_TInt32 x, y; system->getCursorPosition(x, y); @@ -1613,11 +1626,21 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, // Wintab events, processed //////////////////////////////////////////////////////////////////////// case WT_INFOCHANGE: { + WINTAB_PRINTF("%p WT_INFOCHANGE\n", window->getHWND()); window->processWintabInfoChangeEvent(lParam); break; } + case WT_CSRCHANGE: + WINTAB_PRINTF("%p WT_CSRCHANGE\n", window->getHWND()); + break; case WT_PROXIMITY: { bool inRange = LOWORD(lParam); + WINTAB_PRINTF( + "%p WT_PROXIMITY loword (!0 enter 0 leave context): %d, hiword (!0 enter !0 leave " + "hardware): %d\n", + window->getHWND(), + LOWORD(lParam), + HIWORD(lParam)); window->processWintabProximityEvent(inRange); break; } @@ -1625,6 +1648,31 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, window->updatePendingWintabEvents(); break; //////////////////////////////////////////////////////////////////////// + // Wintab events, debug + //////////////////////////////////////////////////////////////////////// + case WT_CTXOPEN: + WINTAB_PRINTF("%p WT_CTXOPEN\n", window->getHWND()); + break; + case WT_CTXCLOSE: + WINTAB_PRINTF("%p WT_CTXCLOSE\n", window->getHWND()); + break; + case WT_CTXUPDATE: + WINTAB_PRINTF("%p WT_CTXUPDATE\n", window->getHWND()); + break; + case WT_CTXOVERLAP: + switch (lParam) { + case CXS_DISABLED: + WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_DISABLED\n", window->getHWND()); + break; + case CXS_OBSCURED: + WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_OBSCURED\n", window->getHWND()); + break; + case CXS_ONTOP: + WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_ONTOP\n", window->getHWND()); + break; + } + break; + //////////////////////////////////////////////////////////////////////// // Pointer events, processed //////////////////////////////////////////////////////////////////////// case WM_POINTERENTER: diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 809faa81177..e1ecec8081a 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -796,6 +796,7 @@ void GHOST_WindowWin32::updateWintabSysBut(GHOST_MouseCaptureEventWin32 event) case OperatorUngrab: break; } + WINTAB_PRINTF("%p %d system buttons\n", m_hWnd, m_wintab.numSysButtons); } HCURSOR GHOST_WindowWin32::getStandardCursor(GHOST_TStandardCursor shape) const @@ -1013,6 +1014,8 @@ void GHOST_WindowWin32::updateWintab(bool active, bool visible) m_wintab.enable(m_wintab.context, enable); m_wintab.overlap(m_wintab.context, overlap); + WINTAB_PRINTF("%p updateWintab enable: %d, overlap: %d\n", m_hWnd, enable, overlap); + if (!overlap) { // WT_PROXIMITY event doesn't occur unless tablet's cursor leaves the proximity while the // window is active. @@ -1027,6 +1030,10 @@ void GHOST_WindowWin32::initializeWintab() { // return if wintab library handle doesn't exist or wintab is already initialized if (!m_wintab.handle || m_wintab.context) { + WINTAB_PRINTF("%p initializeWintab() handle: %p, context: %p\n", + m_hWnd, + m_wintab.handle, + m_wintab.context); return; } @@ -1045,17 +1052,32 @@ void GHOST_WindowWin32::initializeWintab() lc.lcPktData = PACKETDATA; lc.lcPktMode = PACKETMODE; lc.lcMoveMask = PACKETDATA; - lc.lcOptions |= CXO_MESSAGES; + lc.lcOptions |= CXO_CSRMESSAGES | CXO_MESSAGES; // Wacom maps y origin to the tablet's bottom // Invert to match Windows y origin mapping to the screen top lc.lcOutExtY = -lc.lcOutExtY; + WINTAB_PRINTF("lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n", + lc.lcOutOrgX, + lc.lcOutOrgY, + lc.lcOutExtX, + lc.lcOutExtY); + WINTAB_PRINTF("left: %d, top: %d, width: %d, height: %d\n", + ::GetSystemMetrics(SM_XVIRTUALSCREEN), + ::GetSystemMetrics(SM_YVIRTUALSCREEN), + ::GetSystemMetrics(SM_CXVIRTUALSCREEN), + ::GetSystemMetrics(SM_CYVIRTUALSCREEN)); + m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices); + WINTAB_PRINTF("initializeWintab numDevices: %d\n", m_wintab.numDevices); + /* get the max pressure, to divide into a float */ BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0; + WINTAB_PRINTF("initializeWintab maxPressure: %d\n", m_wintab.maxPressure); + /* get the max tilt axes, to divide into floats */ BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); /* does the tablet support azimuth ([0]) and altitude ([1]) */ @@ -1063,6 +1085,10 @@ void GHOST_WindowWin32::initializeWintab() /* all this assumes the minimum is 0 */ m_wintab.maxAzimuth = Orientation[0].axMax; m_wintab.maxAltitude = Orientation[1].axMax; + + WINTAB_PRINTF("initializeWintab maxAzimuth: %d, maxAltitude: %d\n", + m_wintab.maxAzimuth, + m_wintab.maxAltitude); } else { /* no so dont do tilt stuff */ m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; @@ -1071,6 +1097,13 @@ void GHOST_WindowWin32::initializeWintab() // The Wintab spec says we must open the context disabled if we are using cursor masks. m_wintab.context = m_wintab.open(m_hWnd, &lc, FALSE); +#ifdef WITH_WINTAB_DEBUG + UINT maxcontexts, opencontexts; + m_wintab.info(WTI_INTERFACE, IFC_NCONTEXTS, &maxcontexts); + m_wintab.info(WTI_STATUS, STA_CONTEXTS, &opencontexts); + WINTAB_PRINTF("%p %u max contexts, %u open contexts\n", getHWND(), maxcontexts, opencontexts); +#endif + // Wintab provides no way to determine the maximum queue size aside from checking if attempts // to change the queue size are successful. const int maxQueue = 500; @@ -1096,6 +1129,40 @@ void GHOST_WindowWin32::initializeWintab() } } m_wintab.pkts.resize(queueSize); + +#ifdef WITH_WINTAB_DEBUG + int sanityQueueSize = m_wintab.queueSizeGet(m_wintab.context); + WINTAB_PRINTF("initializeWintab queueSize: %d, queueSizeGet: %d\n", queueSize, sanityQueueSize); + + // print button maps + BYTE logicalButtons[32] = {0}; + BYTE systemButtons[32] = {0}; + for (int i = 0; i < 3; i++) { + WINTAB_PRINTF("initializeWintab cursor %d buttons\n", i); + UINT lbut = m_wintab.info(WTI_CURSORS + i, CSR_BUTTONMAP, &logicalButtons); + if (lbut) { + WINTAB_PRINTF("%d", logicalButtons[0]); + for (int j = 1; j < lbut; j++) { + WINTAB_PRINTF(", %d", logicalButtons[j]); + } + WINTAB_PRINTF("\n"); + } + else { + WINTAB_PRINTF("logical button error\n"); + } + UINT sbut = m_wintab.info(WTI_CURSORS + i, CSR_SYSBTNMAP, &systemButtons); + if (sbut) { + WINTAB_PRINTF("%d", systemButtons[0]); + for (int j = 1; j < sbut; j++) { + WINTAB_PRINTF(", %d", systemButtons[j]); + } + WINTAB_PRINTF("\n"); + } + else { + WINTAB_PRINTF("system button error\n"); + } + } +#endif } } @@ -1220,6 +1287,8 @@ void GHOST_WindowWin32::processWintabProximityEvent(bool inRange) return; } + WINTAB_PRINTF("%p processWintabProximityEvent inRange: %d\n", m_hWnd, inRange); + // Let's see if we can initialize tablet here if (m_wintab.info && m_wintab.context) { AXIS Pressure, Orientation[3]; /* The maximum tablet size */ @@ -1250,6 +1319,8 @@ void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam) m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices); updateWintab((GHOST_WindowWin32 *)system->getWindowManager()->getActiveWindow() == this, !::IsIconic(m_hWnd)); + + WINTAB_PRINTF("%p processWintabInfoChangeEvent numDevices: %d\n", m_hWnd, m_wintab.numDevices); } } @@ -1274,15 +1345,19 @@ GHOST_TSuccess GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, } switch (systemButtons[lb]) { case SBN_LCLICK: + WINTAB_PRINTF("%p wintabMouseToGhost left click\n", m_hWnd); ghostButton = GHOST_kButtonMaskLeft; return GHOST_kSuccess; case SBN_RCLICK: + WINTAB_PRINTF("%p wintabMouseToGhost right click\n", m_hWnd); ghostButton = GHOST_kButtonMaskRight; return GHOST_kSuccess; case SBN_MCLICK: + WINTAB_PRINTF("%p wintabMouseToGhost middle click\n", m_hWnd); ghostButton = GHOST_kButtonMaskMiddle; return GHOST_kSuccess; default: + WINTAB_PRINTF("%p wintabMouseToGhost non-sys button: %d\n", m_hWnd, systemButtons[lb]); return GHOST_kFailure; } } |