[Bf-blender-cvs] [96e2b1bac3b] wintab-high-frequency: tmp

Nicholas Rishel noreply at git.blender.org
Fri Jun 4 03:10:45 CEST 2021


Commit: 96e2b1bac3bebfe48d65dab633c98cd776059f4f
Author: Nicholas Rishel
Date:   Thu Mar 4 15:48:48 2021 -0800
Branches: wintab-high-frequency
https://developer.blender.org/rB96e2b1bac3bebfe48d65dab633c98cd776059f4f

tmp

===================================================================

M	intern/ghost/CMakeLists.txt
A	intern/ghost/intern/GHOST_PointerWin32.cpp
A	intern/ghost/intern/GHOST_PointerWin32.h
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_PointerWin32.cpp b/intern/ghost/intern/GHOST_PointerWin32.cpp
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/intern/ghost/intern/GHOST_PointerWin32.h b/intern/ghost/intern/GHOST_PointerWin32.h
new file mode 100644
index 00000000000..e69de29bb2d
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 fc3cb81e26a..bbe2c3a3dda 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -174,6 +174,11 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
   toggleConsole(1);
 }
 
+GHOST_TUns64 GHOST_SystemWin32::millisSinceStart(__int64 ms) const
+{
+  return (GHOST_TUns64)(ms - m_start * 1000 / m_freq);
+}
+
 GHOST_TUns64 GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
 {
   // Calculate the time passed since system initialization.
@@ -867,15 +872,141 @@ 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;
   }
 
-  return new GHOST_EventButton(
-      system->getMilliSeconds(), type, window, mask, window->getTabletData());
+  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) {
+
+          POINT pt;
+          pt.x = GET_X_LPARAM(msg.lParam);
+          pt.y = GET_Y_LPARAM(msg.lParam);
+          ::ClientToScreen(window->getHWND(), &pt);
+
+          if (wt->testCoordinates(pt.x, 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;
+    }
+  }
+
+  /* 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(
@@ -900,14 +1031,17 @@ void GHOST_SystemWin32::processPointerEvent(
   }
 
   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 +1058,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 +1066,6 @@ void GHOST_SystemWin32::processPointerEvent(
                                               pointerInfo[0].tabletData));
       window->updateMouseCapture(MouseReleased);
       break;
-    case WM_POINTERLEAVE:
-      window->m_tabletInRange = false;
-      break;
     default:
       break;
   }
@@ -960,18

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list