#pressure #bindings #pen #tablet #read #wacom #wintab

wintab_lite

Read pen tablet pressure with these lightly oxidized wintab bindings

4 releases (2 stable)

1.0.1 Apr 19, 2024
0.2.0 Apr 17, 2024
0.1.0 Apr 16, 2024

#441 in Hardware support

Download history 6/week @ 2024-09-19 4/week @ 2024-09-26 2/week @ 2024-10-03

92 downloads per month

MIT license

110KB
742 lines

Wintab; Lite-ly Rusted

Defines a minimal set of types to get rust working with wintab.

1. Licence

The original wintab headers and documentation are marked with a copyright notice by Wacom. See here and here. The example code provided by Wacom is MIT licensed here

2. Examples

2.1. Using winit and the libloading feature

cargo run --example winit_libloading --features="libloading"

Usage:

  • Press space on the keyboard to clear the view.
  • Only wintab input will cause anything to be drawn. Mouse won't do anything.

Screenshot of Window Showing Debug Strokes with Pressure

Notes:

-When working in winit, the native wintab events (e.g. WT_PACKET) are unavailable.

  • Luckily wintab supports polling methods and keeps a nice timestamped event queue. YOu only need access to the hwnd pointer. This is good news as it means it is likely-ish I can get this working in bevy, as long as the plugin lets me have the hwnd :P
  • The winit project is in the process of overhauling how the event loop works. Hopefully they see fit to make lparam and wparam available in the new system.

2.2. Using windows and the raw-dylib feature

cargo run --example windows_raw_dylib --features="raw-dylib"

Usage:

  • Press space on the keyboard to clear the view.
  • Only wintab input will cause anything to be drawn. Mouse won't do anything.

Notes:

  • links to "Wintab32.dll" at compile time using #[link(name="Wintab32", kind = "raw-dylib")]
    • This is nice because it drastically simplifies the use of extern functions in your code
    • But it means that it can only be compiled on a windows system with Wintab32.dll installed, and if Wintab32 becomes unavailable then your software will crash instead of being able to launch and deliver a meaningful error message to your user.
    • This is probably the way to go for hacky personal projects. I think libloading is the way to go for most other things.
  • The call to SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) is critical to avoid hours of painful debugging scaling problems!

3. Limitations

  • Not all foreign functions are ported.
    • For example WTEnable is currently missing but I will probably add it in a future update.
    • WTMgrOpen is missing, but I can't be bothered adding it, because I think it is not needed unless you are writing a config tool for your tablet device, or doing really weird advanced stuff. PRs welcome though.
  • libloading is not necessarily the best option... there are a few others out there. I would like to find a way to support any of them but I am not sure how.
  • The examples worked for me with my hardware, however I didn't try to strictly follow all guidance in the docs, so edge cases and other hardware may need some extra code to properly configure the LOGCONTEXT object.
    • For example; I found that the default LOGCONTEXT object was mostly already configured as needed. The documentation gave me the impression that more setup steps should be needed; for example manually measuring the size of the virtual screen and using that to configure the LOGCONTEXT object. HOwever I found that the LOGCONTEXT object generally arrives pre-configured correctly, so much of the setup in the examples is possibly redundant. Or perhaps it is worth doing to ensure consistency across different hardware?

4. Alternatives

4.1. bindgen with wintab.h

An alternative to this crate is to use bindgen and the original wintab.h header files which are avaliable here. I did not have a good time with that approach

  • A lot of excess code gets generated
  • Missing useful trait definitions
  • Coordinates are represented as separate struct fields instead of being packed into an XYZ struct
  • Enums are represented as separate const declarations instead of being a rust enum or using the bitflags crate.

4.2. octotablet crate

Please check out the octotablet project. At the time of writing it is the goal of this crate to be wrapped by octotablet. Currently octotablet already provides Windows Ink functionality and support for other platforms.

I did not have good results with windows Ink on my windows 11 machine, and therefore I started work on this crate.

Dependencies

~128MB
~2M SLoC