Skip to content

Commit 2130640

Browse files
committed
Add hotplug support for USB devices
1 parent d423aa3 commit 2130640

File tree

4 files changed

+46
-28
lines changed

4 files changed

+46
-28
lines changed

include/hotplug_linux.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class HotplugLinux : public Hotplug
1717
struct udev *m_handle;
1818
int m_nof_devices;
1919

20+
int Enumerate(const char *subsystem, const char *sysattr, const char *value);
2021
void CheckForEvents();
2122
int CreateHandle();
2223
void DestroyHandle();

include/hotplug_windows.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ class HotplugWindows : public Hotplug
1717
void MainLoop() override;
1818

1919
private:
20-
static constexpr char *GUID = "{46c58a4e-05fb-441e-84f5-55aa37e4b412}";
20+
static constexpr char *GUID_PCI = "{46c58a4e-05fb-441e-84f5-55aa37e4b412}";
21+
static constexpr char *GUID_USB = "{9f4ef953-49da-47a0-a3e9-820fbfad4a24}";
2122
size_t m_nof_devices;
2223

2324
static std::vector<std::string> SplitDeviceList(const std::string &list);
25+
size_t Enumerate(const char *guid);
2426
void CheckForEvents();
2527
};

src/hotplug_linux.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,19 @@ HotplugLinux::~HotplugLinux()
2121
Stop();
2222
}
2323

24-
void HotplugLinux::CheckForEvents()
24+
int HotplugLinux::Enumerate(const char *subsystem, const char *sysattr, const char *value)
2525
{
2626
struct udev_enumerate *enumerator = udev_enumerate_new(m_handle);
2727
try
2828
{
29-
/* Filter the PCI subsystem for devices w/ vendor id 0x1b37. */
3029
if (enumerator == NULL)
3130
throw HotplugLinuxException("Failed to create libudev enumerator.");
3231

33-
if (udev_enumerate_add_match_subsystem(enumerator, "pci") < 0)
34-
throw HotplugLinuxException("Failed to add libudev enumerator filter.");
32+
if (udev_enumerate_add_match_subsystem(enumerator, subsystem) < 0)
33+
throw HotplugLinuxException("Failed to add libudev enumerator subsystem filter.");
3534

36-
if (udev_enumerate_add_match_sysattr(enumerator, "vendor", "0x1b37") < 0)
37-
throw HotplugLinuxException("Failed to add libudev enumerator vendor filter.");
35+
if (udev_enumerate_add_match_sysattr(enumerator, sysattr, value) < 0)
36+
throw HotplugLinuxException("Failed to add libudev enumerator sysattr filter.");
3837

3938
udev_enumerate_scan_devices(enumerator);
4039

@@ -44,22 +43,32 @@ void HotplugLinux::CheckForEvents()
4443
udev_list_entry_foreach(entry, devices)
4544
nof_devices++;
4645

47-
if (nof_devices > m_nof_devices)
48-
_EmplaceMessage(HotplugEvent::CONNECT);
49-
else if (nof_devices < m_nof_devices)
50-
_EmplaceMessage(HotplugEvent::DISCONNECT);
51-
52-
m_nof_devices = nof_devices;
5346
udev_enumerate_unref(enumerator);
47+
return nof_devices;
5448
}
5549
catch (const HotplugLinuxException& e)
5650
{
5751
if (enumerator != NULL)
5852
udev_enumerate_unref(enumerator);
5953
Log::log->error(e.what());
54+
return 0;
6055
}
6156
}
6257

58+
void HotplugLinux::CheckForEvents()
59+
{
60+
/* Filter the PCI subsystem for devices with vendor id 0x1b37 and the USB
61+
subsystem for devices with vendor id 0x1d73. */
62+
int nof_devices = Enumerate("pci", "vendor", "0x1b37") + Enumerate("usb", "idVendor", "1d73");
63+
64+
if (nof_devices > m_nof_devices)
65+
_EmplaceMessage(HotplugEvent::CONNECT);
66+
else if (nof_devices < m_nof_devices)
67+
_EmplaceMessage(HotplugEvent::DISCONNECT);
68+
69+
m_nof_devices = nof_devices;
70+
}
71+
6372
int HotplugLinux::CreateHandle()
6473
{
6574
if (m_handle != NULL)

src/hotplug_windows.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,44 +33,50 @@ std::vector<std::string> HotplugWindows::SplitDeviceList(const std::string &list
3333
return result;
3434
}
3535

36-
void HotplugWindows::CheckForEvents()
36+
size_t HotplugWindows::Enumerate(const char *guid);
3737
{
3838
/* We check for events by polling the Windows kernel for devices
3939
- present on the system; and
40-
- matching the setup class GUID for a TSPD digitizer.
41-
42-
We simply take the difference between the number of devices we got in the
43-
last call and the number we get from a new call. This obviously misses
44-
the case when a digitizer gets removed and added between polling events
45-
but that's so rare that it basically shouldn't happen in practice. */
40+
- matching the target setup class GUID. */
4641

4742
const ULONG LIST_FLAGS = CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT;
4843
ULONG list_size = 0;
4944

50-
CONFIGRET result = CM_Get_Device_ID_List_SizeA(&list_size, GUID, LIST_FLAGS);
45+
CONFIGRET result = CM_Get_Device_ID_List_SizeA(&list_size, guid, LIST_FLAGS);
5146
if (result != CR_SUCCESS)
5247
{
5348
Log::log->error("CM_Get_Device_ID_List_SizeA failed, code {}.", result);
54-
return;
49+
return 0;
5550
}
5651

5752
/* Allocate a string of the prescribed size (includes the NULL terminator). */
5853
auto list = std::string(list_size, '\0');
5954

60-
result = CM_Get_Device_ID_ListA(GUID, (PZZSTR)list.data(), (ULONG)list.capacity(), LIST_FLAGS);
55+
result = CM_Get_Device_ID_ListA(guid, (PZZSTR)list.data(), (ULONG)list.capacity(), LIST_FLAGS);
6156
if (result != CR_SUCCESS)
6257
{
6358
Log::log->error("CM_Get_Device_ID_ListA failed, code {}.", result);
64-
return;
59+
return 0;
6560
}
6661

67-
auto devices = std::move(SplitDeviceList(list));
68-
if (devices.size() > m_nof_devices)
62+
return SplitDeviceList(list).size();
63+
}
64+
65+
void HotplugWindows::CheckForEvents()
66+
{
67+
size_t nof_devices = Enumerate(GUID_PCI) + Enumerate(GUID_USB);
68+
69+
/* We simply take the difference between the number of devices we got in the
70+
last call and the number we get from a new call. This obviously misses
71+
the case when a digitizer gets removed and added between polling events
72+
but that's so rare that it basically shouldn't happen in practice. */
73+
74+
if (nof_devices > m_nof_devices)
6975
_EmplaceMessage(HotplugEvent::CONNECT);
70-
else if (devices.size() < m_nof_devices)
76+
else if (nof_devices < m_nof_devices)
7177
_EmplaceMessage(HotplugEvent::DISCONNECT);
7278

73-
m_nof_devices = devices.size();
79+
m_nof_devices = nof_devices;
7480
}
7581

7682
void HotplugWindows::MainLoop()

0 commit comments

Comments
 (0)