Enabling/Disabling Joysticks from registry for the Mac

Ken Thomases ken at codeweavers.com
Sat Jul 30 03:40:28 CDT 2016


Hi,

On Jul 30, 2016, at 2:15 AM, DavidL <david.dljunk at gmail.com> wrote:
> 
> I was looking into how the Linux-dinput code and joy.cpl work and comparing that to the macOS-dinput code. I have some questions about how best to proceed:
> 
> joy.cpl uses joy->instance.tszInstanceName to name the joysticks in the control panel. In Linux-dinput code, they pass the joystick_devices[id].name to both tszInstanceName and tszProductName  In the macOS-dinput code, they pass the name "Joystick #" where # is the index in the joystick array to the instance name and the joystick's actual name to the product name. When looking at the Microsoft guidelines for dinput, it does indeed say that the instance name *can* be joystick + position in the array, but doesn't specify that it *has* to be (https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dideviceinstance(v=vs.85).aspx). Also, I've confirmed that in the Windows 10 joystick control panel the joysticks are listed by their name, not by joystick number (and in my memory of earlier Windows OSes it's the same). 
> 
> So, should I change the macOS-dinput code to set both tszInstanceName and tszProductName to the product name (as in Linux) or should I change joy.cpl to use tszProductName instead of tszInstanceName? This will also make it easier in the registry to know which joystick is being enabled/disabled. 

We need to distinguish between an object's internal identifier and what's displayed in UI.

It seems to me that joy.cpl and dinput ought to use the guidInstance field to determine which devices are enabled or disabled.  That would require that the backends actually provide a guidInstance that's unique among devices but stable across runs and attachment/detachment of devices.  Unfortunately, I'm not sure how practical that is.  Some devices seem to provide kIOHIDSerialNumberKey, but not all do.  kIOHIDLocationIDKey is stable so long as the USB topology doesn't change, but it can change, of course.  An experiment shows that the location ID changes if you just plug the device into a different point in the topology (a USB port on the computer vs. one on the keyboard, which is a hub).

Also, if you change how this works, everybody's existing registry settings will break.

So, perhaps a decent compromise would be for joy.cpl to display both the instance and the product name (e.g. "Joystick 1 - Logitech Extreme 3D Pro") but record the instance name in the registry.  On Linux, I guess that may make the name looked doubled, if the instance and product names are the same.

On the Mac, we should probably change the instance name to something that's really associated with the device.  The index in the device array is not stable.  If you disconnect the first joystick, all other joysticks will get renumbered in that scheme.  Probably, the location ID is the closest we have to a stable ID (which is why you've used it for sorting).  It's just too bad that it's an ugly number, whether formatted decimal or hexadecimal.

Another approach would be for the Mac code to basically build a dynamic database of every game controller it ever encounters, storing all of the available stable identifying information about each, and assigning a permanent identifier.  So, location ID would not be used because it's not truly stable, but vendor ID, product ID, manufacturer, product name, serial number, version number, usage pairs, and maybe even the report descriptor could be.  As it enumerates devices, it would look through the database to find one that matches all of the these available pieces of metadata.  If it does, it will reuse the previously-generated identifier.  Otherwise, it will generate a new identifier and add the device to the database.  There would have to be a check, in case there are two exactly identical devices attached, to not use the same identifier for both.  In practice, the database should never grow very large since one system should never have very many devices connected to it over its history.


> Further, while joy.cpl correctly is a dinput control panel, enabling/disabling joystick should be for both dinput and winmm games - e.g. X-wing vs Tie Fighter even has the joystick control panel in the game's loader window*, but, once in the game, joystick control is handled by winmm. I believe the joystick registry entry is under dinput, but the winmm wine joystick driver should read that as well. 
> 
> Is it acceptable for wine joystick driver to read the dinput registry? Or should two registry entries be created? or should a single general joystick registry entry not under dinput or winmm control both?

Well, the registry key is actually Wine-specific.  It's got "DirectInput" in the path, but we can play a little fast and lose with it.  No Windows app is sensitive to what's under that key, for example.  I see no problem with having winmm check it.

There's work underway to implement proper HID support and then reimplement lots of different APIs (dinput, winmm joystick, xinput, raw input) on top of that.  When that happens, a lot of this will probably have to change and redundancy will hopefully be eliminated.  (If it's going to break people's settings, it may be a good time to switch to using guidInstance or the equivalent, too.)

-Ken




More information about the wine-devel mailing list