Hey,
what’s going on with the ControllerListener interface.
I see it’s still an open issue on the issue tracker, and as far as I can see DirectInput doesn’t generate events upon connecting and disconnecting devices.
(There are exceptions that will be thrown if a controller is disconnected, but that’s about it).
But it seems like it’s pretty easy to register that a window is listening to USB HID devices being connected/disconnected in Windows.
There’s a pretty ugly HID GUID constant that has to go in there, but…
I haven’t had the time to look into the jInput native code, nor do I have much C++ or Windows programming experience, but I did find code for setting up a window as listening to USB devices being connected/disconnected:
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
HDEVNOTIFY hDeviceNotify = NULL;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCADT_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = { 0x4d1e55b2, 0xf16f, 0x11Cf, { 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
hDeviceNotify = RegisterDeviceNotification(hWnd, &NotificationFilter
DEVICE_NOTIFY_WINDOW_HANDLE);
if (hDeviceNotify == NULL)
{
// Handle the error...
}
This is a modified version of the code I found, as it used loops to register all kinds of USB devices, I just removed the loop and moved the guid directly into the notification filter instead of using an array of guids to pick from.
And the callback in the window:
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch (uiMsg)
{
case WM_DEVICECHANGE:
{
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR) lParam;
switch (wParam)
{
case DBT_DEVICEARRIVAL:
// Handle a device being connected
break;
case DBT_DEVICEREMOVECOMPLETE:
// Handle a device being removed
break;
}
}
break;
default:
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
break;
}
return 0;
}
Of course, if it turns out the device is not a game device (I’m guessing this would have to be checked by enumerating devices in DirectInput and checking if there are any new devices on the list), DefWindowProc should probably be called.
I have a feeling this might be slow, though. shrug
The callback is probably called pretty quickly, and upon disconnection it should at least be easy to check the device specific GUID against a stored list of game device GUIDs, to quickly call the ControllerListener’s controllerRemoved method, but detecting connections seems like the hard part.
For that matter, disconnects could probably be detected quite easily using DirectInput’s InputLost- or UnpluggedExceptions.
Of course, I haven’t tried these things.
Maybe I should make a small test application and see how fast/slow this would be at detecting me connecting/disconnecting a gamepad.