XInput compatible device initialized as a DirectInput device

Hi all,

When I was using SDL joysticks on Windows 7 64bit in my project, I found
that SDL2 initializes XInput compatible device as a DirectInput device under
a specific circumstance. I looked into the joystick initialization code and
probably figured out how it occurs.

Things related:

  • XInput assigns its internal user ID to each input device and usually it
    starts from 0.
  • But, sometimes, an input device may acquire ID 1 even if there’s no any
    other device connected. I guess that could happen in such situation that we
    connected multiple input devices to our machine, and then disconnected the
    first connected one.

And, the senario of the case is that:

  • SDL2 detects all XInput compatible devices in SDL_JoystickInit() (which is
    called from SDL_Init(SDL_INIT_JOYSTICK) or
    SDL_InitSubSystem(SDL_INIT_JOYSTICK)) and marks them as "XInput compatible"
    by setting bXInputDevice to SDL_TRUE in EnumJoysticksCallback(). But they
    are just detected at that time, and not opened.
  • After that, in SDL_SYS_JoystickOpen() (which is called from
    SDL_JoystickOpen()), SDL2 checks if a XInput compatible device is really
    available by checking the result of call for XINPUTGETCAPABILITIES(). When
    the capability check function is called, an user ID is passed to the
    function. The point is that SDL_SYS_JoystickOpen() always tries passing user
    ID 0 (and then increments the ID if there were multiple joysticks detected),
    and if the capability check is failed with the use ID, it marks the device
    is not XInput compatible by setting bXInputDevice to SDL_FALSE. In this
    case, the device will be handled by DirectInput instead of XInput.
  • If there is only one XInput compatible device connected with user ID 1
    acquired, SDL_SYS_JoystickOpen() always marks it as “NOT XInput compatible”.
    That’s it!

I don’t think it is the best behavior SDL2 can do. Is that a known problem
that already in a bug tracking system?

Yamamoto

Let me see if I’m getting this right: basically during the second step
SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Because in that case it sounds like a rather serious bug that can
potentially result in even more side-effects.

It’d be probably better to not bother checking the joysticks until the
program tries to open them anyway.

2013/7/25, Yamamoto :> Hi all,

When I was using SDL joysticks on Windows 7 64bit in my project, I found
that SDL2 initializes XInput compatible device as a DirectInput device under

a specific circumstance. I looked into the joystick initialization code and

probably figured out how it occurs.

Things related:

  • XInput assigns its internal user ID to each input device and usually it
    starts from 0.
  • But, sometimes, an input device may acquire ID 1 even if there’s no any
    other device connected. I guess that could happen in such situation that we

connected multiple input devices to our machine, and then disconnected the
first connected one.

And, the senario of the case is that:

  • SDL2 detects all XInput compatible devices in SDL_JoystickInit() (which is

called from SDL_Init(SDL_INIT_JOYSTICK) or
SDL_InitSubSystem(SDL_INIT_JOYSTICK)) and marks them as “XInput compatible”

by setting bXInputDevice to SDL_TRUE in EnumJoysticksCallback(). But they
are just detected at that time, and not opened.

  • After that, in SDL_SYS_JoystickOpen() (which is called from
    SDL_JoystickOpen()), SDL2 checks if a XInput compatible device is really
    available by checking the result of call for XINPUTGETCAPABILITIES(). When
    the capability check function is called, an user ID is passed to the
    function. The point is that SDL_SYS_JoystickOpen() always tries passing user

ID 0 (and then increments the ID if there were multiple joysticks detected),

and if the capability check is failed with the use ID, it marks the device
is not XInput compatible by setting bXInputDevice to SDL_FALSE. In this
case, the device will be handled by DirectInput instead of XInput.

  • If there is only one XInput compatible device connected with user ID 1
    acquired, SDL_SYS_JoystickOpen() always marks it as “NOT XInput compatible”.

That’s it!

I don’t think it is the best behavior SDL2 can do. Is that a known problem
that already in a bug tracking system?

Yamamoto


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Let me see if I’m getting this right: basically during the second step
SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Yes. That’s the point.

If there’s only one XInput compatible device with user ID 1 (or greater) is
acquired, SDL_SYS_JoystickOpen() tries to see if the device is available by
using wrong ID (= 0). And XINPUTGETCAPABILITIES() ends up returning “device
is not connected” error and the code marks the device as “NOT XInput
compatible”.

Yeah that sounds like a serious bug.

Check in Bugzilla if there was a report with the search tool, if you
can’t find something similar just go ahead and report it (if it turned
out there was already a bug report then at worst it can just be merged
with that old report).

2013/7/25, Yamamoto :>>Let me see if I’m getting this right: basically during the second step

SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Yes. That’s the point.

If there’s only one XInput compatible device with user ID 1 (or greater) is

acquired, SDL_SYS_JoystickOpen() tries to see if the device is available by

using wrong ID (= 0). And XINPUTGETCAPABILITIES() ends up returning "device

is not connected" error and the code marks the device as “NOT XInput
compatible”.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yeah that sounds like a serious bug.
It may or may not be that serious. On Windows, it is common and correct way
to handle game pad devices by first trying to apply XInput, and next try
DirectInput if XInput doesn’t match the device. Maybe you know, XInput only
handles new input devices while DirectInput covers all. But, these 2 APIs
handles buttons and axes in different manner.

Check in Bugzilla if there was a report with the search tool, if you
can’t find something similar just go ahead and report it (if it turned
out there was already a bug report then at worst it can just be merged
with that old report).
Okay. I’ll check Bugzilla. If there’s no smilar report, I’ll add new one.
Thanks.

2013/7/25, Yamamoto :

It may or may not be that serious. On Windows, it is common and correct way
to handle game pad devices by first trying to apply XInput, and next try
DirectInput if XInput doesn’t match the device. Maybe you know, XInput only
handles new input devices while DirectInput covers all. But, these 2 APIs
handles buttons and axes in different manner.

I meant the ID mismatch.