HID button count and values for event = 3, 28 & 29

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
openantz
Posts: 6
Joined: Wed Nov 25, 2020 12:38 pm

HID button count and values for event = 3, 28 & 29

Post by openantz »

I am looking to discover a method to detect the number of buttons and a list of corresponding button (event) values using HID info.

My (personal) dev case is a 3D data viz project called ANTz (https://openantz.com) and I am in the process of patching the freeglut library to work with (hopefully) all current SpaceMouse devices and legacy ones too. Testing with the SpaceMouse Enterprise now works for all event data, but shows that the buttons are not contigous (they skip numbers).

Currently using GetRawInputDeviceInfo(... RID_DEVICE_INFO), which gives me the VID and PID of connected devices. Best guess is that perhaps I can tease out the button details from the (RID_DEVICE_INFO_HID) UsagePage(s).

I wish to support both legacy devices (VID = 0x042f) and the (newer) SpaceMouse Enterprise and Pro (including Wireless) editions using VID = 0x256f. My app uses the freeglut framework, so I am patching it!

--- Details and maybe some useful info to others below ---

At the moment, the patch works (6DOF + button events) for Space Navigator and SpaceMouse Enterprise, but the freeglut maintainer is requesting support for the function glutGet(GLUT_NUM_SPACEBALL_BUTTONS) and that the (GLUT) button events be contigous from 1 to n (# of buttons). This is sensible (for API consistancy), but poses two challenges; knowing the button count and related (button data packets) for each event type.

The button events are complex, and depending on which device, appear to have 3 packet sizes (3, 4, or 5 bytes). The first byte is the event type (3, 28 or 29) and is followed by the button value(s). It seems the valid (BITWISE/INTEGER) values can be 16bit (eg. Space Navigator), 24bit (Space Pilot) or 32bit (starting with the Space Pilot Pro and going forward). There also appears to be three fundamental types: event = 3 (BITWISE), 28 (INTEGER), 29 (only from a subset of the keys, when they are HELD down). Also, the integer events (28 and 29) can issue two words of 2 bytes each. The low word is used with a single key press and the high word only when 2 keys or more pressed. For the 'special' keys with a HELD down event = 29, you get the same value as event 28, But you can also get alternating events (of type 29) when simultaneously holding 3 keys down, ie: an event every second, one with two keys (high and low word) and the following second, a second event with a single key value (low word), and this repeats (every second) until released.

Additional discussion details are here:
https://sourceforge.net/p/freeglut/bugs/258/

Also, verbose comments in the (partially functional) code here:
http://openantz.com/code/freeglut/

My super-users love Spacemice and it would be greatlly appreciated (by the open source community) if anybody can assist in this mission!
jwick
Moderator
Moderator
Posts: 3328
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: HID button count and values for event = 3, 28 & 29

Post by jwick »

Yes, some of the devices have breaks in the numbering. It's unusual for us, but is not an unusual USB practice.
Had I known about it at the time I would have taken that into account when I designed the APIs.

If you download our Windows driver package, there is a file, Base.xml, that describes all the button event details.
Don't redistribute that file, but you can make use of the information to help you build your parsing code.

AFAIK, for recent devices, the USB device descriptors are correct. They were not for some of our early USB devices.
There is a lot of information in there that you can make use of.
openantz
Posts: 6
Joined: Wed Nov 25, 2020 12:38 pm

Re: HID button count and values for event = 3, 28 & 29

Post by openantz »

I find it preferable to match a set of static button ID's to device labels across various models, and this helps make it easier to keep it consistent for future devices as well. Though this makes it necessary to have a complete list of all device buttons to implement good code.

On this regard, the 'Base.xml' file is very helpful with it's device specific event (Report ID) types and button ID's (from Space Pilot Pro forward). Also, the 'virtualkeys.hpp' file in the SDK helps fill in the gaps for older devices, (eg. Space Pilot, Space Explorer, etc.)

In pursuit of coding support for all devices, I've updated my 3Dx HID cheatsheet here:

https://github.com/openantz/antz/wiki/3 ... developers

Please do provide any feedback as to accuracy, clarity and/or missing key information.

Lastly, it would be handy to be able to set all (SMP/SME) Dual Function keys (LongPressButtons) state to OFF (for a specific app). However, it is likely that the 3DxWare will re-configure the buttons whenever switching windows. So perhaps could reset this by checking the device state, (and to requote,) using:

> RPTID_LONGPRESS_MASK = 0x14, // Data: 4 bytes...
> Default 0x00000000 (all off). E.g., 0x0000f000 turns on long press on buttons 1-4

However, I have two problems here:

1) I have not (yet) succeeded in properly sending the HID data to configure the SME device. I only got as far as getting the device motion events to act really weird, suggesting the FileWrite() is working, but the packet is mis-configured. Perhaps you can provide some (windows C/C++) source code that demonstrates this or something similar, (like turning on the various LED's, which would be fun too)?

2) I have not (yet) thought of an efficient and reliable way to avoid fighting it out with the 3DxWare app configurations (which are helpful to the user, so a solution that allows both to co-exist would be ideal).

So, perhaps there is another approach, such as configuring the app.xml file to disable the DF keys?
And/or, maybe adding the functionality directly to the 3DxWare 'Buttons' dialog, (eg. setting [Roll -] to 'Disabled' would configure the HW to turn OFF the LONGPRESS for that key.)

BTW: I did figure out how to create custom SME lcd button icons by messing with the [app].xml file (in the users sub-folder) in conjuction with adding some [custom].PNG references in the Base.xml file. But I think this is a separate topic.
jwick
Moderator
Moderator
Posts: 3328
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: HID button count and values for event = 3, 28 & 29

Post by jwick »

Typo on your page: Logitech VID = 0x042d (legacy 3Dconnexion). (0x046d)

I still don't understand the scope of your project. If you are working exclusively with the Windows driver, you can do much more configuration using the capabilities of the driver and the API. With a proper cfg, you have a lot of control and cooperation.

It appears you support 3 platforms (Windows, MacOS, Linux). I still suggest building on top of our APIs on the platforms. They will be slightly different per platform but there is always a platform-specific layer somewhere in multi-platform code.

This allows users to use our GUI for configuration. Most importantly it insulates your software from changes caused by future devices. I don't want you to have to rebuild your software each time we introduce a new product.

If you want to go directly to HID, you can create a Windows cfg that tells the driver to get out of the way. It's a lot of work. And you are just redoing what I am already doing for you.

There will still undoubtedly be some app-specific configuration required in your program.
openantz
Posts: 6
Joined: Wed Nov 25, 2020 12:38 pm

Re: HID button count and values for event = 3, 28 & 29

Post by openantz »

Thank you for catching the typo, (fore-mentioned wiki corrected to 0x046d).

ANTz scope:
An open source cross-framework core technology that is deployed both as a standalone app (on MSW, OSX, Linux...) and plugin component within other frameworks. Most end-users are either commercial or U.S. government with (open source directives). Some of the sponsors and dev partners are research institutes (eg. health care, education and national labs).

Note that I am not an attorney, the information provided here does not, and is not intended to, constitute legal advice; instead, all information is for general informational purposes only. The 3Dx SDK license does not appear to be compatible with open source code distribution, (object code only = compiled binary = no open source code), here is an excerpt:

"...3Dconnexion grants to you a personal limited non-exclusive, non-transferable, non-sublicensable, world-wide, royalty-free, revocable license to install, use, copy, modify and distribute in object code form the 3DCONNEXION SDK....
...Unauthorized reproduction or distribution of the 3DCONNEXION SDK is subject to civil and criminal penalties."

At this time, directly using HID appears to be the only viable option, though please do correct me if I am wrong. On this assumption, I very much encourage 3Dconnexion to consider an open source friendly approach: Eg. The Blackmagic Design license is a workable compromise that protects their broad intellectual property rights, while allowing the distribution of open source code that directly uses the proprietary SDK.

Regardless, I very much enjoy the 3DxWare functionality (as do my users) and it appears that it works very well in conjunction with direct HID events (via MSW). The only thorn in the side is the Dual Function (DF) keys, (aka LongPressButtons). From my perspective, event (Report ID) 0x03 and 0x1c work great, so long as the DF keys are disabled. While the user can selectively turn off the DF behavior for keys 1-12, the navigation keys event behavior remains inaccessible (to the user). Hence, why not build this into the existing 3Dx 'Buttons' dialog, where if the user sets a DF button (eg. ISO2) to 'Disabled' it also sets the HW to behave accordingly, akin to keys 1-12 with '[X] Disable On-Screen Display'. And ideally, this config setting would be defined within the (app).xml file.

The (app).xml file is quite handy! It not only allows the user to create custom button macros, it also can be manually edited (by a super-user) to support custom LCD button icon images specific to each unique macro action, which is cool! Going further, it appears possible to setup multiple button configs via ButtonBanks (https://forum.3dconnexion.com/viewtopic ... 706#p70706) and perhaps have the app directly set them.
jwick
Moderator
Moderator
Posts: 3328
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Re: HID button count and values for event = 3, 28 & 29

Post by jwick »

I understand. Then let's use HID. It works for the driver, it can work for you.

There is no problem using HID, but you might have to do a little bit of work as new devices appear.
We try to limit the differences. It makes our life easier too.

All what follows is limited to Windows.

99% of everything is controlled by the XML files. All the GUI (3DxSmartUI.exe) does is edit the XML files. The driver (3DxService.exe) reads them, and occasionally writes them. Notepad works too, but it's not very pretty. For the most part, the API also just edits the cfg files.

The first order of business is to get the driver helping you not hurting you. If you tell the driver that you are using HID, it will configure the device in a compatible way.

You will have to create a cfg file for this. Easy with the stand alone app, not so easy when the app is used inside another app.

1) Copy some cfg file in Program Files/3Dconnexion/3DxWare/3DxWinCore/Cfg. (e.g., Jet.xml) to AntZ.xml
2) Change the ExecutableName to your executable's name (and the ID and Name fields)
3) Change the Transport to HID

