Browse Source

device: support digitizers via Win32 raw input API

rdb 6 years ago
parent
commit
b67c7dd84f

+ 6 - 0
panda/src/device/inputDevice.cxx

@@ -578,6 +578,9 @@ format_device_class(DeviceClass dc) {
 
   case InputDevice::DeviceClass::spatial_mouse:
     return "spatial_mouse";
+
+  case InputDevice::DeviceClass::digitizer:
+    return "digitizer";
   }
   return "**invalid**";
 }
@@ -644,6 +647,9 @@ format_axis(Axis axis) {
 
   case InputDevice::Axis::brake:
     return "brake";
+
+  case InputDevice::Axis::pressure:
+    return "pressure";
   }
   return "**invalid**";
 }

+ 6 - 0
panda/src/device/inputDevice.h

@@ -80,6 +80,9 @@ PUBLISHED:
 
     // 3D mouse, such as produced by 3Dconnexion.
     spatial_mouse,
+
+    // A graphics tablet with stylus/pen.
+    digitizer,
   };
 
   enum class Feature {
@@ -128,6 +131,9 @@ PUBLISHED:
     wheel,
     accelerator,
     brake,
+
+    // Pen pressure
+    pressure,
   };
 
   enum State {

+ 1 - 0
panda/src/device/phidsdi.h

@@ -28,6 +28,7 @@ typedef USHORT USAGE, *PUSAGE;
 #define HID_USAGE_PAGE_KEYBOARD        ((USAGE) 0x07)
 #define HID_USAGE_PAGE_LED             ((USAGE) 0x08)
 #define HID_USAGE_PAGE_BUTTON          ((USAGE) 0x09)
+#define HID_USAGE_PAGE_DIGITIZER       ((USAGE) 0x0d)
 
 #define HID_USAGE_GENERIC_POINTER      ((USAGE) 0x01)
 #define HID_USAGE_GENERIC_MOUSE        ((USAGE) 0x02)

+ 7 - 2
panda/src/device/winInputDeviceManager.cxx

@@ -14,6 +14,7 @@
 #include "winInputDeviceManager.h"
 #include "winRawInputDevice.h"
 #include "throw_event.h"
+#include "phidsdi.h"
 
 #if defined(_WIN32) && !defined(CPPPARSER)
 
@@ -385,7 +386,7 @@ setup_message_loop() {
   }
 
   // Now listen for raw input devices using the created message loop.
-  RAWINPUTDEVICE rid[3];
+  RAWINPUTDEVICE rid[4];
   rid[0].usUsagePage = 1;
   rid[0].usUsage = 4; // Joysticks
   rid[0].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
@@ -398,7 +399,11 @@ setup_message_loop() {
   rid[2].usUsage = 8; // Multi-axis controllers (including 3D mice)
   rid[2].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
   rid[2].hwndTarget = _message_hwnd;
-  if (!RegisterRawInputDevices(rid, 3, sizeof(RAWINPUTDEVICE))) {
+  rid[3].usUsagePage = HID_USAGE_PAGE_DIGITIZER;
+  rid[3].usUsage = 1; // Digitizers
+  rid[3].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK;
+  rid[3].hwndTarget = _message_hwnd;
+  if (!RegisterRawInputDevices(rid, 4, sizeof(RAWINPUTDEVICE))) {
     device_cat.warning()
       << "Failed to register raw input devices.\n";
   }

+ 13 - 0
panda/src/device/winRawInputDevice.cxx

@@ -199,6 +199,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
                info.hid.usUsage == HID_USAGE_GENERIC_KEYBOARD) {
       _device_class = DeviceClass::keyboard;
 
+    // Digitizers
+    } else if (info.hid.usUsagePage == HID_USAGE_PAGE_DIGITIZER &&
+               info.hid.usUsage == 1) {
+      _device_class = DeviceClass::digitizer;
+
     // 3Dconnexion SpaceNavigator and friends.
     } else if (_vendor_id == 0x046d &&
         (_product_id == 0xc623 ||
@@ -504,6 +509,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) {
           continue;
         }
         break;
+
+      case HID_USAGE_PAGE_DIGITIZER:
+        switch (usage) {
+        case 0x30:
+          axis = Axis::pressure;
+          break;
+        }
+        break;
       }
 
       // If this axis already exists, don't double-map it, but take the first