[Bf-blender-cvs] [85defa5e2c5] wintab-high-frequency: Refactor of Wintab to use Wintab supplied mouse movement once verified against system input.
Nicholas Rishel
noreply at git.blender.org
Mon Jun 14 20:32:21 CEST 2021
Commit: 85defa5e2c5d4ef15a1ade1d052fcded501fbc39
Author: Nicholas Rishel
Date: Thu Mar 4 15:48:48 2021 -0800
Branches: wintab-high-frequency
https://developer.blender.org/rB85defa5e2c5d4ef15a1ade1d052fcded501fbc39
Refactor of Wintab to use Wintab supplied mouse movement once verified against system input.
Differential Revision: https://developer.blender.org/D11508
===================================================================
M intern/ghost/CMakeLists.txt
M intern/ghost/intern/GHOST_System.h
M intern/ghost/intern/GHOST_SystemWin32.cpp
M intern/ghost/intern/GHOST_SystemWin32.h
M intern/ghost/intern/GHOST_WindowWin32.cpp
M intern/ghost/intern/GHOST_WindowWin32.h
A intern/ghost/intern/GHOST_Wintab.cpp
A intern/ghost/intern/GHOST_Wintab.h
===================================================================
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 1b5cdb3cda0..40d78a22e6f 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -370,6 +370,7 @@ elseif(WIN32)
intern/GHOST_DropTargetWin32.cpp
intern/GHOST_SystemWin32.cpp
intern/GHOST_WindowWin32.cpp
+ intern/GHOST_Wintab.cpp
intern/GHOST_ContextD3D.h
intern/GHOST_DisplayManagerWin32.h
@@ -377,6 +378,7 @@ elseif(WIN32)
intern/GHOST_SystemWin32.h
intern/GHOST_TaskbarWin32.h
intern/GHOST_WindowWin32.h
+ intern/GHOST_Wintab.h
)
if(NOT WITH_GL_EGL)
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 2a7123b293e..9915520691f 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -239,7 +239,7 @@ class GHOST_System : public GHOST_ISystem {
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
* \param api: Enum indicating which API to use.
*/
- void setTabletAPI(GHOST_TTabletAPI api);
+ virtual void setTabletAPI(GHOST_TTabletAPI api) override;
GHOST_TTabletAPI getTabletAPI(void);
#ifdef WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index c3a243cc22c..c06f46520b3 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -867,15 +867,135 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if (type == GHOST_kEventButtonDown) {
- window->updateMouseCapture(MousePressed);
+ GHOST_TabletData td = window->getTabletData();
+
+ /* Move mouse to button event position. */
+ if (window->getTabletData().Active != GHOST_kTabletModeNone) {
+ /* Tablet should be handling inbetween mouse moves, only move to event position. */
+ DWORD msgPos = ::GetMessagePos();
+ int msgPosX = GET_X_LPARAM(msgPos);
+ int msgPosY = GET_Y_LPARAM(msgPos);
+ system->pushEvent(new GHOST_EventCursor(
+ ::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
}
- else if (type == GHOST_kEventButtonUp) {
- window->updateMouseCapture(MouseReleased);
+
+ window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
+ return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
+}
+
+void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
+{
+ GHOST_Wintab *wt = window->getWintab();
+ if (!wt) {
+ return;
+ }
+
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
+
+ std::vector<GHOST_WintabInfoWin32> wintabInfo;
+ wt->getInput(wintabInfo);
+
+ bool mouseUpdated = wt->trustCoordinates();
+
+ for (auto info : wintabInfo) {
+ switch (info.type) {
+ case GHOST_kEventCursorMove: {
+ if (!wt->trustCoordinates()) {
+ continue;
+ }
+ wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
+ system->pushEvent(new GHOST_EventCursor(
+ info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
+
+ break;
+ }
+ case GHOST_kEventButtonDown: {
+ /* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
+ * in. Only issue button events if we can steal an equivalent Win32 button event from the
+ * event queue. */
+ UINT message;
+ switch (info.button) {
+ case GHOST_kButtonMaskLeft:
+ message = WM_LBUTTONDOWN;
+ break;
+ case GHOST_kButtonMaskRight:
+ message = WM_RBUTTONDOWN;
+ break;
+ case GHOST_kButtonMaskMiddle:
+ message = WM_MBUTTONDOWN;
+ break;
+ default:
+ continue;
+ }
+
+ MSG msg;
+ if (PeekMessage(&msg, window->getHWND(), message, message, PM_NOYIELD) &&
+ WM_QUIT != msg.message) {
+ if (wt->testCoordinates(msg.pt.x, msg.pt.y, info.x, info.y)) {
+ PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD);
+
+ /* Move cursor to button location, to prevent incorrect cursor position when
+ * transitioning from unsynchronized Win32 to Wintab cursor control. */
+ wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
+ system->pushEvent(new GHOST_EventCursor(
+ info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
+
+ window->updateMouseCapture(MousePressed);
+ system->pushEvent(
+ new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
+
+ mouseUpdated = true;
+ }
+ }
+ break;
+ }
+ case GHOST_kEventButtonUp: {
+ if (!wt->trustCoordinates()) {
+ continue;
+ }
+
+ /* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
+ * in. Only issue button events if we can steal an equivalent Win32 button event from the
+ * event queue. */
+ UINT message;
+ switch (info.button) {
+ case GHOST_kButtonMaskLeft:
+ message = WM_LBUTTONUP;
+ break;
+ case GHOST_kButtonMaskRight:
+ message = WM_RBUTTONUP;
+ break;
+ case GHOST_kButtonMaskMiddle:
+ message = WM_MBUTTONUP;
+ break;
+ default:
+ continue;
+ }
+
+ MSG msg;
+ if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
+ WM_QUIT != msg.message) {
+ window->updateMouseCapture(MouseReleased);
+ system->pushEvent(
+ new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
+ }
+ break;
+ }
+ default:
+ break;
+ }
}
- return new GHOST_EventButton(
- system->getMilliSeconds(), type, window, mask, window->getTabletData());
+ /* Fallback mouse movement if Wintab provided coodinates are untrusted. */
+ if (!mouseUpdated) {
+ DWORD pos = GetMessagePos();
+ int x = GET_X_LPARAM(pos);
+ int y = GET_Y_LPARAM(pos);
+
+ /* TODO supply tablet data */
+ system->pushEvent(new GHOST_EventCursor(
+ system->getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
+ }
}
void GHOST_SystemWin32::processPointerEvent(
@@ -894,20 +1014,18 @@ void GHOST_SystemWin32::processPointerEvent(
return;
}
- if (!pointerInfo[0].isPrimary) {
- eventHandled = true;
- return; // For multi-touch displays we ignore these events
- }
-
switch (type) {
- case WM_POINTERENTER:
- window->m_tabletInRange = true;
- system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time,
- GHOST_kEventCursorMove,
- window,
- pointerInfo[0].pixelLocation.x,
- pointerInfo[0].pixelLocation.y,
- pointerInfo[0].tabletData));
+ case WM_POINTERUPDATE:
+ /* Coalesced pointer events are reverse chronological order, reorder chronologically.
+ * Only contiguous move events are coalesced. */
+ for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) {
+ system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
+ GHOST_kEventCursorMove,
+ window,
+ pointerInfo[i].pixelLocation.x,
+ pointerInfo[i].pixelLocation.y,
+ pointerInfo[i].tabletData));
+ }
break;
case WM_POINTERDOWN:
/* Move cursor to point of contact because GHOST_EventButton does not include position. */
@@ -924,18 +1042,6 @@ void GHOST_SystemWin32::processPointerEvent(
pointerInfo[0].tabletData));
window->updateMouseCapture(MousePressed);
break;
- case WM_POINTERUPDATE:
- /* Coalesced pointer events are reverse chronological order, reorder chronologically.
- * Only contiguous move events are coalesced. */
- for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) {
- system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
- GHOST_kEventCursorMove,
- window,
- pointerInfo[i].pixelLocation.x,
- pointerInfo[i].pixelLocation.y,
- pointerInfo[i].tabletData));
- }
- break;
case WM_POINTERUP:
system->pushEvent(new GHOST_EventButton(pointerInfo[0].time,
GHOST_kEventButtonUp,
@@ -944,9 +1050,6 @@ void GHOST_SystemWin32::processPointerEvent(
pointerInfo[0].tabletData));
window->updateMouseCapture(MouseReleased);
break;
- case WM_POINTERLEAVE:
- window->m_tabletInRange = false;
- break;
default:
break;
}
@@ -960,18 +1063,16 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
GHOST_TInt32 x_screen, y_screen;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if (window->m_tabletInRange) {
- if (window->useTabletAPI(GHOST_kTabletNative)) {
- /* Tablet input handled in WM_POINTER* events. WM_MOUSEMOVE events in response to tablet
- * input aren't normally generated when using WM_POINTER events, but manually moving the
- * system cursor as we do in WM_POINTER handling does. */
- return NULL;
- }
+ if (window->getTabletData().Active != GHOST_kTabletModeNone) {
+ /* Tablet input handled in WM_POINTER* eve
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list