Save the file. Restart the driver. Open your app. Set focus to it. You should see AntZ.xml in the GUI and when hovering over the 3Dx systray icon.
Now you have a cfg file to work with and all the capabilities are open to you.

Yes, you can define multiple ButtonBanks in your cfg file. You can assign buttons on your device to navigate through them (forward/backward, push/pop, goto, etc).

Or you can use your code or a script to do the XML editing outside of the device buttons. You are at mercy of my changes to the cfg file format.

It's just a file. Anyone who can edit a file can make changes. Everyone who is interested will respond to the changes.
Our GUI exposes a limited selection of the capabilities (e.g., no access to the LongPressButtons).
ruevs
Posts: 3
Joined: Sun Feb 14, 2021 1:47 pm

SDK License compatibility with open source

Post by ruevs »

Hello,

This thread seems like the perfect place to ask the question:
Does the license of the current 3Dconnexion SDK allow it to be used with open source software?

The question came up in the SolveSpace project (https://github.com/solvespace/solvespace/pull/968) since on Windows we are using an ancient (2005) version of the SDK that is only 32bit (x86). Updating to a much newer version seems rather painless - great job guys! - but the license may be a problem, see the discussion in the link above.

On Linux we are already using spacenavd (https://github.com/FreeSpacenav/spacenavd) which as far as I understand is compatible with the official driver.

If using the official SDK is not "allowed", just like OpenANTz we are considering using the 6DOF 3Dconnection devices through HID directly. I developed a very minimalist plain C library (started by John Tsiombikas) to a point where it should work with all the USB devices and even some some serial ones (not finished). https://github.com/ruevs/libspnavdev/tree/USBWin32

However as jwick pointed out using the official SDK should make SolveSpace more "future proof". That is why I am asking the question.
jordanbrown
Posts: 1
Joined: Fri Mar 25, 2022 3:36 pm

SDK License compatibility with open source

Post by jordanbrown »

Was there ever an answer to this question?

It looks like the intent of the SDK license is to be relatively liberal, but it's not immediately clear whether the SDK is usable with an open-source project or, if so, what hoops one must jump through.

In particular, the license seems to restrict disclosure of the header files, which makes it unclear how an open-source project could do routine builds or how its developers would work with the 3DConnexion components.
ruevs
Posts: 3
Joined: Sun Feb 14, 2021 1:47 pm

Re: HID button count and values for event = 3, 28 & 29

Post by ruevs »

There never was an answer to the question about using the official SDK in open source projects. And I am still interested in that.
tksuoran
Posts: 2
Joined: Mon May 31, 2021 12:46 am

Re: HID button count and values for event = 3, 28 & 29

Post by tksuoran »

While I am improving my own space mouse support, here is some information that you may find useful:
You don't need to identify devices based on vendor and product ids. Instead, you can identify devices based on "usage page" and "usage id". Space mouse devices are all usage page = 0x01 (Generic Desktop Page) and usage id = 0x08 (Multi-axis Controller). You can query buttons and inputs with HID API calls. You can query what are contents of each report id at runtime.

For example, my SpaceMouse Wireless:

Code: Select all

Output Button #1:
-----------------
Report ID: 0x4
Usage Page: 0x8
Alias: FALSE
Link Collection: 3
Link Usage Page: 0x9
Link Usage: 0x0
Usage: 0x4b
DataIndex: 0x0
String Index: 0x0
Designator Index: 0x0
Absolute: Yes
Usage page 0x8 is LED page and usage 0x4b is Generic Indicator. I suppose I might be able to turn the green led on and off by sending report 0x4 to the device.

Code: Select all

Input Value #1:
---------------
Report ID 0x1
Usage Page: 0x1
Bit size: 0x10
Report Count: 0x1
Unit Exponent: 0xc
Has Null: 0x0
Alias: FALSE
Usage: 0x35
DataIndex: 0x0
Physical Minimum: -1400, Physical Maximum: 1400
Logical Minimum: 0xfffffea2, Logical Maximum: 0x15e
String Index: 0x0
Designator Index: 0x0
Absolute: Yes
Usage 0x35 on usage page 0x1 is Rz. This is rotation around the Z-axis. It will report minimum value of -350 (0xfffffea2) and maximum value 350 (0x15e). This is the first listed entry for report using report using id 0x1, taking 0x10 = 16 bits = two bytes. Using Unit Exponent and physical range should also allow to interpret the reported values in correct physical units.

Code: Select all

Input Value #2:
---------------
Report ID 0x1
Usage Page: 0x1
Bit size: 0x10
Report Count: 0x1
Unit Exponent: 0xc
Has Null: 0x0
Alias: FALSE
Usage: 0x34
DataIndex: 0x1
Physical Minimum: -1400, Physical Maximum: 1400
Logical Minimum: 0xfffffea2, Logical Maximum: 0x15e
String Index: 0x0
Designator Index: 0x0
Absolute: Yes
Similar to the previous entry, this is 0x34 = Ry = rotate around the Y-axis. This will be the next 16 bits = 2 bytes in report id 1.

Similar entries for Rx, Z, Y and X follow. Together all entries using report id 1 tell how to interpret that report: Rz Ry Rx Z Y X, each 2 bytes.

Code: Select all

Input Value #7:
---------------
Report ID 0x17
Usage Page: 0x6
Bit size: 0x8
Report Count: 0x1
Unit Exponent: 0x0
Has Null: 0x0
Alias: FALSE
Usage: 0x20
DataIndex: 0x8
Physical Minimum: 0, Physical Maximum: 1
Logical Minimum: 0x0, Logical Maximum: 0x64
String Index: 0x0
Designator Index: 0x0
Absolute: Yes
Usage page 0x6 = Generic Device Controls Page, Usage 0x20 = Battery Strength. Looks like the battery strength will be reported using 8 bits = one byte with report id = 0x17.

My code is still work in progress. Here are some useful functions:
  • RegisterRawInputDevices()
  • GetRawInputDeviceInfo()
  • HidP_GetCaps()
  • HidP_GetLinkCollectionNodes()
  • HidP_GetButtonCaps()
  • HidP_GetValueCaps()
Amelia4
Posts: 1
Joined: Thu Oct 26, 2023 1:37 am
Location: mexico

Re: HID button count and values for event = 3, 28 & 29

Post by Amelia4 »

Can the 3DConnexion SDK be used with open-source projects, and if so, what are the specific requirements? I would be very happy if you could let me know, thanks
ngomes
Moderator
Moderator
Posts: 3318
Joined: Mon Nov 27, 2006 7:22 am
Contact:

Re: HID button count and values for event = 3, 28 & 29

Post by ngomes »

All 3Dconnexion SDKs can be used in open- and close-source programs. There is an attribution clause in the SDK license.
Nuno Gomes
Post Reply