Page MenuHome

Fix T57869 : No pressure sensitivity with Surface Pen on Surface Laptop
ClosedPublic

Authored by Christopher Peerman (chris_82) on Jan 3 2019, 10:21 PM.

Details

Summary

Currently Blender on Windows does not appear to support Stylus hardware without the need for the WinTab driver, for example the stylus functionality does not work on a Microsoft Surface Book and pen without the WinTab driver being installed. Windows 8 added support for stylus hardware but including the WM_POINTERUPDATE Windows message, GetPointerInfo and GetPointerPenInfo API.

This pull request provides native support for these stylus devices without needing the WinTab driver, it should also resolve this bug report for Microsoft Surface Book 2 see https://developer.blender.org/T57869.

This is my first Blender request. It needs some definitions (copied from WinUser.h) for the WM_POINTERUPDATE message, as well as the GetPointerInfo and GetPointerPenInfo API. I tried to follow the existing methods but any advice would be useful. I tested it using the Grease Pencil and tested using the pointer and eraser on a Microsoft Surface Book 1.

Diff Detail

Repository
rB Blender

Event Timeline

Christopher Peerman (chris_82) retitled this revision from Support Stylus hardware on Window 8 and above to Fix T57869 : No pressure sensitivity with Surface Pen on Surface Laptop.Jan 3 2019, 10:25 PM

I'm still on win7, @Joshua Leung (aligorith) do you have time to take a look at this?

biggest question i have is what happens when both api's are available? I think Krita allows you to switch between the two, so i'm guessing they are gonna collide?

Brecht Van Lommel (brecht) requested changes to this revision.Jan 4 2019, 12:15 PM

This is great, it's been a long standing issue.

It should indeed use wintab or pointer events explicitly, otherwise it's not clear where the events will come from. I'm not sure which should be preferred by default, but I'm guessing it's best to use Wintab when available? At least Krita recommends using it for Wacom devices.

We could have a preference to choose between "Automatic", "Wintab" and "Windows Ink" to let the user make a specific choice if the automatic behavior doesn't work well.

It would be good to support tilt too, even though we don't use this in Blender currently.

intern/ghost/intern/GHOST_WindowWin32.cpp
870

This memory leaks in GHOST_WindowWin32::~GHOST_WindowWin32 if no wintab is present. The code there needs to be updated.

892

Is the pointerPenInfo.pressure > 0 test correct? Are there case where the mask is set but no valid pressure is provided?

It seems like it could cause full pressure when there is none.

This revision now requires changes to proceed.Jan 4 2019, 12:15 PM
Christopher Peerman (chris_82) marked an inline comment as done.Jan 4 2019, 2:41 PM

Thanks for taking a look at this. I'm planning do to some more work on it on Sunday evening and fix the issues you've highlighted. I'll also dig out a Wacom CTH-470K tablet and try it out with that and WinTab.

I'll have a look at adding tilt support. None of my pens currently support tilting so I won't be able to test that part of the code.

intern/ghost/intern/GHOST_WindowWin32.cpp
892

With the Microsoft Surface Pen if you hover the pen within 1cm of the screen you'll start getting WM_POINTERUPDATE events with the PEN_MASK_PRESSURE mask set and zero pressure. When the pen is touching the screen the pressure field will have a value between 1 and 1024. After taking a look at the WinTab code I made it so that if the pen is not physically touching the screen GHOST_kTabletModeNone is set. With this implementation if the user switches from the pen to the mouse it will switch from GHOST_kTabletModeStylus to GHOST_kTabletModeNone and they'll be able to draw at full pressure with the mouse.

That said I have realised that the test for PEN_FLAG_ERASER should happen after this, otherwise if their is a user with a pressure sensitive eraser it may start drawing a line instead.

intern/ghost/intern/GHOST_WindowWin32.cpp
892

Makes sense then. You could leave a comment explaining this in the code.

intern/ghost/intern/GHOST_WindowWin32.cpp
859

please do this only once and cache the result.

I made the following changes to the code

  • Added description what the pressure check is for
  • Added tilt support (Pointer API supports -90 to +90, with 0 for vertical pen)
  • Caches GetPointerInfo and GetPointerPenInfo
  • The LoadLibrary requests to user32.dll and wintab.dll are now released using FreeLibrary off in the destructor
  • Nulling out references in the destructor
  • Fixed bug with the eraser code, now supports pressure sensitivity.

I set up my Wacom CTH-470 with my Surface Book to see how what happened with WinTab and to see if it conflicted this the Windows API. It seems (at least in the case of this hardware) to automatically switch between the WinTab (for the Wacom) and Windows API (for the Surface Book display). I've made a video here where I tested each of the breakpoints and functionality https://youtu.be/feN1GnD0e6c
.

Christopher Peerman (chris_82) marked an inline comment as done.EditedJan 6 2019, 9:25 PM

After submitting this I had a search and found the WinTab driver for the Surface Book. The attached video shows it in operation with the WinTab driver installed https://youtu.be/hTyGAwSfF5M. I'll need to spend more work on it to add settings to the enable/disable WinTab and Windows Ink. Is there any documentation how you add preferences?

Video is here https://youtu.be/hTyGAwSfF5M.

Looks good so far.

We don't have documentation for adding preferences, but here's a recent commit that added a preference: rB9ea645862cfb967376bb7ae2c7f7ef8a5fe90637.

GHOST can't access Blender preferences directory, so you'll need to add an API function for Blender to pass it to GHOST.

intern/ghost/intern/GHOST_WindowWin32.cpp
905

the within -> to within

Now with Preferences control allowing you to switch between Automatic, Native (as in the API introduced in Windows 8), Wintab and None. A demo video is here https://youtu.be/qX0zsG6LNDw

  • Use "Windows Ink" rather than "Native" in the UI, I think that matches the naming in Windows better.
  • Call it "Tablet API" instead of "Pressure API", for future proofing in case we start using more tablet functionality than just pressure.
  • Some more code refactoring.

Thanks for the update, I'll commit this with some further changes:

This revision is now accepted and ready to land.Jan 14 2019, 8:41 PM
This revision was automatically updated to reflect the committed changes.